ActivityManagerService.java revision d69e4c1460017062e7c36be55801cb434ad19d97
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 com.android.server.am.ActivityManagerDebugConfig.*;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37import static org.xmlpull.v1.XmlPullParser.START_TAG;
38
39import android.Manifest;
40import android.app.AppOpsManager;
41import android.app.ApplicationThreadNative;
42import android.app.IActivityContainer;
43import android.app.IActivityContainerCallback;
44import android.app.IAppTask;
45import android.app.ITaskStackListener;
46import android.app.ProfilerInfo;
47import android.app.usage.UsageEvents;
48import android.app.usage.UsageStatsManagerInternal;
49import android.appwidget.AppWidgetManager;
50import android.content.res.Resources;
51import android.graphics.Bitmap;
52import android.graphics.Point;
53import android.graphics.Rect;
54import android.os.BatteryStats;
55import android.os.PersistableBundle;
56import android.os.PowerManager;
57import android.os.TransactionTooLargeException;
58import android.os.WorkSource;
59import android.os.storage.IMountService;
60import android.os.storage.StorageManager;
61import android.service.voice.IVoiceInteractionSession;
62import android.util.ArrayMap;
63import android.util.ArraySet;
64import android.util.DebugUtils;
65import android.util.SparseIntArray;
66import android.view.Display;
67
68import com.android.internal.R;
69import com.android.internal.annotations.GuardedBy;
70import com.android.internal.app.DumpHeapActivity;
71import com.android.internal.app.IAppOpsService;
72import com.android.internal.app.IVoiceInteractor;
73import com.android.internal.app.ProcessMap;
74import com.android.internal.app.ProcessStats;
75import com.android.internal.os.BackgroundThread;
76import com.android.internal.os.BatteryStatsImpl;
77import com.android.internal.os.IResultReceiver;
78import com.android.internal.os.ProcessCpuTracker;
79import com.android.internal.os.TransferPipe;
80import com.android.internal.os.Zygote;
81import com.android.internal.util.ArrayUtils;
82import com.android.internal.util.FastPrintWriter;
83import com.android.internal.util.FastXmlSerializer;
84import com.android.internal.util.MemInfoReader;
85import com.android.internal.util.Preconditions;
86import com.android.server.AppOpsService;
87import com.android.server.AttributeCache;
88import com.android.server.IntentResolver;
89import com.android.server.LocalServices;
90import com.android.server.ServiceThread;
91import com.android.server.SystemService;
92import com.android.server.SystemServiceManager;
93import com.android.server.Watchdog;
94import com.android.server.am.ActivityStack.ActivityState;
95import com.android.server.firewall.IntentFirewall;
96import com.android.server.pm.Installer;
97import com.android.server.pm.UserManagerService;
98import com.android.server.statusbar.StatusBarManagerInternal;
99import com.android.server.wm.AppTransition;
100import com.android.server.wm.WindowManagerService;
101import com.google.android.collect.Lists;
102import com.google.android.collect.Maps;
103
104import libcore.io.IoUtils;
105import libcore.util.EmptyArray;
106
107import org.xmlpull.v1.XmlPullParser;
108import org.xmlpull.v1.XmlPullParserException;
109import org.xmlpull.v1.XmlSerializer;
110
111import android.app.Activity;
112import android.app.ActivityManager;
113import android.app.ActivityManager.RunningTaskInfo;
114import android.app.ActivityManager.StackInfo;
115import android.app.ActivityManagerInternal;
116import android.app.ActivityManagerInternal.SleepToken;
117import android.app.ActivityManagerNative;
118import android.app.ActivityOptions;
119import android.app.ActivityThread;
120import android.app.AlertDialog;
121import android.app.AppGlobals;
122import android.app.ApplicationErrorReport;
123import android.app.Dialog;
124import android.app.IActivityController;
125import android.app.IApplicationThread;
126import android.app.IInstrumentationWatcher;
127import android.app.INotificationManager;
128import android.app.IProcessObserver;
129import android.app.IServiceConnection;
130import android.app.IStopUserCallback;
131import android.app.IUiAutomationConnection;
132import android.app.IUserSwitchObserver;
133import android.app.Instrumentation;
134import android.app.Notification;
135import android.app.NotificationManager;
136import android.app.PendingIntent;
137import android.app.backup.IBackupManager;
138import android.content.ActivityNotFoundException;
139import android.content.BroadcastReceiver;
140import android.content.ClipData;
141import android.content.ComponentCallbacks2;
142import android.content.ComponentName;
143import android.content.ContentProvider;
144import android.content.ContentResolver;
145import android.content.Context;
146import android.content.DialogInterface;
147import android.content.IContentProvider;
148import android.content.IIntentReceiver;
149import android.content.IIntentSender;
150import android.content.Intent;
151import android.content.IntentFilter;
152import android.content.IntentSender;
153import android.content.pm.ActivityInfo;
154import android.content.pm.ApplicationInfo;
155import android.content.pm.ConfigurationInfo;
156import android.content.pm.IPackageDataObserver;
157import android.content.pm.IPackageManager;
158import android.content.pm.InstrumentationInfo;
159import android.content.pm.PackageInfo;
160import android.content.pm.PackageManager;
161import android.content.pm.ParceledListSlice;
162import android.content.pm.UserInfo;
163import android.content.pm.PackageManager.NameNotFoundException;
164import android.content.pm.PathPermission;
165import android.content.pm.ProviderInfo;
166import android.content.pm.ResolveInfo;
167import android.content.pm.ServiceInfo;
168import android.content.res.CompatibilityInfo;
169import android.content.res.Configuration;
170import android.net.Proxy;
171import android.net.ProxyInfo;
172import android.net.Uri;
173import android.os.Binder;
174import android.os.Build;
175import android.os.Bundle;
176import android.os.Debug;
177import android.os.DropBoxManager;
178import android.os.Environment;
179import android.os.FactoryTest;
180import android.os.FileObserver;
181import android.os.FileUtils;
182import android.os.Handler;
183import android.os.IBinder;
184import android.os.IPermissionController;
185import android.os.IProcessInfoService;
186import android.os.IRemoteCallback;
187import android.os.IUserManager;
188import android.os.Looper;
189import android.os.Message;
190import android.os.Parcel;
191import android.os.ParcelFileDescriptor;
192import android.os.PowerManagerInternal;
193import android.os.Process;
194import android.os.RemoteCallbackList;
195import android.os.RemoteException;
196import android.os.SELinux;
197import android.os.ServiceManager;
198import android.os.StrictMode;
199import android.os.SystemClock;
200import android.os.SystemProperties;
201import android.os.UpdateLock;
202import android.os.UserHandle;
203import android.os.UserManager;
204import android.provider.Settings;
205import android.text.format.DateUtils;
206import android.text.format.Time;
207import android.util.AtomicFile;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Gravity;
217import android.view.LayoutInflater;
218import android.view.View;
219import android.view.WindowManager;
220
221import dalvik.system.VMRuntime;
222
223import java.io.BufferedInputStream;
224import java.io.BufferedOutputStream;
225import java.io.DataInputStream;
226import java.io.DataOutputStream;
227import java.io.File;
228import java.io.FileDescriptor;
229import java.io.FileInputStream;
230import java.io.FileNotFoundException;
231import java.io.FileOutputStream;
232import java.io.IOException;
233import java.io.InputStreamReader;
234import java.io.PrintWriter;
235import java.io.StringWriter;
236import java.lang.ref.WeakReference;
237import java.util.ArrayList;
238import java.util.Arrays;
239import java.util.Collections;
240import java.util.Comparator;
241import java.util.HashMap;
242import java.util.HashSet;
243import java.util.Iterator;
244import java.util.List;
245import java.util.Locale;
246import java.util.Map;
247import java.util.Set;
248import java.util.concurrent.atomic.AtomicBoolean;
249import java.util.concurrent.atomic.AtomicLong;
250
251public final class ActivityManagerService extends ActivityManagerNative
252        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
253
254    private static final String USER_DATA_DIR = "/data/user/";
255    // File that stores last updated system version and called preboot receivers
256    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
257
258    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
259    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
260    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
261    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
262    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
263    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
264    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
265    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
266    private static final String TAG_LRU = TAG + POSTFIX_LRU;
267    private static final String TAG_MU = TAG + POSTFIX_MU;
268    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
269    private static final String TAG_POWER = TAG + POSTFIX_POWER;
270    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
271    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
272    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
273    private static final String TAG_PSS = TAG + POSTFIX_PSS;
274    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
275    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
276    private static final String TAG_STACK = TAG + POSTFIX_STACK;
277    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
278    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
279    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
280
281    /** Control over CPU and battery monitoring */
282    // write battery stats every 30 minutes.
283    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
284    static final boolean MONITOR_CPU_USAGE = true;
285    // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
287    // wait possibly forever for next cpu sample.
288    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
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    // Amount of time after a call to stopAppSwitches() during which we will
299    // prevent further untrusted switches from happening.
300    static final long APP_SWITCH_DELAY_TIME = 5*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real.
304    static final int PROC_START_TIMEOUT = 10*1000;
305
306    // How long we wait for a launched process to attach to the activity manager
307    // before we decide it's never going to come up for real, when the process was
308    // started with a wrapper for instrumentation (such as Valgrind) because it
309    // could take much longer than usual.
310    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
311
312    // How long to wait after going idle before forcing apps to GC.
313    static final int GC_TIMEOUT = 5*1000;
314
315    // The minimum amount of time between successive GC requests for a process.
316    static final int GC_MIN_INTERVAL = 60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process.
319    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process
322    // when the request is due to the memory state being lowered.
323    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
324
325    // The rate at which we check for apps using excessive power -- 15 mins.
326    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on wake locks to start killing things.
330    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on CPU usage to start killing things.
334    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // How long we allow a receiver to run before giving up on it.
337    static final int BROADCAST_FG_TIMEOUT = 10*1000;
338    static final int BROADCAST_BG_TIMEOUT = 60*1000;
339
340    // How long we wait until we timeout on key dispatching.
341    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
342
343    // How long we wait until we timeout on key dispatching during instrumentation.
344    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
345
346    // Amount of time we wait for observers to handle a user switch before
347    // giving up on them and unfreezing the screen.
348    static final int USER_SWITCH_TIMEOUT = 2*1000;
349
350    // Maximum number of users we allow to be running at a time.
351    static final int MAX_RUNNING_USERS = 3;
352
353    // How long to wait in getAssistContextExtras for the activity and foreground services
354    // to respond with the result.
355    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
356
357    // Maximum number of persisted Uri grants a package is allowed
358    static final int MAX_PERSISTED_URI_GRANTS = 128;
359
360    static final int MY_PID = Process.myPid();
361
362    static final String[] EMPTY_STRING_ARRAY = new String[0];
363
364    // How many bytes to write into the dropbox log before truncating
365    static final int DROPBOX_MAX_SIZE = 256 * 1024;
366
367    // Access modes for handleIncomingUser.
368    static final int ALLOW_NON_FULL = 0;
369    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
370    static final int ALLOW_FULL_ONLY = 2;
371
372    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
373
374    // Delay in notifying task stack change listeners (in millis)
375    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
376
377    /** All system services */
378    SystemServiceManager mSystemServiceManager;
379
380    private Installer mInstaller;
381
382    /** Run all ActivityStacks through this */
383    ActivityStackSupervisor mStackSupervisor;
384
385    /** Task stack change listeners. */
386    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
387            new RemoteCallbackList<ITaskStackListener>();
388
389    public IntentFirewall mIntentFirewall;
390
391    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
392    // default actuion automatically.  Important for devices without direct input
393    // devices.
394    private boolean mShowDialogs = true;
395
396    BroadcastQueue mFgBroadcastQueue;
397    BroadcastQueue mBgBroadcastQueue;
398    // Convenient for easy iteration over the queues. Foreground is first
399    // so that dispatch of foreground broadcasts gets precedence.
400    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
401
402    BroadcastQueue broadcastQueueForIntent(Intent intent) {
403        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
404        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
405                "Broadcast intent " + intent + " on "
406                + (isFg ? "foreground" : "background") + " queue");
407        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    private final RecentTasks mRecentTasks;
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    /**
436     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
437     */
438    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
439
440    /**
441     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
442     */
443    String mDeviceOwnerName;
444
445    /**
446     * Preferred activities to start on boot/user switch, as set by DevicePolicyManager. Indexed
447     * by userId.
448     */
449    SparseArray<ComponentName> mPreferredSetupActivities = new SparseArray<>();
450
451    public class PendingAssistExtras extends Binder implements Runnable {
452        public final ActivityRecord activity;
453        public final Bundle extras;
454        public final Intent intent;
455        public final String hint;
456        public final IResultReceiver receiver;
457        public final int userHandle;
458        public boolean haveResult = false;
459        public Bundle result = null;
460        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
461                String _hint, IResultReceiver _receiver, int _userHandle) {
462            activity = _activity;
463            extras = _extras;
464            intent = _intent;
465            hint = _hint;
466            receiver = _receiver;
467            userHandle = _userHandle;
468        }
469        @Override
470        public void run() {
471            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
472            synchronized (ActivityManagerService.this) {
473                synchronized (this) {
474                    haveResult = true;
475                    notifyAll();
476                }
477                pendingAssistExtrasTimedOutLocked(this);
478            }
479        }
480    }
481
482    final ArrayList<PendingAssistExtras> mPendingAssistExtras
483            = new ArrayList<PendingAssistExtras>();
484
485    /**
486     * Process management.
487     */
488    final ProcessList mProcessList = new ProcessList();
489
490    /**
491     * All of the applications we currently have running organized by name.
492     * The keys are strings of the application package name (as
493     * returned by the package manager), and the keys are ApplicationRecord
494     * objects.
495     */
496    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
497
498    /**
499     * Tracking long-term execution of processes to look for abuse and other
500     * bad app behavior.
501     */
502    final ProcessStatsService mProcessStats;
503
504    /**
505     * The currently running isolated processes.
506     */
507    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
508
509    /**
510     * Counter for assigning isolated process uids, to avoid frequently reusing the
511     * same ones.
512     */
513    int mNextIsolatedProcessUid = 0;
514
515    /**
516     * The currently running heavy-weight process, if any.
517     */
518    ProcessRecord mHeavyWeightProcess = null;
519
520    /**
521     * The last time that various processes have crashed.
522     */
523    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
524
525    /**
526     * Information about a process that is currently marked as bad.
527     */
528    static final class BadProcessInfo {
529        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
530            this.time = time;
531            this.shortMsg = shortMsg;
532            this.longMsg = longMsg;
533            this.stack = stack;
534        }
535
536        final long time;
537        final String shortMsg;
538        final String longMsg;
539        final String stack;
540    }
541
542    /**
543     * Set of applications that we consider to be bad, and will reject
544     * incoming broadcasts from (which the user has no control over).
545     * Processes are added to this set when they have crashed twice within
546     * a minimum amount of time; they are removed from it when they are
547     * later restarted (hopefully due to some user action).  The value is the
548     * time it was added to the list.
549     */
550    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
551
552    /**
553     * All of the processes we currently have running organized by pid.
554     * The keys are the pid running the application.
555     *
556     * <p>NOTE: This object is protected by its own lock, NOT the global
557     * activity manager lock!
558     */
559    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
560
561    /**
562     * All of the processes that have been forced to be foreground.  The key
563     * is the pid of the caller who requested it (we hold a death
564     * link on it).
565     */
566    abstract class ForegroundToken implements IBinder.DeathRecipient {
567        int pid;
568        IBinder token;
569    }
570    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
571
572    /**
573     * List of records for processes that someone had tried to start before the
574     * system was ready.  We don't start them at that point, but ensure they
575     * are started by the time booting is complete.
576     */
577    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
578
579    /**
580     * List of persistent applications that are in the process
581     * of being started.
582     */
583    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Processes that are being forcibly torn down.
587     */
588    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
589
590    /**
591     * List of running applications, sorted by recent usage.
592     * The first entry in the list is the least recently used.
593     */
594    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Where in mLruProcesses that the processes hosting activities start.
598     */
599    int mLruProcessActivityStart = 0;
600
601    /**
602     * Where in mLruProcesses that the processes hosting services start.
603     * This is after (lower index) than mLruProcessesActivityStart.
604     */
605    int mLruProcessServiceStart = 0;
606
607    /**
608     * List of processes that should gc as soon as things are idle.
609     */
610    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
611
612    /**
613     * Processes we want to collect PSS data from.
614     */
615    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
616
617    /**
618     * Last time we requested PSS data of all processes.
619     */
620    long mLastFullPssTime = SystemClock.uptimeMillis();
621
622    /**
623     * If set, the next time we collect PSS data we should do a full collection
624     * with data from native processes and the kernel.
625     */
626    boolean mFullPssPending = false;
627
628    /**
629     * This is the process holding what we currently consider to be
630     * the "home" activity.
631     */
632    ProcessRecord mHomeProcess;
633
634    /**
635     * This is the process holding the activity the user last visited that
636     * is in a different process from the one they are currently in.
637     */
638    ProcessRecord mPreviousProcess;
639
640    /**
641     * The time at which the previous process was last visible.
642     */
643    long mPreviousProcessVisibleTime;
644
645    /**
646     * Which uses have been started, so are allowed to run code.
647     */
648    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
649
650    /**
651     * LRU list of history of current users.  Most recently current is at the end.
652     */
653    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
654
655    /**
656     * Constant array of the users that are currently started.
657     */
658    int[] mStartedUserArray = new int[] { 0 };
659
660    /**
661     * Registered observers of the user switching mechanics.
662     */
663    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
664            = new RemoteCallbackList<IUserSwitchObserver>();
665
666    /**
667     * Currently active user switch.
668     */
669    Object mCurUserSwitchCallback;
670
671    /**
672     * Packages that the user has asked to have run in screen size
673     * compatibility mode instead of filling the screen.
674     */
675    final CompatModePackages mCompatModePackages;
676
677    /**
678     * Set of IntentSenderRecord objects that are currently active.
679     */
680    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
681            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
682
683    /**
684     * Fingerprints (hashCode()) of stack traces that we've
685     * already logged DropBox entries for.  Guarded by itself.  If
686     * something (rogue user app) forces this over
687     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
688     */
689    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
690    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
691
692    /**
693     * Strict Mode background batched logging state.
694     *
695     * The string buffer is guarded by itself, and its lock is also
696     * used to determine if another batched write is already
697     * in-flight.
698     */
699    private final StringBuilder mStrictModeBuffer = new StringBuilder();
700
701    /**
702     * Keeps track of all IIntentReceivers that have been registered for
703     * broadcasts.  Hash keys are the receiver IBinder, hash value is
704     * a ReceiverList.
705     */
706    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
707            new HashMap<IBinder, ReceiverList>();
708
709    /**
710     * Resolver for broadcast intents to registered receivers.
711     * Holds BroadcastFilter (subclass of IntentFilter).
712     */
713    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
714            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
715        @Override
716        protected boolean allowFilterResult(
717                BroadcastFilter filter, List<BroadcastFilter> dest) {
718            IBinder target = filter.receiverList.receiver.asBinder();
719            for (int i=dest.size()-1; i>=0; i--) {
720                if (dest.get(i).receiverList.receiver.asBinder() == target) {
721                    return false;
722                }
723            }
724            return true;
725        }
726
727        @Override
728        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
729            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
730                    || userId == filter.owningUserId) {
731                return super.newResult(filter, match, userId);
732            }
733            return null;
734        }
735
736        @Override
737        protected BroadcastFilter[] newArray(int size) {
738            return new BroadcastFilter[size];
739        }
740
741        @Override
742        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
743            return packageName.equals(filter.packageName);
744        }
745    };
746
747    /**
748     * State of all active sticky broadcasts per user.  Keys are the action of the
749     * sticky Intent, values are an ArrayList of all broadcasted intents with
750     * that action (which should usually be one).  The SparseArray is keyed
751     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
752     * for stickies that are sent to all users.
753     */
754    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
755            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
756
757    final ActiveServices mServices;
758
759    final static class Association {
760        final int mSourceUid;
761        final String mSourceProcess;
762        final int mTargetUid;
763        final ComponentName mTargetComponent;
764        final String mTargetProcess;
765
766        int mCount;
767        long mTime;
768
769        int mNesting;
770        long mStartTime;
771
772        Association(int sourceUid, String sourceProcess, int targetUid,
773                ComponentName targetComponent, String targetProcess) {
774            mSourceUid = sourceUid;
775            mSourceProcess = sourceProcess;
776            mTargetUid = targetUid;
777            mTargetComponent = targetComponent;
778            mTargetProcess = targetProcess;
779        }
780    }
781
782    /**
783     * When service association tracking is enabled, this is all of the associations we
784     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
785     * -> association data.
786     */
787    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
788            mAssociations = new SparseArray<>();
789    boolean mTrackingAssociations;
790
791    /**
792     * Backup/restore process management
793     */
794    String mBackupAppName = null;
795    BackupRecord mBackupTarget = null;
796
797    final ProviderMap mProviderMap;
798
799    /**
800     * List of content providers who have clients waiting for them.  The
801     * application is currently being launched and the provider will be
802     * removed from this list once it is published.
803     */
804    final ArrayList<ContentProviderRecord> mLaunchingProviders
805            = new ArrayList<ContentProviderRecord>();
806
807    /**
808     * File storing persisted {@link #mGrantedUriPermissions}.
809     */
810    private final AtomicFile mGrantFile;
811
812    /** XML constants used in {@link #mGrantFile} */
813    private static final String TAG_URI_GRANTS = "uri-grants";
814    private static final String TAG_URI_GRANT = "uri-grant";
815    private static final String ATTR_USER_HANDLE = "userHandle";
816    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
817    private static final String ATTR_TARGET_USER_ID = "targetUserId";
818    private static final String ATTR_SOURCE_PKG = "sourcePkg";
819    private static final String ATTR_TARGET_PKG = "targetPkg";
820    private static final String ATTR_URI = "uri";
821    private static final String ATTR_MODE_FLAGS = "modeFlags";
822    private static final String ATTR_CREATED_TIME = "createdTime";
823    private static final String ATTR_PREFIX = "prefix";
824
825    /**
826     * Global set of specific {@link Uri} permissions that have been granted.
827     * This optimized lookup structure maps from {@link UriPermission#targetUid}
828     * to {@link UriPermission#uri} to {@link UriPermission}.
829     */
830    @GuardedBy("this")
831    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
832            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
833
834    public static class GrantUri {
835        public final int sourceUserId;
836        public final Uri uri;
837        public boolean prefix;
838
839        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
840            this.sourceUserId = sourceUserId;
841            this.uri = uri;
842            this.prefix = prefix;
843        }
844
845        @Override
846        public int hashCode() {
847            int hashCode = 1;
848            hashCode = 31 * hashCode + sourceUserId;
849            hashCode = 31 * hashCode + uri.hashCode();
850            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
851            return hashCode;
852        }
853
854        @Override
855        public boolean equals(Object o) {
856            if (o instanceof GrantUri) {
857                GrantUri other = (GrantUri) o;
858                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
859                        && prefix == other.prefix;
860            }
861            return false;
862        }
863
864        @Override
865        public String toString() {
866            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
867            if (prefix) result += " [prefix]";
868            return result;
869        }
870
871        public String toSafeString() {
872            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
873            if (prefix) result += " [prefix]";
874            return result;
875        }
876
877        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
878            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
879                    ContentProvider.getUriWithoutUserId(uri), false);
880        }
881    }
882
883    CoreSettingsObserver mCoreSettingsObserver;
884
885    /**
886     * Thread-local storage used to carry caller permissions over through
887     * indirect content-provider access.
888     */
889    private class Identity {
890        public final IBinder token;
891        public final int pid;
892        public final int uid;
893
894        Identity(IBinder _token, int _pid, int _uid) {
895            token = _token;
896            pid = _pid;
897            uid = _uid;
898        }
899    }
900
901    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
902
903    /**
904     * All information we have collected about the runtime performance of
905     * any user id that can impact battery performance.
906     */
907    final BatteryStatsService mBatteryStatsService;
908
909    /**
910     * Information about component usage
911     */
912    UsageStatsManagerInternal mUsageStatsService;
913
914    /**
915     * Information about and control over application operations
916     */
917    final AppOpsService mAppOpsService;
918
919    /**
920     * Save recent tasks information across reboots.
921     */
922    final TaskPersister mTaskPersister;
923
924    /**
925     * Current configuration information.  HistoryRecord objects are given
926     * a reference to this object to indicate which configuration they are
927     * currently running in, so this object must be kept immutable.
928     */
929    Configuration mConfiguration = new Configuration();
930
931    /**
932     * Current sequencing integer of the configuration, for skipping old
933     * configurations.
934     */
935    int mConfigurationSeq = 0;
936
937    /**
938     * Hardware-reported OpenGLES version.
939     */
940    final int GL_ES_VERSION;
941
942    /**
943     * List of initialization arguments to pass to all processes when binding applications to them.
944     * For example, references to the commonly used services.
945     */
946    HashMap<String, IBinder> mAppBindArgs;
947
948    /**
949     * Temporary to avoid allocations.  Protected by main lock.
950     */
951    final StringBuilder mStringBuilder = new StringBuilder(256);
952
953    /**
954     * Used to control how we initialize the service.
955     */
956    ComponentName mTopComponent;
957    String mTopAction = Intent.ACTION_MAIN;
958    String mTopData;
959    boolean mProcessesReady = false;
960    boolean mSystemReady = false;
961    boolean mBooting = false;
962    boolean mCallFinishBooting = false;
963    boolean mBootAnimationComplete = false;
964    boolean mWaitingUpdate = false;
965    boolean mDidUpdate = false;
966    boolean mOnBattery = false;
967    boolean mLaunchWarningShown = false;
968
969    Context mContext;
970
971    int mFactoryTest;
972
973    boolean mCheckedForSetup;
974
975    /**
976     * The time at which we will allow normal application switches again,
977     * after a call to {@link #stopAppSwitches()}.
978     */
979    long mAppSwitchesAllowedTime;
980
981    /**
982     * This is set to true after the first switch after mAppSwitchesAllowedTime
983     * is set; any switches after that will clear the time.
984     */
985    boolean mDidAppSwitch;
986
987    /**
988     * Last time (in realtime) at which we checked for power usage.
989     */
990    long mLastPowerCheckRealtime;
991
992    /**
993     * Last time (in uptime) at which we checked for power usage.
994     */
995    long mLastPowerCheckUptime;
996
997    /**
998     * Set while we are wanting to sleep, to prevent any
999     * activities from being started/resumed.
1000     */
1001    private boolean mSleeping = false;
1002
1003    /**
1004     * The process state used for processes that are running the top activities.
1005     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1006     */
1007    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1008
1009    /**
1010     * Set while we are running a voice interaction.  This overrides
1011     * sleeping while it is active.
1012     */
1013    private IVoiceInteractionSession mRunningVoice;
1014
1015    /**
1016     * We want to hold a wake lock while running a voice interaction session, since
1017     * this may happen with the screen off and we need to keep the CPU running to
1018     * be able to continue to interact with the user.
1019     */
1020    PowerManager.WakeLock mVoiceWakeLock;
1021
1022    /**
1023     * State of external calls telling us if the device is awake or asleep.
1024     */
1025    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1026
1027    /**
1028     * A list of tokens that cause the top activity to be put to sleep.
1029     * They are used by components that may hide and block interaction with underlying
1030     * activities.
1031     */
1032    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1033
1034    static final int LOCK_SCREEN_HIDDEN = 0;
1035    static final int LOCK_SCREEN_LEAVING = 1;
1036    static final int LOCK_SCREEN_SHOWN = 2;
1037    /**
1038     * State of external call telling us if the lock screen is shown.
1039     */
1040    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1041
1042    /**
1043     * Set if we are shutting down the system, similar to sleeping.
1044     */
1045    boolean mShuttingDown = false;
1046
1047    /**
1048     * Current sequence id for oom_adj computation traversal.
1049     */
1050    int mAdjSeq = 0;
1051
1052    /**
1053     * Current sequence id for process LRU updating.
1054     */
1055    int mLruSeq = 0;
1056
1057    /**
1058     * Keep track of the non-cached/empty process we last found, to help
1059     * determine how to distribute cached/empty processes next time.
1060     */
1061    int mNumNonCachedProcs = 0;
1062
1063    /**
1064     * Keep track of the number of cached hidden procs, to balance oom adj
1065     * distribution between those and empty procs.
1066     */
1067    int mNumCachedHiddenProcs = 0;
1068
1069    /**
1070     * Keep track of the number of service processes we last found, to
1071     * determine on the next iteration which should be B services.
1072     */
1073    int mNumServiceProcs = 0;
1074    int mNewNumAServiceProcs = 0;
1075    int mNewNumServiceProcs = 0;
1076
1077    /**
1078     * Allow the current computed overall memory level of the system to go down?
1079     * This is set to false when we are killing processes for reasons other than
1080     * memory management, so that the now smaller process list will not be taken as
1081     * an indication that memory is tighter.
1082     */
1083    boolean mAllowLowerMemLevel = false;
1084
1085    /**
1086     * The last computed memory level, for holding when we are in a state that
1087     * processes are going away for other reasons.
1088     */
1089    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1090
1091    /**
1092     * The last total number of process we have, to determine if changes actually look
1093     * like a shrinking number of process due to lower RAM.
1094     */
1095    int mLastNumProcesses;
1096
1097    /**
1098     * The uptime of the last time we performed idle maintenance.
1099     */
1100    long mLastIdleTime = SystemClock.uptimeMillis();
1101
1102    /**
1103     * Total time spent with RAM that has been added in the past since the last idle time.
1104     */
1105    long mLowRamTimeSinceLastIdle = 0;
1106
1107    /**
1108     * If RAM is currently low, when that horrible situation started.
1109     */
1110    long mLowRamStartTime = 0;
1111
1112    /**
1113     * For reporting to battery stats the current top application.
1114     */
1115    private String mCurResumedPackage = null;
1116    private int mCurResumedUid = -1;
1117
1118    /**
1119     * For reporting to battery stats the apps currently running foreground
1120     * service.  The ProcessMap is package/uid tuples; each of these contain
1121     * an array of the currently foreground processes.
1122     */
1123    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1124            = new ProcessMap<ArrayList<ProcessRecord>>();
1125
1126    /**
1127     * This is set if we had to do a delayed dexopt of an app before launching
1128     * it, to increase the ANR timeouts in that case.
1129     */
1130    boolean mDidDexOpt;
1131
1132    /**
1133     * Set if the systemServer made a call to enterSafeMode.
1134     */
1135    boolean mSafeMode;
1136
1137    /**
1138     * If true, we are running under a test environment so will sample PSS from processes
1139     * much more rapidly to try to collect better data when the tests are rapidly
1140     * running through apps.
1141     */
1142    boolean mTestPssMode = false;
1143
1144    String mDebugApp = null;
1145    boolean mWaitForDebugger = false;
1146    boolean mDebugTransient = false;
1147    String mOrigDebugApp = null;
1148    boolean mOrigWaitForDebugger = false;
1149    boolean mAlwaysFinishActivities = false;
1150    IActivityController mController = null;
1151    String mProfileApp = null;
1152    ProcessRecord mProfileProc = null;
1153    String mProfileFile;
1154    ParcelFileDescriptor mProfileFd;
1155    int mSamplingInterval = 0;
1156    boolean mAutoStopProfiler = false;
1157    int mProfileType = 0;
1158    String mOpenGlTraceApp = null;
1159    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1160    String mMemWatchDumpProcName;
1161    String mMemWatchDumpFile;
1162    int mMemWatchDumpPid;
1163    int mMemWatchDumpUid;
1164
1165    final long[] mTmpLong = new long[1];
1166
1167    static class ProcessChangeItem {
1168        static final int CHANGE_ACTIVITIES = 1<<0;
1169        static final int CHANGE_PROCESS_STATE = 1<<1;
1170        int changes;
1171        int uid;
1172        int pid;
1173        int processState;
1174        boolean foregroundActivities;
1175    }
1176
1177    final RemoteCallbackList<IProcessObserver> mProcessObservers
1178            = new RemoteCallbackList<IProcessObserver>();
1179    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1180
1181    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1182            = new ArrayList<ProcessChangeItem>();
1183    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1184            = new ArrayList<ProcessChangeItem>();
1185
1186    /**
1187     * Runtime CPU use collection thread.  This object's lock is used to
1188     * perform synchronization with the thread (notifying it to run).
1189     */
1190    final Thread mProcessCpuThread;
1191
1192    /**
1193     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1194     * Must acquire this object's lock when accessing it.
1195     * NOTE: this lock will be held while doing long operations (trawling
1196     * through all processes in /proc), so it should never be acquired by
1197     * any critical paths such as when holding the main activity manager lock.
1198     */
1199    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1200            MONITOR_THREAD_CPU_USAGE);
1201    final AtomicLong mLastCpuTime = new AtomicLong(0);
1202    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1203
1204    long mLastWriteTime = 0;
1205
1206    /**
1207     * Used to retain an update lock when the foreground activity is in
1208     * immersive mode.
1209     */
1210    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1211
1212    /**
1213     * Set to true after the system has finished booting.
1214     */
1215    boolean mBooted = false;
1216
1217    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1218    int mProcessLimitOverride = -1;
1219
1220    WindowManagerService mWindowManager;
1221
1222    final ActivityThread mSystemThread;
1223
1224    // Holds the current foreground user's id
1225    int mCurrentUserId = 0;
1226    // Holds the target user's id during a user switch
1227    int mTargetUserId = UserHandle.USER_NULL;
1228    // If there are multiple profiles for the current user, their ids are here
1229    // Currently only the primary user can have managed profiles
1230    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1231
1232    /**
1233     * Mapping from each known user ID to the profile group ID it is associated with.
1234     */
1235    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1236
1237    private UserManagerService mUserManager;
1238
1239    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1240        final ProcessRecord mApp;
1241        final int mPid;
1242        final IApplicationThread mAppThread;
1243
1244        AppDeathRecipient(ProcessRecord app, int pid,
1245                IApplicationThread thread) {
1246            if (DEBUG_ALL) Slog.v(
1247                TAG, "New death recipient " + this
1248                + " for thread " + thread.asBinder());
1249            mApp = app;
1250            mPid = pid;
1251            mAppThread = thread;
1252        }
1253
1254        @Override
1255        public void binderDied() {
1256            if (DEBUG_ALL) Slog.v(
1257                TAG, "Death received in " + this
1258                + " for thread " + mAppThread.asBinder());
1259            synchronized(ActivityManagerService.this) {
1260                appDiedLocked(mApp, mPid, mAppThread, true);
1261            }
1262        }
1263    }
1264
1265    static final int SHOW_ERROR_MSG = 1;
1266    static final int SHOW_NOT_RESPONDING_MSG = 2;
1267    static final int SHOW_FACTORY_ERROR_MSG = 3;
1268    static final int UPDATE_CONFIGURATION_MSG = 4;
1269    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1270    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1271    static final int SERVICE_TIMEOUT_MSG = 12;
1272    static final int UPDATE_TIME_ZONE = 13;
1273    static final int SHOW_UID_ERROR_MSG = 14;
1274    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1275    static final int PROC_START_TIMEOUT_MSG = 20;
1276    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1277    static final int KILL_APPLICATION_MSG = 22;
1278    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1279    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1280    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1281    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1282    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1283    static final int CLEAR_DNS_CACHE_MSG = 28;
1284    static final int UPDATE_HTTP_PROXY_MSG = 29;
1285    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1286    static final int DISPATCH_PROCESSES_CHANGED = 31;
1287    static final int DISPATCH_PROCESS_DIED = 32;
1288    static final int REPORT_MEM_USAGE_MSG = 33;
1289    static final int REPORT_USER_SWITCH_MSG = 34;
1290    static final int CONTINUE_USER_SWITCH_MSG = 35;
1291    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1292    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1293    static final int PERSIST_URI_GRANTS_MSG = 38;
1294    static final int REQUEST_ALL_PSS_MSG = 39;
1295    static final int START_PROFILES_MSG = 40;
1296    static final int UPDATE_TIME = 41;
1297    static final int SYSTEM_USER_START_MSG = 42;
1298    static final int SYSTEM_USER_CURRENT_MSG = 43;
1299    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1300    static final int FINISH_BOOTING_MSG = 45;
1301    static final int START_USER_SWITCH_MSG = 46;
1302    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1303    static final int DISMISS_DIALOG_MSG = 48;
1304    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1305    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1306    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1307    static final int DELETE_DUMPHEAP_MSG = 52;
1308    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1309
1310    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1311    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1312    static final int FIRST_COMPAT_MODE_MSG = 300;
1313    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1314
1315    CompatModeDialog mCompatModeDialog;
1316    long mLastMemUsageReportTime = 0;
1317
1318    /**
1319     * Flag whether the current user is a "monkey", i.e. whether
1320     * the UI is driven by a UI automation tool.
1321     */
1322    private boolean mUserIsMonkey;
1323
1324    /** Flag whether the device has a Recents UI */
1325    boolean mHasRecents;
1326
1327    /** The dimensions of the thumbnails in the Recents UI. */
1328    int mThumbnailWidth;
1329    int mThumbnailHeight;
1330
1331    final ServiceThread mHandlerThread;
1332    final MainHandler mHandler;
1333    final UiHandler mUiHandler;
1334
1335    final class UiHandler extends Handler {
1336        public UiHandler() {
1337            super(com.android.server.UiThread.get().getLooper(), null, true);
1338        }
1339
1340        @Override
1341        public void handleMessage(Message msg) {
1342            switch (msg.what) {
1343            case SHOW_ERROR_MSG: {
1344                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1345                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1346                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1347                synchronized (ActivityManagerService.this) {
1348                    ProcessRecord proc = (ProcessRecord)data.get("app");
1349                    AppErrorResult res = (AppErrorResult) data.get("result");
1350                    if (proc != null && proc.crashDialog != null) {
1351                        Slog.e(TAG, "App already has crash dialog: " + proc);
1352                        if (res != null) {
1353                            res.set(0);
1354                        }
1355                        return;
1356                    }
1357                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1358                            >= Process.FIRST_APPLICATION_UID
1359                            && proc.pid != MY_PID);
1360                    for (int userId : mCurrentProfileIds) {
1361                        isBackground &= (proc.userId != userId);
1362                    }
1363                    if (isBackground && !showBackground) {
1364                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1365                        if (res != null) {
1366                            res.set(0);
1367                        }
1368                        return;
1369                    }
1370                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1371                        Dialog d = new AppErrorDialog(mContext,
1372                                ActivityManagerService.this, res, proc);
1373                        d.show();
1374                        proc.crashDialog = d;
1375                    } else {
1376                        // The device is asleep, so just pretend that the user
1377                        // saw a crash dialog and hit "force quit".
1378                        if (res != null) {
1379                            res.set(0);
1380                        }
1381                    }
1382                }
1383
1384                ensureBootCompleted();
1385            } break;
1386            case SHOW_NOT_RESPONDING_MSG: {
1387                synchronized (ActivityManagerService.this) {
1388                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1389                    ProcessRecord proc = (ProcessRecord)data.get("app");
1390                    if (proc != null && proc.anrDialog != null) {
1391                        Slog.e(TAG, "App already has anr dialog: " + proc);
1392                        return;
1393                    }
1394
1395                    Intent intent = new Intent("android.intent.action.ANR");
1396                    if (!mProcessesReady) {
1397                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1398                                | Intent.FLAG_RECEIVER_FOREGROUND);
1399                    }
1400                    broadcastIntentLocked(null, null, intent,
1401                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1402                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1403
1404                    if (mShowDialogs) {
1405                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1406                                mContext, proc, (ActivityRecord)data.get("activity"),
1407                                msg.arg1 != 0);
1408                        d.show();
1409                        proc.anrDialog = d;
1410                    } else {
1411                        // Just kill the app if there is no dialog to be shown.
1412                        killAppAtUsersRequest(proc, null);
1413                    }
1414                }
1415
1416                ensureBootCompleted();
1417            } break;
1418            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1419                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1420                synchronized (ActivityManagerService.this) {
1421                    ProcessRecord proc = (ProcessRecord) data.get("app");
1422                    if (proc == null) {
1423                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1424                        break;
1425                    }
1426                    if (proc.crashDialog != null) {
1427                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1428                        return;
1429                    }
1430                    AppErrorResult res = (AppErrorResult) data.get("result");
1431                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1432                        Dialog d = new StrictModeViolationDialog(mContext,
1433                                ActivityManagerService.this, res, proc);
1434                        d.show();
1435                        proc.crashDialog = d;
1436                    } else {
1437                        // The device is asleep, so just pretend that the user
1438                        // saw a crash dialog and hit "force quit".
1439                        res.set(0);
1440                    }
1441                }
1442                ensureBootCompleted();
1443            } break;
1444            case SHOW_FACTORY_ERROR_MSG: {
1445                Dialog d = new FactoryErrorDialog(
1446                    mContext, msg.getData().getCharSequence("msg"));
1447                d.show();
1448                ensureBootCompleted();
1449            } break;
1450            case WAIT_FOR_DEBUGGER_MSG: {
1451                synchronized (ActivityManagerService.this) {
1452                    ProcessRecord app = (ProcessRecord)msg.obj;
1453                    if (msg.arg1 != 0) {
1454                        if (!app.waitedForDebugger) {
1455                            Dialog d = new AppWaitingForDebuggerDialog(
1456                                    ActivityManagerService.this,
1457                                    mContext, app);
1458                            app.waitDialog = d;
1459                            app.waitedForDebugger = true;
1460                            d.show();
1461                        }
1462                    } else {
1463                        if (app.waitDialog != null) {
1464                            app.waitDialog.dismiss();
1465                            app.waitDialog = null;
1466                        }
1467                    }
1468                }
1469            } break;
1470            case SHOW_UID_ERROR_MSG: {
1471                if (mShowDialogs) {
1472                    AlertDialog d = new BaseErrorDialog(mContext);
1473                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1474                    d.setCancelable(false);
1475                    d.setTitle(mContext.getText(R.string.android_system_label));
1476                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1477                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1478                            obtainMessage(DISMISS_DIALOG_MSG, d));
1479                    d.show();
1480                }
1481            } break;
1482            case SHOW_FINGERPRINT_ERROR_MSG: {
1483                if (mShowDialogs) {
1484                    AlertDialog d = new BaseErrorDialog(mContext);
1485                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1486                    d.setCancelable(false);
1487                    d.setTitle(mContext.getText(R.string.android_system_label));
1488                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1489                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1490                            obtainMessage(DISMISS_DIALOG_MSG, d));
1491                    d.show();
1492                }
1493            } break;
1494            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1495                synchronized (ActivityManagerService.this) {
1496                    ActivityRecord ar = (ActivityRecord) msg.obj;
1497                    if (mCompatModeDialog != null) {
1498                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1499                                ar.info.applicationInfo.packageName)) {
1500                            return;
1501                        }
1502                        mCompatModeDialog.dismiss();
1503                        mCompatModeDialog = null;
1504                    }
1505                    if (ar != null && false) {
1506                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1507                                ar.packageName)) {
1508                            int mode = mCompatModePackages.computeCompatModeLocked(
1509                                    ar.info.applicationInfo);
1510                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1511                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1512                                mCompatModeDialog = new CompatModeDialog(
1513                                        ActivityManagerService.this, mContext,
1514                                        ar.info.applicationInfo);
1515                                mCompatModeDialog.show();
1516                            }
1517                        }
1518                    }
1519                }
1520                break;
1521            }
1522            case START_USER_SWITCH_MSG: {
1523                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1524                break;
1525            }
1526            case DISMISS_DIALOG_MSG: {
1527                final Dialog d = (Dialog) msg.obj;
1528                d.dismiss();
1529                break;
1530            }
1531            }
1532        }
1533    }
1534
1535    final class MainHandler extends Handler {
1536        public MainHandler(Looper looper) {
1537            super(looper, null, true);
1538        }
1539
1540        @Override
1541        public void handleMessage(Message msg) {
1542            switch (msg.what) {
1543            case UPDATE_CONFIGURATION_MSG: {
1544                final ContentResolver resolver = mContext.getContentResolver();
1545                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1546            } break;
1547            case GC_BACKGROUND_PROCESSES_MSG: {
1548                synchronized (ActivityManagerService.this) {
1549                    performAppGcsIfAppropriateLocked();
1550                }
1551            } break;
1552            case SERVICE_TIMEOUT_MSG: {
1553                if (mDidDexOpt) {
1554                    mDidDexOpt = false;
1555                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1556                    nmsg.obj = msg.obj;
1557                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1558                    return;
1559                }
1560                mServices.serviceTimeout((ProcessRecord)msg.obj);
1561            } break;
1562            case UPDATE_TIME_ZONE: {
1563                synchronized (ActivityManagerService.this) {
1564                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1565                        ProcessRecord r = mLruProcesses.get(i);
1566                        if (r.thread != null) {
1567                            try {
1568                                r.thread.updateTimeZone();
1569                            } catch (RemoteException ex) {
1570                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1571                            }
1572                        }
1573                    }
1574                }
1575            } break;
1576            case CLEAR_DNS_CACHE_MSG: {
1577                synchronized (ActivityManagerService.this) {
1578                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1579                        ProcessRecord r = mLruProcesses.get(i);
1580                        if (r.thread != null) {
1581                            try {
1582                                r.thread.clearDnsCache();
1583                            } catch (RemoteException ex) {
1584                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1585                            }
1586                        }
1587                    }
1588                }
1589            } break;
1590            case UPDATE_HTTP_PROXY_MSG: {
1591                ProxyInfo proxy = (ProxyInfo)msg.obj;
1592                String host = "";
1593                String port = "";
1594                String exclList = "";
1595                Uri pacFileUrl = Uri.EMPTY;
1596                if (proxy != null) {
1597                    host = proxy.getHost();
1598                    port = Integer.toString(proxy.getPort());
1599                    exclList = proxy.getExclusionListAsString();
1600                    pacFileUrl = proxy.getPacFileUrl();
1601                }
1602                synchronized (ActivityManagerService.this) {
1603                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1604                        ProcessRecord r = mLruProcesses.get(i);
1605                        if (r.thread != null) {
1606                            try {
1607                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1608                            } catch (RemoteException ex) {
1609                                Slog.w(TAG, "Failed to update http proxy for: " +
1610                                        r.info.processName);
1611                            }
1612                        }
1613                    }
1614                }
1615            } break;
1616            case PROC_START_TIMEOUT_MSG: {
1617                if (mDidDexOpt) {
1618                    mDidDexOpt = false;
1619                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1620                    nmsg.obj = msg.obj;
1621                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1622                    return;
1623                }
1624                ProcessRecord app = (ProcessRecord)msg.obj;
1625                synchronized (ActivityManagerService.this) {
1626                    processStartTimedOutLocked(app);
1627                }
1628            } break;
1629            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1630                synchronized (ActivityManagerService.this) {
1631                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1632                }
1633            } break;
1634            case KILL_APPLICATION_MSG: {
1635                synchronized (ActivityManagerService.this) {
1636                    int appid = msg.arg1;
1637                    boolean restart = (msg.arg2 == 1);
1638                    Bundle bundle = (Bundle)msg.obj;
1639                    String pkg = bundle.getString("pkg");
1640                    String reason = bundle.getString("reason");
1641                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1642                            false, UserHandle.USER_ALL, reason);
1643                }
1644            } break;
1645            case FINALIZE_PENDING_INTENT_MSG: {
1646                ((PendingIntentRecord)msg.obj).completeFinalize();
1647            } break;
1648            case POST_HEAVY_NOTIFICATION_MSG: {
1649                INotificationManager inm = NotificationManager.getService();
1650                if (inm == null) {
1651                    return;
1652                }
1653
1654                ActivityRecord root = (ActivityRecord)msg.obj;
1655                ProcessRecord process = root.app;
1656                if (process == null) {
1657                    return;
1658                }
1659
1660                try {
1661                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1662                    String text = mContext.getString(R.string.heavy_weight_notification,
1663                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1664                    Notification notification = new Notification();
1665                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1666                    notification.when = 0;
1667                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1668                    notification.tickerText = text;
1669                    notification.defaults = 0; // please be quiet
1670                    notification.sound = null;
1671                    notification.vibrate = null;
1672                    notification.color = mContext.getColor(
1673                            com.android.internal.R.color.system_notification_accent_color);
1674                    notification.setLatestEventInfo(context, text,
1675                            mContext.getText(R.string.heavy_weight_notification_detail),
1676                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1677                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1678                                    new UserHandle(root.userId)));
1679
1680                    try {
1681                        int[] outId = new int[1];
1682                        inm.enqueueNotificationWithTag("android", "android", null,
1683                                R.string.heavy_weight_notification,
1684                                notification, outId, root.userId);
1685                    } catch (RuntimeException e) {
1686                        Slog.w(ActivityManagerService.TAG,
1687                                "Error showing notification for heavy-weight app", e);
1688                    } catch (RemoteException e) {
1689                    }
1690                } catch (NameNotFoundException e) {
1691                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1692                }
1693            } break;
1694            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1695                INotificationManager inm = NotificationManager.getService();
1696                if (inm == null) {
1697                    return;
1698                }
1699                try {
1700                    inm.cancelNotificationWithTag("android", null,
1701                            R.string.heavy_weight_notification,  msg.arg1);
1702                } catch (RuntimeException e) {
1703                    Slog.w(ActivityManagerService.TAG,
1704                            "Error canceling notification for service", e);
1705                } catch (RemoteException e) {
1706                }
1707            } break;
1708            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1709                synchronized (ActivityManagerService.this) {
1710                    checkExcessivePowerUsageLocked(true);
1711                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1712                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1713                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1714                }
1715            } break;
1716            case DISPATCH_PROCESSES_CHANGED: {
1717                dispatchProcessesChanged();
1718                break;
1719            }
1720            case DISPATCH_PROCESS_DIED: {
1721                final int pid = msg.arg1;
1722                final int uid = msg.arg2;
1723                dispatchProcessDied(pid, uid);
1724                break;
1725            }
1726            case REPORT_MEM_USAGE_MSG: {
1727                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1728                Thread thread = new Thread() {
1729                    @Override public void run() {
1730                        reportMemUsage(memInfos);
1731                    }
1732                };
1733                thread.start();
1734                break;
1735            }
1736            case REPORT_USER_SWITCH_MSG: {
1737                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1738                break;
1739            }
1740            case CONTINUE_USER_SWITCH_MSG: {
1741                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1742                break;
1743            }
1744            case USER_SWITCH_TIMEOUT_MSG: {
1745                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1746                break;
1747            }
1748            case IMMERSIVE_MODE_LOCK_MSG: {
1749                final boolean nextState = (msg.arg1 != 0);
1750                if (mUpdateLock.isHeld() != nextState) {
1751                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1752                            "Applying new update lock state '" + nextState
1753                            + "' for " + (ActivityRecord)msg.obj);
1754                    if (nextState) {
1755                        mUpdateLock.acquire();
1756                    } else {
1757                        mUpdateLock.release();
1758                    }
1759                }
1760                break;
1761            }
1762            case PERSIST_URI_GRANTS_MSG: {
1763                writeGrantedUriPermissions();
1764                break;
1765            }
1766            case REQUEST_ALL_PSS_MSG: {
1767                synchronized (ActivityManagerService.this) {
1768                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1769                }
1770                break;
1771            }
1772            case START_PROFILES_MSG: {
1773                synchronized (ActivityManagerService.this) {
1774                    startProfilesLocked();
1775                }
1776                break;
1777            }
1778            case UPDATE_TIME: {
1779                synchronized (ActivityManagerService.this) {
1780                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1781                        ProcessRecord r = mLruProcesses.get(i);
1782                        if (r.thread != null) {
1783                            try {
1784                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1785                            } catch (RemoteException ex) {
1786                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1787                            }
1788                        }
1789                    }
1790                }
1791                break;
1792            }
1793            case SYSTEM_USER_START_MSG: {
1794                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1795                        Integer.toString(msg.arg1), msg.arg1);
1796                mSystemServiceManager.startUser(msg.arg1);
1797                break;
1798            }
1799            case SYSTEM_USER_CURRENT_MSG: {
1800                mBatteryStatsService.noteEvent(
1801                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1802                        Integer.toString(msg.arg2), msg.arg2);
1803                mBatteryStatsService.noteEvent(
1804                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1805                        Integer.toString(msg.arg1), msg.arg1);
1806                mSystemServiceManager.switchUser(msg.arg1);
1807                break;
1808            }
1809            case ENTER_ANIMATION_COMPLETE_MSG: {
1810                synchronized (ActivityManagerService.this) {
1811                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1812                    if (r != null && r.app != null && r.app.thread != null) {
1813                        try {
1814                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1815                        } catch (RemoteException e) {
1816                        }
1817                    }
1818                }
1819                break;
1820            }
1821            case FINISH_BOOTING_MSG: {
1822                if (msg.arg1 != 0) {
1823                    finishBooting();
1824                }
1825                if (msg.arg2 != 0) {
1826                    enableScreenAfterBoot();
1827                }
1828                break;
1829            }
1830            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1831                try {
1832                    Locale l = (Locale) msg.obj;
1833                    IBinder service = ServiceManager.getService("mount");
1834                    IMountService mountService = IMountService.Stub.asInterface(service);
1835                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1836                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1837                } catch (RemoteException e) {
1838                    Log.e(TAG, "Error storing locale for decryption UI", e);
1839                }
1840                break;
1841            }
1842            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1843                synchronized (ActivityManagerService.this) {
1844                    int i = mTaskStackListeners.beginBroadcast();
1845                    while (i > 0) {
1846                        i--;
1847                        try {
1848                            // Make a one-way callback to the listener
1849                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1850                        } catch (RemoteException e){
1851                            // Handled by the RemoteCallbackList
1852                        }
1853                    }
1854                    mTaskStackListeners.finishBroadcast();
1855                }
1856                break;
1857            }
1858            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1859                final int uid = msg.arg1;
1860                final byte[] firstPacket = (byte[]) msg.obj;
1861
1862                synchronized (mPidsSelfLocked) {
1863                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1864                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1865                        if (p.uid == uid) {
1866                            try {
1867                                p.thread.notifyCleartextNetwork(firstPacket);
1868                            } catch (RemoteException ignored) {
1869                            }
1870                        }
1871                    }
1872                }
1873                break;
1874            }
1875            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1876                final String procName;
1877                final int uid;
1878                final long memLimit;
1879                final String reportPackage;
1880                synchronized (ActivityManagerService.this) {
1881                    procName = mMemWatchDumpProcName;
1882                    uid = mMemWatchDumpUid;
1883                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1884                    if (val == null) {
1885                        val = mMemWatchProcesses.get(procName, 0);
1886                    }
1887                    if (val != null) {
1888                        memLimit = val.first;
1889                        reportPackage = val.second;
1890                    } else {
1891                        memLimit = 0;
1892                        reportPackage = null;
1893                    }
1894                }
1895                if (procName == null) {
1896                    return;
1897                }
1898
1899                if (DEBUG_PSS) Slog.d(TAG_PSS,
1900                        "Showing dump heap notification from " + procName + "/" + uid);
1901
1902                INotificationManager inm = NotificationManager.getService();
1903                if (inm == null) {
1904                    return;
1905                }
1906
1907                String text = mContext.getString(R.string.dump_heap_notification, procName);
1908                Notification notification = new Notification();
1909                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1910                notification.when = 0;
1911                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1912                notification.tickerText = text;
1913                notification.defaults = 0; // please be quiet
1914                notification.sound = null;
1915                notification.vibrate = null;
1916                notification.color = mContext.getColor(
1917                        com.android.internal.R.color.system_notification_accent_color);
1918                Intent deleteIntent = new Intent();
1919                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1920                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1921                        deleteIntent, 0, UserHandle.OWNER);
1922                Intent intent = new Intent();
1923                intent.setClassName("android", DumpHeapActivity.class.getName());
1924                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1925                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1926                if (reportPackage != null) {
1927                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1928                }
1929                int userId = UserHandle.getUserId(uid);
1930                notification.setLatestEventInfo(mContext, text,
1931                        mContext.getText(R.string.dump_heap_notification_detail),
1932                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1933                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1934                                new UserHandle(userId)));
1935
1936                try {
1937                    int[] outId = new int[1];
1938                    inm.enqueueNotificationWithTag("android", "android", null,
1939                            R.string.dump_heap_notification,
1940                            notification, outId, userId);
1941                } catch (RuntimeException e) {
1942                    Slog.w(ActivityManagerService.TAG,
1943                            "Error showing notification for dump heap", e);
1944                } catch (RemoteException e) {
1945                }
1946            } break;
1947            case DELETE_DUMPHEAP_MSG: {
1948                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1949                        DumpHeapActivity.JAVA_URI,
1950                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1951                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1952                        UserHandle.myUserId());
1953                synchronized (ActivityManagerService.this) {
1954                    mMemWatchDumpFile = null;
1955                    mMemWatchDumpProcName = null;
1956                    mMemWatchDumpPid = -1;
1957                    mMemWatchDumpUid = -1;
1958                }
1959            } break;
1960            case FOREGROUND_PROFILE_CHANGED_MSG: {
1961                dispatchForegroundProfileChanged(msg.arg1);
1962            } break;
1963            }
1964        }
1965    };
1966
1967    static final int COLLECT_PSS_BG_MSG = 1;
1968
1969    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1970        @Override
1971        public void handleMessage(Message msg) {
1972            switch (msg.what) {
1973            case COLLECT_PSS_BG_MSG: {
1974                long start = SystemClock.uptimeMillis();
1975                MemInfoReader memInfo = null;
1976                synchronized (ActivityManagerService.this) {
1977                    if (mFullPssPending) {
1978                        mFullPssPending = false;
1979                        memInfo = new MemInfoReader();
1980                    }
1981                }
1982                if (memInfo != null) {
1983                    updateCpuStatsNow();
1984                    long nativeTotalPss = 0;
1985                    synchronized (mProcessCpuTracker) {
1986                        final int N = mProcessCpuTracker.countStats();
1987                        for (int j=0; j<N; j++) {
1988                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1989                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1990                                // This is definitely an application process; skip it.
1991                                continue;
1992                            }
1993                            synchronized (mPidsSelfLocked) {
1994                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1995                                    // This is one of our own processes; skip it.
1996                                    continue;
1997                                }
1998                            }
1999                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2000                        }
2001                    }
2002                    memInfo.readMemInfo();
2003                    synchronized (ActivityManagerService.this) {
2004                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2005                                + (SystemClock.uptimeMillis()-start) + "ms");
2006                        final long cachedKb = memInfo.getCachedSizeKb();
2007                        final long freeKb = memInfo.getFreeSizeKb();
2008                        final long zramKb = memInfo.getZramTotalSizeKb();
2009                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2010                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2011                                kernelKb*1024, nativeTotalPss*1024);
2012                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2013                                nativeTotalPss);
2014                    }
2015                }
2016
2017                int num = 0;
2018                long[] tmp = new long[1];
2019                do {
2020                    ProcessRecord proc;
2021                    int procState;
2022                    int pid;
2023                    long lastPssTime;
2024                    synchronized (ActivityManagerService.this) {
2025                        if (mPendingPssProcesses.size() <= 0) {
2026                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2027                                    "Collected PSS of " + num + " processes in "
2028                                    + (SystemClock.uptimeMillis() - start) + "ms");
2029                            mPendingPssProcesses.clear();
2030                            return;
2031                        }
2032                        proc = mPendingPssProcesses.remove(0);
2033                        procState = proc.pssProcState;
2034                        lastPssTime = proc.lastPssTime;
2035                        if (proc.thread != null && procState == proc.setProcState
2036                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2037                                        < SystemClock.uptimeMillis()) {
2038                            pid = proc.pid;
2039                        } else {
2040                            proc = null;
2041                            pid = 0;
2042                        }
2043                    }
2044                    if (proc != null) {
2045                        long pss = Debug.getPss(pid, tmp, null);
2046                        synchronized (ActivityManagerService.this) {
2047                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2048                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2049                                num++;
2050                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2051                                        SystemClock.uptimeMillis());
2052                            }
2053                        }
2054                    }
2055                } while (true);
2056            }
2057            }
2058        }
2059    };
2060
2061    public void setSystemProcess() {
2062        try {
2063            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2064            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2065            ServiceManager.addService("meminfo", new MemBinder(this));
2066            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2067            ServiceManager.addService("dbinfo", new DbBinder(this));
2068            if (MONITOR_CPU_USAGE) {
2069                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2070            }
2071            ServiceManager.addService("permission", new PermissionController(this));
2072            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2073
2074            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2075                    "android", STOCK_PM_FLAGS);
2076            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2077
2078            synchronized (this) {
2079                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2080                app.persistent = true;
2081                app.pid = MY_PID;
2082                app.maxAdj = ProcessList.SYSTEM_ADJ;
2083                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2084                mProcessNames.put(app.processName, app.uid, app);
2085                synchronized (mPidsSelfLocked) {
2086                    mPidsSelfLocked.put(app.pid, app);
2087                }
2088                updateLruProcessLocked(app, false, null);
2089                updateOomAdjLocked();
2090            }
2091        } catch (PackageManager.NameNotFoundException e) {
2092            throw new RuntimeException(
2093                    "Unable to find android system package", e);
2094        }
2095    }
2096
2097    public void setWindowManager(WindowManagerService wm) {
2098        mWindowManager = wm;
2099        mStackSupervisor.setWindowManager(wm);
2100    }
2101
2102    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2103        mUsageStatsService = usageStatsManager;
2104    }
2105
2106    public void startObservingNativeCrashes() {
2107        final NativeCrashListener ncl = new NativeCrashListener(this);
2108        ncl.start();
2109    }
2110
2111    public IAppOpsService getAppOpsService() {
2112        return mAppOpsService;
2113    }
2114
2115    static class MemBinder extends Binder {
2116        ActivityManagerService mActivityManagerService;
2117        MemBinder(ActivityManagerService activityManagerService) {
2118            mActivityManagerService = activityManagerService;
2119        }
2120
2121        @Override
2122        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2123            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2124                    != PackageManager.PERMISSION_GRANTED) {
2125                pw.println("Permission Denial: can't dump meminfo from from pid="
2126                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2127                        + " without permission " + android.Manifest.permission.DUMP);
2128                return;
2129            }
2130
2131            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2132        }
2133    }
2134
2135    static class GraphicsBinder extends Binder {
2136        ActivityManagerService mActivityManagerService;
2137        GraphicsBinder(ActivityManagerService activityManagerService) {
2138            mActivityManagerService = activityManagerService;
2139        }
2140
2141        @Override
2142        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2143            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2144                    != PackageManager.PERMISSION_GRANTED) {
2145                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2146                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2147                        + " without permission " + android.Manifest.permission.DUMP);
2148                return;
2149            }
2150
2151            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2152        }
2153    }
2154
2155    static class DbBinder extends Binder {
2156        ActivityManagerService mActivityManagerService;
2157        DbBinder(ActivityManagerService activityManagerService) {
2158            mActivityManagerService = activityManagerService;
2159        }
2160
2161        @Override
2162        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2163            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2164                    != PackageManager.PERMISSION_GRANTED) {
2165                pw.println("Permission Denial: can't dump dbinfo from from pid="
2166                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2167                        + " without permission " + android.Manifest.permission.DUMP);
2168                return;
2169            }
2170
2171            mActivityManagerService.dumpDbInfo(fd, pw, args);
2172        }
2173    }
2174
2175    static class CpuBinder extends Binder {
2176        ActivityManagerService mActivityManagerService;
2177        CpuBinder(ActivityManagerService activityManagerService) {
2178            mActivityManagerService = activityManagerService;
2179        }
2180
2181        @Override
2182        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2183            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2184                    != PackageManager.PERMISSION_GRANTED) {
2185                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2186                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2187                        + " without permission " + android.Manifest.permission.DUMP);
2188                return;
2189            }
2190
2191            synchronized (mActivityManagerService.mProcessCpuTracker) {
2192                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2193                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2194                        SystemClock.uptimeMillis()));
2195            }
2196        }
2197    }
2198
2199    public static final class Lifecycle extends SystemService {
2200        private final ActivityManagerService mService;
2201
2202        public Lifecycle(Context context) {
2203            super(context);
2204            mService = new ActivityManagerService(context);
2205        }
2206
2207        @Override
2208        public void onStart() {
2209            mService.start();
2210        }
2211
2212        public ActivityManagerService getService() {
2213            return mService;
2214        }
2215    }
2216
2217    // Note: This method is invoked on the main thread but may need to attach various
2218    // handlers to other threads.  So take care to be explicit about the looper.
2219    public ActivityManagerService(Context systemContext) {
2220        mContext = systemContext;
2221        mFactoryTest = FactoryTest.getMode();
2222        mSystemThread = ActivityThread.currentActivityThread();
2223
2224        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2225
2226        mHandlerThread = new ServiceThread(TAG,
2227                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2228        mHandlerThread.start();
2229        mHandler = new MainHandler(mHandlerThread.getLooper());
2230        mUiHandler = new UiHandler();
2231
2232        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2233                "foreground", BROADCAST_FG_TIMEOUT, false);
2234        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2235                "background", BROADCAST_BG_TIMEOUT, true);
2236        mBroadcastQueues[0] = mFgBroadcastQueue;
2237        mBroadcastQueues[1] = mBgBroadcastQueue;
2238
2239        mServices = new ActiveServices(this);
2240        mProviderMap = new ProviderMap(this);
2241
2242        // TODO: Move creation of battery stats service outside of activity manager service.
2243        File dataDir = Environment.getDataDirectory();
2244        File systemDir = new File(dataDir, "system");
2245        systemDir.mkdirs();
2246        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2247        mBatteryStatsService.getActiveStatistics().readLocked();
2248        mBatteryStatsService.scheduleWriteToDisk();
2249        mOnBattery = DEBUG_POWER ? true
2250                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2251        mBatteryStatsService.getActiveStatistics().setCallback(this);
2252
2253        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2254
2255        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2256
2257        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2258
2259        // User 0 is the first and only user that runs at boot.
2260        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2261        mUserLru.add(UserHandle.USER_OWNER);
2262        updateStartedUserArrayLocked();
2263
2264        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2265            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2266
2267        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2268
2269        mConfiguration.setToDefaults();
2270        mConfiguration.setLocale(Locale.getDefault());
2271
2272        mConfigurationSeq = mConfiguration.seq = 1;
2273        mProcessCpuTracker.init();
2274
2275        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2276        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2277        mRecentTasks = new RecentTasks(this);
2278        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2279        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2280
2281        mProcessCpuThread = new Thread("CpuTracker") {
2282            @Override
2283            public void run() {
2284                while (true) {
2285                    try {
2286                        try {
2287                            synchronized(this) {
2288                                final long now = SystemClock.uptimeMillis();
2289                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2290                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2291                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2292                                //        + ", write delay=" + nextWriteDelay);
2293                                if (nextWriteDelay < nextCpuDelay) {
2294                                    nextCpuDelay = nextWriteDelay;
2295                                }
2296                                if (nextCpuDelay > 0) {
2297                                    mProcessCpuMutexFree.set(true);
2298                                    this.wait(nextCpuDelay);
2299                                }
2300                            }
2301                        } catch (InterruptedException e) {
2302                        }
2303                        updateCpuStatsNow();
2304                    } catch (Exception e) {
2305                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2306                    }
2307                }
2308            }
2309        };
2310
2311        Watchdog.getInstance().addMonitor(this);
2312        Watchdog.getInstance().addThread(mHandler);
2313    }
2314
2315    public void setSystemServiceManager(SystemServiceManager mgr) {
2316        mSystemServiceManager = mgr;
2317    }
2318
2319    public void setInstaller(Installer installer) {
2320        mInstaller = installer;
2321    }
2322
2323    private void start() {
2324        Process.removeAllProcessGroups();
2325        mProcessCpuThread.start();
2326
2327        mBatteryStatsService.publish(mContext);
2328        mAppOpsService.publish(mContext);
2329        Slog.d("AppOps", "AppOpsService published");
2330        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2331    }
2332
2333    public void initPowerManagement() {
2334        mStackSupervisor.initPowerManagement();
2335        mBatteryStatsService.initPowerManagement();
2336        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2337        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2338        mVoiceWakeLock.setReferenceCounted(false);
2339    }
2340
2341    @Override
2342    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2343            throws RemoteException {
2344        if (code == SYSPROPS_TRANSACTION) {
2345            // We need to tell all apps about the system property change.
2346            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2347            synchronized(this) {
2348                final int NP = mProcessNames.getMap().size();
2349                for (int ip=0; ip<NP; ip++) {
2350                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2351                    final int NA = apps.size();
2352                    for (int ia=0; ia<NA; ia++) {
2353                        ProcessRecord app = apps.valueAt(ia);
2354                        if (app.thread != null) {
2355                            procs.add(app.thread.asBinder());
2356                        }
2357                    }
2358                }
2359            }
2360
2361            int N = procs.size();
2362            for (int i=0; i<N; i++) {
2363                Parcel data2 = Parcel.obtain();
2364                try {
2365                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2366                } catch (RemoteException e) {
2367                }
2368                data2.recycle();
2369            }
2370        }
2371        try {
2372            return super.onTransact(code, data, reply, flags);
2373        } catch (RuntimeException e) {
2374            // The activity manager only throws security exceptions, so let's
2375            // log all others.
2376            if (!(e instanceof SecurityException)) {
2377                Slog.wtf(TAG, "Activity Manager Crash", e);
2378            }
2379            throw e;
2380        }
2381    }
2382
2383    void updateCpuStats() {
2384        final long now = SystemClock.uptimeMillis();
2385        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2386            return;
2387        }
2388        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2389            synchronized (mProcessCpuThread) {
2390                mProcessCpuThread.notify();
2391            }
2392        }
2393    }
2394
2395    void updateCpuStatsNow() {
2396        synchronized (mProcessCpuTracker) {
2397            mProcessCpuMutexFree.set(false);
2398            final long now = SystemClock.uptimeMillis();
2399            boolean haveNewCpuStats = false;
2400
2401            if (MONITOR_CPU_USAGE &&
2402                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2403                mLastCpuTime.set(now);
2404                mProcessCpuTracker.update();
2405                if (mProcessCpuTracker.hasGoodLastStats()) {
2406                    haveNewCpuStats = true;
2407                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2408                    //Slog.i(TAG, "Total CPU usage: "
2409                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2410
2411                    // Slog the cpu usage if the property is set.
2412                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2413                        int user = mProcessCpuTracker.getLastUserTime();
2414                        int system = mProcessCpuTracker.getLastSystemTime();
2415                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2416                        int irq = mProcessCpuTracker.getLastIrqTime();
2417                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2418                        int idle = mProcessCpuTracker.getLastIdleTime();
2419
2420                        int total = user + system + iowait + irq + softIrq + idle;
2421                        if (total == 0) total = 1;
2422
2423                        EventLog.writeEvent(EventLogTags.CPU,
2424                                ((user+system+iowait+irq+softIrq) * 100) / total,
2425                                (user * 100) / total,
2426                                (system * 100) / total,
2427                                (iowait * 100) / total,
2428                                (irq * 100) / total,
2429                                (softIrq * 100) / total);
2430                    }
2431                }
2432            }
2433
2434            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2435            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2436            synchronized(bstats) {
2437                synchronized(mPidsSelfLocked) {
2438                    if (haveNewCpuStats) {
2439                        final int perc = bstats.startAddingCpuLocked();
2440                        if (perc >= 0) {
2441                            int remainUTime = 0;
2442                            int remainSTime = 0;
2443                            int totalUTime = 0;
2444                            int totalSTime = 0;
2445                            final int N = mProcessCpuTracker.countStats();
2446                            for (int i=0; i<N; i++) {
2447                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2448                                if (!st.working) {
2449                                    continue;
2450                                }
2451                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2452                                int otherUTime = (st.rel_utime*perc)/100;
2453                                int otherSTime = (st.rel_stime*perc)/100;
2454                                remainUTime += otherUTime;
2455                                remainSTime += otherSTime;
2456                                totalUTime += st.rel_utime;
2457                                totalSTime += st.rel_stime;
2458                                if (pr != null) {
2459                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2460                                    if (ps == null || !ps.isActive()) {
2461                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2462                                                pr.info.uid, pr.processName);
2463                                    }
2464                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2465                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2466                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2467                                } else {
2468                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2469                                    if (ps == null || !ps.isActive()) {
2470                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2471                                                bstats.mapUid(st.uid), st.name);
2472                                    }
2473                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2474                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2475                                }
2476                            }
2477                            final int userTime = mProcessCpuTracker.getLastUserTime();
2478                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2479                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2480                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2481                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2482                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2483                            bstats.finishAddingCpuLocked(perc, remainUTime,
2484                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2485                                    iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes);
2486                        }
2487                    }
2488                }
2489
2490                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2491                    mLastWriteTime = now;
2492                    mBatteryStatsService.scheduleWriteToDisk();
2493                }
2494            }
2495        }
2496    }
2497
2498    @Override
2499    public void batteryNeedsCpuUpdate() {
2500        updateCpuStatsNow();
2501    }
2502
2503    @Override
2504    public void batteryPowerChanged(boolean onBattery) {
2505        // When plugging in, update the CPU stats first before changing
2506        // the plug state.
2507        updateCpuStatsNow();
2508        synchronized (this) {
2509            synchronized(mPidsSelfLocked) {
2510                mOnBattery = DEBUG_POWER ? true : onBattery;
2511            }
2512        }
2513    }
2514
2515    @Override
2516    public void batterySendBroadcast(Intent intent) {
2517        broadcastIntentLocked(null, null, intent, null,
2518                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
2519                Process.SYSTEM_UID, UserHandle.USER_ALL);
2520    }
2521
2522    /**
2523     * Initialize the application bind args. These are passed to each
2524     * process when the bindApplication() IPC is sent to the process. They're
2525     * lazily setup to make sure the services are running when they're asked for.
2526     */
2527    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2528        if (mAppBindArgs == null) {
2529            mAppBindArgs = new HashMap<>();
2530
2531            // Isolated processes won't get this optimization, so that we don't
2532            // violate the rules about which services they have access to.
2533            if (!isolated) {
2534                // Setup the application init args
2535                mAppBindArgs.put("package", ServiceManager.getService("package"));
2536                mAppBindArgs.put("window", ServiceManager.getService("window"));
2537                mAppBindArgs.put(Context.ALARM_SERVICE,
2538                        ServiceManager.getService(Context.ALARM_SERVICE));
2539            }
2540        }
2541        return mAppBindArgs;
2542    }
2543
2544    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2545        if (r != null && mFocusedActivity != r) {
2546            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2547            ActivityRecord last = mFocusedActivity;
2548            mFocusedActivity = r;
2549            if (r.task != null && r.task.voiceInteractor != null) {
2550                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2551            } else {
2552                finishRunningVoiceLocked();
2553                if (last != null && last.task.voiceSession != null) {
2554                    // We had been in a voice interaction session, but now focused has
2555                    // move to something different.  Just finish the session, we can't
2556                    // return to it and retain the proper state and synchronization with
2557                    // the voice interaction service.
2558                    finishVoiceTask(last.task.voiceSession);
2559                }
2560            }
2561            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2562                mWindowManager.setFocusedApp(r.appToken, true);
2563            }
2564            applyUpdateLockStateLocked(r);
2565            if (last != null && last.userId != mFocusedActivity.userId) {
2566                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2567                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2568                                mFocusedActivity.userId, 0));
2569            }
2570        }
2571        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2572                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2573    }
2574
2575    final void clearFocusedActivity(ActivityRecord r) {
2576        if (mFocusedActivity == r) {
2577            mFocusedActivity = null;
2578        }
2579    }
2580
2581    @Override
2582    public void setFocusedStack(int stackId) {
2583        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2584        synchronized (ActivityManagerService.this) {
2585            ActivityStack stack = mStackSupervisor.getStack(stackId);
2586            if (stack != null) {
2587                ActivityRecord r = stack.topRunningActivityLocked(null);
2588                if (r != null) {
2589                    setFocusedActivityLocked(r, "setFocusedStack");
2590                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2591                }
2592            }
2593        }
2594    }
2595
2596    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2597    @Override
2598    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2599        synchronized (ActivityManagerService.this) {
2600            if (listener != null) {
2601                mTaskStackListeners.register(listener);
2602            }
2603        }
2604    }
2605
2606    @Override
2607    public void notifyActivityDrawn(IBinder token) {
2608        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2609        synchronized (this) {
2610            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2611            if (r != null) {
2612                r.task.stack.notifyActivityDrawnLocked(r);
2613            }
2614        }
2615    }
2616
2617    final void applyUpdateLockStateLocked(ActivityRecord r) {
2618        // Modifications to the UpdateLock state are done on our handler, outside
2619        // the activity manager's locks.  The new state is determined based on the
2620        // state *now* of the relevant activity record.  The object is passed to
2621        // the handler solely for logging detail, not to be consulted/modified.
2622        final boolean nextState = r != null && r.immersive;
2623        mHandler.sendMessage(
2624                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2625    }
2626
2627    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2628        Message msg = Message.obtain();
2629        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2630        msg.obj = r.task.askedCompatMode ? null : r;
2631        mUiHandler.sendMessage(msg);
2632    }
2633
2634    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2635            String what, Object obj, ProcessRecord srcApp) {
2636        app.lastActivityTime = now;
2637
2638        if (app.activities.size() > 0) {
2639            // Don't want to touch dependent processes that are hosting activities.
2640            return index;
2641        }
2642
2643        int lrui = mLruProcesses.lastIndexOf(app);
2644        if (lrui < 0) {
2645            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2646                    + what + " " + obj + " from " + srcApp);
2647            return index;
2648        }
2649
2650        if (lrui >= index) {
2651            // Don't want to cause this to move dependent processes *back* in the
2652            // list as if they were less frequently used.
2653            return index;
2654        }
2655
2656        if (lrui >= mLruProcessActivityStart) {
2657            // Don't want to touch dependent processes that are hosting activities.
2658            return index;
2659        }
2660
2661        mLruProcesses.remove(lrui);
2662        if (index > 0) {
2663            index--;
2664        }
2665        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2666                + " in LRU list: " + app);
2667        mLruProcesses.add(index, app);
2668        return index;
2669    }
2670
2671    final void removeLruProcessLocked(ProcessRecord app) {
2672        int lrui = mLruProcesses.lastIndexOf(app);
2673        if (lrui >= 0) {
2674            if (!app.killed) {
2675                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2676                Process.killProcessQuiet(app.pid);
2677                Process.killProcessGroup(app.info.uid, app.pid);
2678            }
2679            if (lrui <= mLruProcessActivityStart) {
2680                mLruProcessActivityStart--;
2681            }
2682            if (lrui <= mLruProcessServiceStart) {
2683                mLruProcessServiceStart--;
2684            }
2685            mLruProcesses.remove(lrui);
2686        }
2687    }
2688
2689    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2690            ProcessRecord client) {
2691        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2692                || app.treatLikeActivity;
2693        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2694        if (!activityChange && hasActivity) {
2695            // The process has activities, so we are only allowing activity-based adjustments
2696            // to move it.  It should be kept in the front of the list with other
2697            // processes that have activities, and we don't want those to change their
2698            // order except due to activity operations.
2699            return;
2700        }
2701
2702        mLruSeq++;
2703        final long now = SystemClock.uptimeMillis();
2704        app.lastActivityTime = now;
2705
2706        // First a quick reject: if the app is already at the position we will
2707        // put it, then there is nothing to do.
2708        if (hasActivity) {
2709            final int N = mLruProcesses.size();
2710            if (N > 0 && mLruProcesses.get(N-1) == app) {
2711                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2712                return;
2713            }
2714        } else {
2715            if (mLruProcessServiceStart > 0
2716                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2717                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2718                return;
2719            }
2720        }
2721
2722        int lrui = mLruProcesses.lastIndexOf(app);
2723
2724        if (app.persistent && lrui >= 0) {
2725            // We don't care about the position of persistent processes, as long as
2726            // they are in the list.
2727            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2728            return;
2729        }
2730
2731        /* In progress: compute new position first, so we can avoid doing work
2732           if the process is not actually going to move.  Not yet working.
2733        int addIndex;
2734        int nextIndex;
2735        boolean inActivity = false, inService = false;
2736        if (hasActivity) {
2737            // Process has activities, put it at the very tipsy-top.
2738            addIndex = mLruProcesses.size();
2739            nextIndex = mLruProcessServiceStart;
2740            inActivity = true;
2741        } else if (hasService) {
2742            // Process has services, put it at the top of the service list.
2743            addIndex = mLruProcessActivityStart;
2744            nextIndex = mLruProcessServiceStart;
2745            inActivity = true;
2746            inService = true;
2747        } else  {
2748            // Process not otherwise of interest, it goes to the top of the non-service area.
2749            addIndex = mLruProcessServiceStart;
2750            if (client != null) {
2751                int clientIndex = mLruProcesses.lastIndexOf(client);
2752                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2753                        + app);
2754                if (clientIndex >= 0 && addIndex > clientIndex) {
2755                    addIndex = clientIndex;
2756                }
2757            }
2758            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2759        }
2760
2761        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2762                + mLruProcessActivityStart + "): " + app);
2763        */
2764
2765        if (lrui >= 0) {
2766            if (lrui < mLruProcessActivityStart) {
2767                mLruProcessActivityStart--;
2768            }
2769            if (lrui < mLruProcessServiceStart) {
2770                mLruProcessServiceStart--;
2771            }
2772            /*
2773            if (addIndex > lrui) {
2774                addIndex--;
2775            }
2776            if (nextIndex > lrui) {
2777                nextIndex--;
2778            }
2779            */
2780            mLruProcesses.remove(lrui);
2781        }
2782
2783        /*
2784        mLruProcesses.add(addIndex, app);
2785        if (inActivity) {
2786            mLruProcessActivityStart++;
2787        }
2788        if (inService) {
2789            mLruProcessActivityStart++;
2790        }
2791        */
2792
2793        int nextIndex;
2794        if (hasActivity) {
2795            final int N = mLruProcesses.size();
2796            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2797                // Process doesn't have activities, but has clients with
2798                // activities...  move it up, but one below the top (the top
2799                // should always have a real activity).
2800                if (DEBUG_LRU) Slog.d(TAG_LRU,
2801                        "Adding to second-top of LRU activity list: " + app);
2802                mLruProcesses.add(N - 1, app);
2803                // To keep it from spamming the LRU list (by making a bunch of clients),
2804                // we will push down any other entries owned by the app.
2805                final int uid = app.info.uid;
2806                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2807                    ProcessRecord subProc = mLruProcesses.get(i);
2808                    if (subProc.info.uid == uid) {
2809                        // We want to push this one down the list.  If the process after
2810                        // it is for the same uid, however, don't do so, because we don't
2811                        // want them internally to be re-ordered.
2812                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2813                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2814                                    "Pushing uid " + uid + " swapping at " + i + ": "
2815                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2816                            ProcessRecord tmp = mLruProcesses.get(i);
2817                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2818                            mLruProcesses.set(i - 1, tmp);
2819                            i--;
2820                        }
2821                    } else {
2822                        // A gap, we can stop here.
2823                        break;
2824                    }
2825                }
2826            } else {
2827                // Process has activities, put it at the very tipsy-top.
2828                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2829                mLruProcesses.add(app);
2830            }
2831            nextIndex = mLruProcessServiceStart;
2832        } else if (hasService) {
2833            // Process has services, put it at the top of the service list.
2834            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2835            mLruProcesses.add(mLruProcessActivityStart, app);
2836            nextIndex = mLruProcessServiceStart;
2837            mLruProcessActivityStart++;
2838        } else  {
2839            // Process not otherwise of interest, it goes to the top of the non-service area.
2840            int index = mLruProcessServiceStart;
2841            if (client != null) {
2842                // If there is a client, don't allow the process to be moved up higher
2843                // in the list than that client.
2844                int clientIndex = mLruProcesses.lastIndexOf(client);
2845                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2846                        + " when updating " + app);
2847                if (clientIndex <= lrui) {
2848                    // Don't allow the client index restriction to push it down farther in the
2849                    // list than it already is.
2850                    clientIndex = lrui;
2851                }
2852                if (clientIndex >= 0 && index > clientIndex) {
2853                    index = clientIndex;
2854                }
2855            }
2856            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2857            mLruProcesses.add(index, app);
2858            nextIndex = index-1;
2859            mLruProcessActivityStart++;
2860            mLruProcessServiceStart++;
2861        }
2862
2863        // If the app is currently using a content provider or service,
2864        // bump those processes as well.
2865        for (int j=app.connections.size()-1; j>=0; j--) {
2866            ConnectionRecord cr = app.connections.valueAt(j);
2867            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2868                    && cr.binding.service.app != null
2869                    && cr.binding.service.app.lruSeq != mLruSeq
2870                    && !cr.binding.service.app.persistent) {
2871                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2872                        "service connection", cr, app);
2873            }
2874        }
2875        for (int j=app.conProviders.size()-1; j>=0; j--) {
2876            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2877            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2878                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2879                        "provider reference", cpr, app);
2880            }
2881        }
2882    }
2883
2884    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2885        if (uid == Process.SYSTEM_UID) {
2886            // The system gets to run in any process.  If there are multiple
2887            // processes with the same uid, just pick the first (this
2888            // should never happen).
2889            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2890            if (procs == null) return null;
2891            final int N = procs.size();
2892            for (int i = 0; i < N; i++) {
2893                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2894            }
2895        }
2896        ProcessRecord proc = mProcessNames.get(processName, uid);
2897        if (false && proc != null && !keepIfLarge
2898                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2899                && proc.lastCachedPss >= 4000) {
2900            // Turn this condition on to cause killing to happen regularly, for testing.
2901            if (proc.baseProcessTracker != null) {
2902                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2903            }
2904            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2905        } else if (proc != null && !keepIfLarge
2906                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2907                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2908            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2909            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2910                if (proc.baseProcessTracker != null) {
2911                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2912                }
2913                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2914            }
2915        }
2916        return proc;
2917    }
2918
2919    void ensurePackageDexOpt(String packageName) {
2920        IPackageManager pm = AppGlobals.getPackageManager();
2921        try {
2922            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2923                mDidDexOpt = true;
2924            }
2925        } catch (RemoteException e) {
2926        }
2927    }
2928
2929    boolean isNextTransitionForward() {
2930        int transit = mWindowManager.getPendingAppTransition();
2931        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2932                || transit == AppTransition.TRANSIT_TASK_OPEN
2933                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2934    }
2935
2936    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2937            String processName, String abiOverride, int uid, Runnable crashHandler) {
2938        synchronized(this) {
2939            ApplicationInfo info = new ApplicationInfo();
2940            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2941            // For isolated processes, the former contains the parent's uid and the latter the
2942            // actual uid of the isolated process.
2943            // In the special case introduced by this method (which is, starting an isolated
2944            // process directly from the SystemServer without an actual parent app process) the
2945            // closest thing to a parent's uid is SYSTEM_UID.
2946            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2947            // the |isolated| logic in the ProcessRecord constructor.
2948            info.uid = Process.SYSTEM_UID;
2949            info.processName = processName;
2950            info.className = entryPoint;
2951            info.packageName = "android";
2952            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2953                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2954                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2955                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2956                    crashHandler);
2957            return proc != null ? proc.pid : 0;
2958        }
2959    }
2960
2961    final ProcessRecord startProcessLocked(String processName,
2962            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2963            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2964            boolean isolated, boolean keepIfLarge) {
2965        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2966                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2967                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2968                null /* crashHandler */);
2969    }
2970
2971    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2972            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2973            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2974            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2975        long startTime = SystemClock.elapsedRealtime();
2976        ProcessRecord app;
2977        if (!isolated) {
2978            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2979            checkTime(startTime, "startProcess: after getProcessRecord");
2980
2981            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2982                // If we are in the background, then check to see if this process
2983                // is bad.  If so, we will just silently fail.
2984                if (mBadProcesses.get(info.processName, info.uid) != null) {
2985                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2986                            + "/" + info.processName);
2987                    return null;
2988                }
2989            } else {
2990                // When the user is explicitly starting a process, then clear its
2991                // crash count so that we won't make it bad until they see at
2992                // least one crash dialog again, and make the process good again
2993                // if it had been bad.
2994                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2995                        + "/" + info.processName);
2996                mProcessCrashTimes.remove(info.processName, info.uid);
2997                if (mBadProcesses.get(info.processName, info.uid) != null) {
2998                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2999                            UserHandle.getUserId(info.uid), info.uid,
3000                            info.processName);
3001                    mBadProcesses.remove(info.processName, info.uid);
3002                    if (app != null) {
3003                        app.bad = false;
3004                    }
3005                }
3006            }
3007        } else {
3008            // If this is an isolated process, it can't re-use an existing process.
3009            app = null;
3010        }
3011
3012        // We don't have to do anything more if:
3013        // (1) There is an existing application record; and
3014        // (2) The caller doesn't think it is dead, OR there is no thread
3015        //     object attached to it so we know it couldn't have crashed; and
3016        // (3) There is a pid assigned to it, so it is either starting or
3017        //     already running.
3018        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3019                + " app=" + app + " knownToBeDead=" + knownToBeDead
3020                + " thread=" + (app != null ? app.thread : null)
3021                + " pid=" + (app != null ? app.pid : -1));
3022        if (app != null && app.pid > 0) {
3023            if (!knownToBeDead || app.thread == null) {
3024                // We already have the app running, or are waiting for it to
3025                // come up (we have a pid but not yet its thread), so keep it.
3026                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3027                // If this is a new package in the process, add the package to the list
3028                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3029                checkTime(startTime, "startProcess: done, added package to proc");
3030                return app;
3031            }
3032
3033            // An application record is attached to a previous process,
3034            // clean it up now.
3035            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3036            checkTime(startTime, "startProcess: bad proc running, killing");
3037            Process.killProcessGroup(app.info.uid, app.pid);
3038            handleAppDiedLocked(app, true, true);
3039            checkTime(startTime, "startProcess: done killing old proc");
3040        }
3041
3042        String hostingNameStr = hostingName != null
3043                ? hostingName.flattenToShortString() : null;
3044
3045        if (app == null) {
3046            checkTime(startTime, "startProcess: creating new process record");
3047            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3048            if (app == null) {
3049                Slog.w(TAG, "Failed making new process record for "
3050                        + processName + "/" + info.uid + " isolated=" + isolated);
3051                return null;
3052            }
3053            app.crashHandler = crashHandler;
3054            mProcessNames.put(processName, app.uid, app);
3055            if (isolated) {
3056                mIsolatedProcesses.put(app.uid, app);
3057            }
3058            checkTime(startTime, "startProcess: done creating new process record");
3059        } else {
3060            // If this is a new package in the process, add the package to the list
3061            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3062            checkTime(startTime, "startProcess: added package to existing proc");
3063        }
3064
3065        // If the system is not ready yet, then hold off on starting this
3066        // process until it is.
3067        if (!mProcessesReady
3068                && !isAllowedWhileBooting(info)
3069                && !allowWhileBooting) {
3070            if (!mProcessesOnHold.contains(app)) {
3071                mProcessesOnHold.add(app);
3072            }
3073            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3074                    "System not ready, putting on hold: " + app);
3075            checkTime(startTime, "startProcess: returning with proc on hold");
3076            return app;
3077        }
3078
3079        checkTime(startTime, "startProcess: stepping in to startProcess");
3080        startProcessLocked(
3081                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3082        checkTime(startTime, "startProcess: done starting proc!");
3083        return (app.pid != 0) ? app : null;
3084    }
3085
3086    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3087        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3088    }
3089
3090    private final void startProcessLocked(ProcessRecord app,
3091            String hostingType, String hostingNameStr) {
3092        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3093                null /* entryPoint */, null /* entryPointArgs */);
3094    }
3095
3096    private final void startProcessLocked(ProcessRecord app, String hostingType,
3097            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3098        long startTime = SystemClock.elapsedRealtime();
3099        if (app.pid > 0 && app.pid != MY_PID) {
3100            checkTime(startTime, "startProcess: removing from pids map");
3101            synchronized (mPidsSelfLocked) {
3102                mPidsSelfLocked.remove(app.pid);
3103                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3104            }
3105            checkTime(startTime, "startProcess: done removing from pids map");
3106            app.setPid(0);
3107        }
3108
3109        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3110                "startProcessLocked removing on hold: " + app);
3111        mProcessesOnHold.remove(app);
3112
3113        checkTime(startTime, "startProcess: starting to update cpu stats");
3114        updateCpuStats();
3115        checkTime(startTime, "startProcess: done updating cpu stats");
3116
3117        try {
3118            int uid = app.uid;
3119
3120            int[] gids = null;
3121            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3122            if (!app.isolated) {
3123                int[] permGids = null;
3124                try {
3125                    checkTime(startTime, "startProcess: getting gids from package manager");
3126                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3127                            app.userId);
3128                } catch (RemoteException e) {
3129                    Slog.w(TAG, "Unable to retrieve gids", e);
3130                }
3131
3132                /*
3133                 * Add shared application and profile GIDs so applications can share some
3134                 * resources like shared libraries and access user-wide resources
3135                 */
3136                if (ArrayUtils.isEmpty(permGids)) {
3137                    gids = new int[2];
3138                } else {
3139                    gids = new int[permGids.length + 2];
3140                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3141                }
3142                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3143                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3144            }
3145            checkTime(startTime, "startProcess: building args");
3146            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3147                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3148                        && mTopComponent != null
3149                        && app.processName.equals(mTopComponent.getPackageName())) {
3150                    uid = 0;
3151                }
3152                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3153                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3154                    uid = 0;
3155                }
3156            }
3157            int debugFlags = 0;
3158            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3159                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3160                // Also turn on CheckJNI for debuggable apps. It's quite
3161                // awkward to turn on otherwise.
3162                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3163            }
3164            // Run the app in safe mode if its manifest requests so or the
3165            // system is booted in safe mode.
3166            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3167                mSafeMode == true) {
3168                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3169            }
3170            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3171                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3172            }
3173            String jitDebugProperty = SystemProperties.get("debug.usejit");
3174            if ("true".equals(jitDebugProperty)) {
3175                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3176            } else if (!"false".equals(jitDebugProperty)) {
3177                // If we didn't force disable by setting false, defer to the dalvik vm options.
3178                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3179                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3180                }
3181            }
3182            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3183                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3184            }
3185            if ("1".equals(SystemProperties.get("debug.assert"))) {
3186                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3187            }
3188
3189            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3190            if (requiredAbi == null) {
3191                requiredAbi = Build.SUPPORTED_ABIS[0];
3192            }
3193
3194            String instructionSet = null;
3195            if (app.info.primaryCpuAbi != null) {
3196                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3197            }
3198
3199            app.gids = gids;
3200            app.requiredAbi = requiredAbi;
3201            app.instructionSet = instructionSet;
3202
3203            // Start the process.  It will either succeed and return a result containing
3204            // the PID of the new process, or else throw a RuntimeException.
3205            boolean isActivityProcess = (entryPoint == null);
3206            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3207            checkTime(startTime, "startProcess: asking zygote to start proc");
3208            Process.ProcessStartResult startResult = Process.start(entryPoint,
3209                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3210                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3211                    app.info.dataDir, entryPointArgs);
3212            checkTime(startTime, "startProcess: returned from zygote!");
3213
3214            if (app.isolated) {
3215                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3216            }
3217            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3218            checkTime(startTime, "startProcess: done updating battery stats");
3219
3220            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3221                    UserHandle.getUserId(uid), startResult.pid, uid,
3222                    app.processName, hostingType,
3223                    hostingNameStr != null ? hostingNameStr : "");
3224
3225            if (app.persistent) {
3226                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3227            }
3228
3229            checkTime(startTime, "startProcess: building log message");
3230            StringBuilder buf = mStringBuilder;
3231            buf.setLength(0);
3232            buf.append("Start proc ");
3233            buf.append(startResult.pid);
3234            buf.append(':');
3235            buf.append(app.processName);
3236            buf.append('/');
3237            UserHandle.formatUid(buf, uid);
3238            if (!isActivityProcess) {
3239                buf.append(" [");
3240                buf.append(entryPoint);
3241                buf.append("]");
3242            }
3243            buf.append(" for ");
3244            buf.append(hostingType);
3245            if (hostingNameStr != null) {
3246                buf.append(" ");
3247                buf.append(hostingNameStr);
3248            }
3249            Slog.i(TAG, buf.toString());
3250            app.setPid(startResult.pid);
3251            app.usingWrapper = startResult.usingWrapper;
3252            app.removed = false;
3253            app.killed = false;
3254            app.killedByAm = false;
3255            checkTime(startTime, "startProcess: starting to update pids map");
3256            synchronized (mPidsSelfLocked) {
3257                this.mPidsSelfLocked.put(startResult.pid, app);
3258                if (isActivityProcess) {
3259                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3260                    msg.obj = app;
3261                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3262                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3263                }
3264            }
3265            checkTime(startTime, "startProcess: done updating pids map");
3266        } catch (RuntimeException e) {
3267            // XXX do better error recovery.
3268            app.setPid(0);
3269            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3270            if (app.isolated) {
3271                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3272            }
3273            Slog.e(TAG, "Failure starting process " + app.processName, e);
3274        }
3275    }
3276
3277    void updateUsageStats(ActivityRecord component, boolean resumed) {
3278        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3279                "updateUsageStats: comp=" + component + "res=" + resumed);
3280        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3281        if (resumed) {
3282            if (mUsageStatsService != null) {
3283                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3284                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3285            }
3286            synchronized (stats) {
3287                stats.noteActivityResumedLocked(component.app.uid);
3288            }
3289        } else {
3290            if (mUsageStatsService != null) {
3291                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3292                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3293            }
3294            synchronized (stats) {
3295                stats.noteActivityPausedLocked(component.app.uid);
3296            }
3297        }
3298    }
3299
3300    Intent getHomeIntent() {
3301        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3302        intent.setComponent(mTopComponent);
3303        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3304            intent.addCategory(Intent.CATEGORY_HOME);
3305        }
3306        return intent;
3307    }
3308
3309    boolean startHomeActivityLocked(int userId, String reason) {
3310        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3311                && mTopAction == null) {
3312            // We are running in factory test mode, but unable to find
3313            // the factory test app, so just sit around displaying the
3314            // error message and don't try to start anything.
3315            return false;
3316        }
3317        Intent intent = getHomeIntent();
3318        ActivityInfo aInfo =
3319            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3320        if (aInfo != null) {
3321            intent.setComponent(new ComponentName(
3322                    aInfo.applicationInfo.packageName, aInfo.name));
3323            // Don't do this if the home app is currently being
3324            // instrumented.
3325            aInfo = new ActivityInfo(aInfo);
3326            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3327            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3328                    aInfo.applicationInfo.uid, true);
3329            if (app == null || app.instrumentationClass == null) {
3330                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3331                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3332            }
3333        }
3334
3335        return true;
3336    }
3337
3338    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3339        ActivityInfo ai = null;
3340        ComponentName comp = intent.getComponent();
3341        try {
3342            if (comp != null) {
3343                // Factory test.
3344                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3345            } else {
3346                ComponentName preferredComponent = mPreferredSetupActivities.get(userId);
3347                if (preferredComponent != null) {
3348                    ai = AppGlobals.getPackageManager().getActivityInfo(
3349                            preferredComponent, flags, userId);
3350                } else {
3351                    ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3352                            intent,
3353                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3354                                flags, userId);
3355
3356                    if (info != null) {
3357                        ai = info.activityInfo;
3358                    }
3359                }
3360            }
3361        } catch (RemoteException e) {
3362            // ignore
3363        }
3364
3365        return ai;
3366    }
3367
3368    /**
3369     * Starts the "new version setup screen" if appropriate.
3370     */
3371    void startSetupActivityLocked() {
3372        // Only do this once per boot.
3373        if (mCheckedForSetup) {
3374            return;
3375        }
3376
3377        // We will show this screen if the current one is a different
3378        // version than the last one shown, and we are not running in
3379        // low-level factory test mode.
3380        final ContentResolver resolver = mContext.getContentResolver();
3381        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3382                Settings.Global.getInt(resolver,
3383                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3384            mCheckedForSetup = true;
3385
3386            // See if we should be showing the platform update setup UI.
3387            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3388            List<ResolveInfo> ris = mContext.getPackageManager()
3389                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3390
3391            // We don't allow third party apps to replace this.
3392            ResolveInfo ri = null;
3393            for (int i=0; ris != null && i<ris.size(); i++) {
3394                if ((ris.get(i).activityInfo.applicationInfo.flags
3395                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3396                    ri = ris.get(i);
3397                    break;
3398                }
3399            }
3400
3401            if (ri != null) {
3402                String vers = ri.activityInfo.metaData != null
3403                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3404                        : null;
3405                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3406                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3407                            Intent.METADATA_SETUP_VERSION);
3408                }
3409                String lastVers = Settings.Secure.getString(
3410                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3411                if (vers != null && !vers.equals(lastVers)) {
3412                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3413                    intent.setComponent(new ComponentName(
3414                            ri.activityInfo.packageName, ri.activityInfo.name));
3415                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3416                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3417                            null);
3418                }
3419            }
3420        }
3421    }
3422
3423    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3424        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3425    }
3426
3427    void enforceNotIsolatedCaller(String caller) {
3428        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3429            throw new SecurityException("Isolated process not allowed to call " + caller);
3430        }
3431    }
3432
3433    void enforceShellRestriction(String restriction, int userHandle) {
3434        if (Binder.getCallingUid() == Process.SHELL_UID) {
3435            if (userHandle < 0
3436                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3437                throw new SecurityException("Shell does not have permission to access user "
3438                        + userHandle);
3439            }
3440        }
3441    }
3442
3443    @Override
3444    public int getFrontActivityScreenCompatMode() {
3445        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3446        synchronized (this) {
3447            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3448        }
3449    }
3450
3451    @Override
3452    public void setFrontActivityScreenCompatMode(int mode) {
3453        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3454                "setFrontActivityScreenCompatMode");
3455        synchronized (this) {
3456            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3457        }
3458    }
3459
3460    @Override
3461    public int getPackageScreenCompatMode(String packageName) {
3462        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3463        synchronized (this) {
3464            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3465        }
3466    }
3467
3468    @Override
3469    public void setPackageScreenCompatMode(String packageName, int mode) {
3470        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3471                "setPackageScreenCompatMode");
3472        synchronized (this) {
3473            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3474        }
3475    }
3476
3477    @Override
3478    public boolean getPackageAskScreenCompat(String packageName) {
3479        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3480        synchronized (this) {
3481            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3482        }
3483    }
3484
3485    @Override
3486    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3487        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3488                "setPackageAskScreenCompat");
3489        synchronized (this) {
3490            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3491        }
3492    }
3493
3494    @Override
3495    public int getPackageProcessState(String packageName) {
3496        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3497        synchronized (this) {
3498            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3499                final ProcessRecord proc = mLruProcesses.get(i);
3500                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3501                        || procState > proc.setProcState) {
3502                    boolean found = false;
3503                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3504                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3505                            procState = proc.setProcState;
3506                            found = true;
3507                        }
3508                    }
3509                    if (proc.pkgDeps != null && !found) {
3510                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3511                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3512                                procState = proc.setProcState;
3513                                break;
3514                            }
3515                        }
3516                    }
3517                }
3518            }
3519        }
3520        return procState;
3521    }
3522
3523    private void dispatchProcessesChanged() {
3524        int N;
3525        synchronized (this) {
3526            N = mPendingProcessChanges.size();
3527            if (mActiveProcessChanges.length < N) {
3528                mActiveProcessChanges = new ProcessChangeItem[N];
3529            }
3530            mPendingProcessChanges.toArray(mActiveProcessChanges);
3531            mAvailProcessChanges.addAll(mPendingProcessChanges);
3532            mPendingProcessChanges.clear();
3533            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3534                    "*** Delivering " + N + " process changes");
3535        }
3536
3537        int i = mProcessObservers.beginBroadcast();
3538        while (i > 0) {
3539            i--;
3540            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3541            if (observer != null) {
3542                try {
3543                    for (int j=0; j<N; j++) {
3544                        ProcessChangeItem item = mActiveProcessChanges[j];
3545                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3546                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3547                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3548                                    + item.uid + ": " + item.foregroundActivities);
3549                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3550                                    item.foregroundActivities);
3551                        }
3552                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3553                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3554                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3555                                    + ": " + item.processState);
3556                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3557                        }
3558                    }
3559                } catch (RemoteException e) {
3560                }
3561            }
3562        }
3563        mProcessObservers.finishBroadcast();
3564    }
3565
3566    private void dispatchProcessDied(int pid, int uid) {
3567        int i = mProcessObservers.beginBroadcast();
3568        while (i > 0) {
3569            i--;
3570            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3571            if (observer != null) {
3572                try {
3573                    observer.onProcessDied(pid, uid);
3574                } catch (RemoteException e) {
3575                }
3576            }
3577        }
3578        mProcessObservers.finishBroadcast();
3579    }
3580
3581    @Override
3582    public final int startActivity(IApplicationThread caller, String callingPackage,
3583            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3584            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3585        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3586            resultWho, requestCode, startFlags, profilerInfo, options,
3587            UserHandle.getCallingUserId());
3588    }
3589
3590    @Override
3591    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3592            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3593            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3594        enforceNotIsolatedCaller("startActivity");
3595        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3596                false, ALLOW_FULL_ONLY, "startActivity", null);
3597        // TODO: Switch to user app stacks here.
3598        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3599                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3600                profilerInfo, null, null, options, userId, null, null);
3601    }
3602
3603    @Override
3604    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3605            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3606            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3607
3608        // This is very dangerous -- it allows you to perform a start activity (including
3609        // permission grants) as any app that may launch one of your own activities.  So
3610        // we will only allow this to be done from activities that are part of the core framework,
3611        // and then only when they are running as the system.
3612        final ActivityRecord sourceRecord;
3613        final int targetUid;
3614        final String targetPackage;
3615        synchronized (this) {
3616            if (resultTo == null) {
3617                throw new SecurityException("Must be called from an activity");
3618            }
3619            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3620            if (sourceRecord == null) {
3621                throw new SecurityException("Called with bad activity token: " + resultTo);
3622            }
3623            if (!sourceRecord.info.packageName.equals("android")) {
3624                throw new SecurityException(
3625                        "Must be called from an activity that is declared in the android package");
3626            }
3627            if (sourceRecord.app == null) {
3628                throw new SecurityException("Called without a process attached to activity");
3629            }
3630            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3631                // This is still okay, as long as this activity is running under the
3632                // uid of the original calling activity.
3633                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3634                    throw new SecurityException(
3635                            "Calling activity in uid " + sourceRecord.app.uid
3636                                    + " must be system uid or original calling uid "
3637                                    + sourceRecord.launchedFromUid);
3638                }
3639            }
3640            targetUid = sourceRecord.launchedFromUid;
3641            targetPackage = sourceRecord.launchedFromPackage;
3642        }
3643
3644        if (userId == UserHandle.USER_NULL) {
3645            userId = UserHandle.getUserId(sourceRecord.app.uid);
3646        }
3647
3648        // TODO: Switch to user app stacks here.
3649        try {
3650            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3651                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3652                    null, null, options, userId, null, null);
3653            return ret;
3654        } catch (SecurityException e) {
3655            // XXX need to figure out how to propagate to original app.
3656            // A SecurityException here is generally actually a fault of the original
3657            // calling activity (such as a fairly granting permissions), so propagate it
3658            // back to them.
3659            /*
3660            StringBuilder msg = new StringBuilder();
3661            msg.append("While launching");
3662            msg.append(intent.toString());
3663            msg.append(": ");
3664            msg.append(e.getMessage());
3665            */
3666            throw e;
3667        }
3668    }
3669
3670    @Override
3671    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3672            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3673            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3674        enforceNotIsolatedCaller("startActivityAndWait");
3675        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3676                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3677        WaitResult res = new WaitResult();
3678        // TODO: Switch to user app stacks here.
3679        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3680                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3681                options, userId, null, null);
3682        return res;
3683    }
3684
3685    @Override
3686    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3687            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3688            int startFlags, Configuration config, Bundle options, int userId) {
3689        enforceNotIsolatedCaller("startActivityWithConfig");
3690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3691                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3692        // TODO: Switch to user app stacks here.
3693        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3694                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3695                null, null, config, options, userId, null, null);
3696        return ret;
3697    }
3698
3699    @Override
3700    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3701            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3702            int requestCode, int flagsMask, int flagsValues, Bundle options)
3703            throws TransactionTooLargeException {
3704        enforceNotIsolatedCaller("startActivityIntentSender");
3705        // Refuse possible leaked file descriptors
3706        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3707            throw new IllegalArgumentException("File descriptors passed in Intent");
3708        }
3709
3710        IIntentSender sender = intent.getTarget();
3711        if (!(sender instanceof PendingIntentRecord)) {
3712            throw new IllegalArgumentException("Bad PendingIntent object");
3713        }
3714
3715        PendingIntentRecord pir = (PendingIntentRecord)sender;
3716
3717        synchronized (this) {
3718            // If this is coming from the currently resumed activity, it is
3719            // effectively saying that app switches are allowed at this point.
3720            final ActivityStack stack = getFocusedStack();
3721            if (stack.mResumedActivity != null &&
3722                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3723                mAppSwitchesAllowedTime = 0;
3724            }
3725        }
3726        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3727                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3728        return ret;
3729    }
3730
3731    @Override
3732    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3733            Intent intent, String resolvedType, IVoiceInteractionSession session,
3734            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3735            Bundle options, int userId) {
3736        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3737                != PackageManager.PERMISSION_GRANTED) {
3738            String msg = "Permission Denial: startVoiceActivity() from pid="
3739                    + Binder.getCallingPid()
3740                    + ", uid=" + Binder.getCallingUid()
3741                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3742            Slog.w(TAG, msg);
3743            throw new SecurityException(msg);
3744        }
3745        if (session == null || interactor == null) {
3746            throw new NullPointerException("null session or interactor");
3747        }
3748        userId = handleIncomingUser(callingPid, callingUid, userId,
3749                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3750        // TODO: Switch to user app stacks here.
3751        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3752                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3753                null, options, userId, null, null);
3754    }
3755
3756    @Override
3757    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3758        synchronized (this) {
3759            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3760                if (keepAwake) {
3761                    mVoiceWakeLock.acquire();
3762                } else {
3763                    mVoiceWakeLock.release();
3764                }
3765            }
3766        }
3767    }
3768
3769    @Override
3770    public boolean startNextMatchingActivity(IBinder callingActivity,
3771            Intent intent, Bundle options) {
3772        // Refuse possible leaked file descriptors
3773        if (intent != null && intent.hasFileDescriptors() == true) {
3774            throw new IllegalArgumentException("File descriptors passed in Intent");
3775        }
3776
3777        synchronized (this) {
3778            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3779            if (r == null) {
3780                ActivityOptions.abort(options);
3781                return false;
3782            }
3783            if (r.app == null || r.app.thread == null) {
3784                // The caller is not running...  d'oh!
3785                ActivityOptions.abort(options);
3786                return false;
3787            }
3788            intent = new Intent(intent);
3789            // The caller is not allowed to change the data.
3790            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3791            // And we are resetting to find the next component...
3792            intent.setComponent(null);
3793
3794            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3795
3796            ActivityInfo aInfo = null;
3797            try {
3798                List<ResolveInfo> resolves =
3799                    AppGlobals.getPackageManager().queryIntentActivities(
3800                            intent, r.resolvedType,
3801                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3802                            UserHandle.getCallingUserId());
3803
3804                // Look for the original activity in the list...
3805                final int N = resolves != null ? resolves.size() : 0;
3806                for (int i=0; i<N; i++) {
3807                    ResolveInfo rInfo = resolves.get(i);
3808                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3809                            && rInfo.activityInfo.name.equals(r.info.name)) {
3810                        // We found the current one...  the next matching is
3811                        // after it.
3812                        i++;
3813                        if (i<N) {
3814                            aInfo = resolves.get(i).activityInfo;
3815                        }
3816                        if (debug) {
3817                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3818                                    + "/" + r.info.name);
3819                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3820                                    + "/" + aInfo.name);
3821                        }
3822                        break;
3823                    }
3824                }
3825            } catch (RemoteException e) {
3826            }
3827
3828            if (aInfo == null) {
3829                // Nobody who is next!
3830                ActivityOptions.abort(options);
3831                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3832                return false;
3833            }
3834
3835            intent.setComponent(new ComponentName(
3836                    aInfo.applicationInfo.packageName, aInfo.name));
3837            intent.setFlags(intent.getFlags()&~(
3838                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3839                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3840                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3841                    Intent.FLAG_ACTIVITY_NEW_TASK));
3842
3843            // Okay now we need to start the new activity, replacing the
3844            // currently running activity.  This is a little tricky because
3845            // we want to start the new one as if the current one is finished,
3846            // but not finish the current one first so that there is no flicker.
3847            // And thus...
3848            final boolean wasFinishing = r.finishing;
3849            r.finishing = true;
3850
3851            // Propagate reply information over to the new activity.
3852            final ActivityRecord resultTo = r.resultTo;
3853            final String resultWho = r.resultWho;
3854            final int requestCode = r.requestCode;
3855            r.resultTo = null;
3856            if (resultTo != null) {
3857                resultTo.removeResultsLocked(r, resultWho, requestCode);
3858            }
3859
3860            final long origId = Binder.clearCallingIdentity();
3861            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3862                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3863                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3864                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3865            Binder.restoreCallingIdentity(origId);
3866
3867            r.finishing = wasFinishing;
3868            if (res != ActivityManager.START_SUCCESS) {
3869                return false;
3870            }
3871            return true;
3872        }
3873    }
3874
3875    @Override
3876    public final int startActivityFromRecents(int taskId, Bundle options) {
3877        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3878            String msg = "Permission Denial: startActivityFromRecents called without " +
3879                    START_TASKS_FROM_RECENTS;
3880            Slog.w(TAG, msg);
3881            throw new SecurityException(msg);
3882        }
3883        return startActivityFromRecentsInner(taskId, options);
3884    }
3885
3886    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3887        final TaskRecord task;
3888        final int callingUid;
3889        final String callingPackage;
3890        final Intent intent;
3891        final int userId;
3892        synchronized (this) {
3893            task = mRecentTasks.taskForIdLocked(taskId);
3894            if (task == null) {
3895                throw new IllegalArgumentException("Task " + taskId + " not found.");
3896            }
3897            if (task.getRootActivity() != null) {
3898                moveTaskToFrontLocked(task.taskId, 0, null);
3899                return ActivityManager.START_TASK_TO_FRONT;
3900            }
3901            callingUid = task.mCallingUid;
3902            callingPackage = task.mCallingPackage;
3903            intent = task.intent;
3904            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3905            userId = task.userId;
3906        }
3907        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3908                options, userId, null, task);
3909    }
3910
3911    final int startActivityInPackage(int uid, String callingPackage,
3912            Intent intent, String resolvedType, IBinder resultTo,
3913            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3914            IActivityContainer container, TaskRecord inTask) {
3915
3916        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3917                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3918
3919        // TODO: Switch to user app stacks here.
3920        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3921                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3922                null, null, null, options, userId, container, inTask);
3923        return ret;
3924    }
3925
3926    @Override
3927    public final int startActivities(IApplicationThread caller, String callingPackage,
3928            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3929            int userId) {
3930        enforceNotIsolatedCaller("startActivities");
3931        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3932                false, ALLOW_FULL_ONLY, "startActivity", null);
3933        // TODO: Switch to user app stacks here.
3934        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3935                resolvedTypes, resultTo, options, userId);
3936        return ret;
3937    }
3938
3939    final int startActivitiesInPackage(int uid, String callingPackage,
3940            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3941            Bundle options, int userId) {
3942
3943        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3944                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3945        // TODO: Switch to user app stacks here.
3946        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3947                resultTo, options, userId);
3948        return ret;
3949    }
3950
3951    @Override
3952    public void reportActivityFullyDrawn(IBinder token) {
3953        synchronized (this) {
3954            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3955            if (r == null) {
3956                return;
3957            }
3958            r.reportFullyDrawnLocked();
3959        }
3960    }
3961
3962    @Override
3963    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3964        synchronized (this) {
3965            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3966            if (r == null) {
3967                return;
3968            }
3969            if (r.task != null && r.task.mResizeable) {
3970                // Fixed screen orientation isn't supported with resizeable activities.
3971                return;
3972            }
3973            final long origId = Binder.clearCallingIdentity();
3974            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3975            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3976                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3977            if (config != null) {
3978                r.frozenBeforeDestroy = true;
3979                if (!updateConfigurationLocked(config, r, false, false)) {
3980                    mStackSupervisor.resumeTopActivitiesLocked();
3981                }
3982            }
3983            Binder.restoreCallingIdentity(origId);
3984        }
3985    }
3986
3987    @Override
3988    public int getRequestedOrientation(IBinder token) {
3989        synchronized (this) {
3990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3991            if (r == null) {
3992                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3993            }
3994            return mWindowManager.getAppOrientation(r.appToken);
3995        }
3996    }
3997
3998    /**
3999     * This is the internal entry point for handling Activity.finish().
4000     *
4001     * @param token The Binder token referencing the Activity we want to finish.
4002     * @param resultCode Result code, if any, from this Activity.
4003     * @param resultData Result data (Intent), if any, from this Activity.
4004     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4005     *            the root Activity in the task.
4006     *
4007     * @return Returns true if the activity successfully finished, or false if it is still running.
4008     */
4009    @Override
4010    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4011            boolean finishTask) {
4012        // Refuse possible leaked file descriptors
4013        if (resultData != null && resultData.hasFileDescriptors() == true) {
4014            throw new IllegalArgumentException("File descriptors passed in Intent");
4015        }
4016
4017        synchronized(this) {
4018            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4019            if (r == null) {
4020                return true;
4021            }
4022            // Keep track of the root activity of the task before we finish it
4023            TaskRecord tr = r.task;
4024            ActivityRecord rootR = tr.getRootActivity();
4025            if (rootR == null) {
4026                Slog.w(TAG, "Finishing task with all activities already finished");
4027            }
4028            // Do not allow task to finish if last task in lockTask mode. Launchable apps can
4029            // finish themselves.
4030            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r &&
4031                    mStackSupervisor.isLastLockedTask(tr)) {
4032                Slog.i(TAG, "Not finishing task in lock task mode");
4033                mStackSupervisor.showLockTaskToast();
4034                return false;
4035            }
4036            if (mController != null) {
4037                // Find the first activity that is not finishing.
4038                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4039                if (next != null) {
4040                    // ask watcher if this is allowed
4041                    boolean resumeOK = true;
4042                    try {
4043                        resumeOK = mController.activityResuming(next.packageName);
4044                    } catch (RemoteException e) {
4045                        mController = null;
4046                        Watchdog.getInstance().setActivityController(null);
4047                    }
4048
4049                    if (!resumeOK) {
4050                        Slog.i(TAG, "Not finishing activity because controller resumed");
4051                        return false;
4052                    }
4053                }
4054            }
4055            final long origId = Binder.clearCallingIdentity();
4056            try {
4057                boolean res;
4058                if (finishTask && r == rootR) {
4059                    // If requested, remove the task that is associated to this activity only if it
4060                    // was the root activity in the task. The result code and data is ignored
4061                    // because we don't support returning them across task boundaries.
4062                    res = removeTaskByIdLocked(tr.taskId, false);
4063                    if (!res) {
4064                        Slog.i(TAG, "Removing task failed to finish activity");
4065                    }
4066                } else {
4067                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4068                            resultData, "app-request", true);
4069                    if (!res) {
4070                        Slog.i(TAG, "Failed to finish by app-request");
4071                    }
4072                }
4073                return res;
4074            } finally {
4075                Binder.restoreCallingIdentity(origId);
4076            }
4077        }
4078    }
4079
4080    @Override
4081    public final void finishHeavyWeightApp() {
4082        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4083                != PackageManager.PERMISSION_GRANTED) {
4084            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4085                    + Binder.getCallingPid()
4086                    + ", uid=" + Binder.getCallingUid()
4087                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4088            Slog.w(TAG, msg);
4089            throw new SecurityException(msg);
4090        }
4091
4092        synchronized(this) {
4093            if (mHeavyWeightProcess == null) {
4094                return;
4095            }
4096
4097            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4098            for (int i = 0; i < activities.size(); i++) {
4099                ActivityRecord r = activities.get(i);
4100                if (!r.finishing && r.isInStackLocked()) {
4101                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4102                            null, "finish-heavy", true);
4103                }
4104            }
4105
4106            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4107                    mHeavyWeightProcess.userId, 0));
4108            mHeavyWeightProcess = null;
4109        }
4110    }
4111
4112    @Override
4113    public void crashApplication(int uid, int initialPid, String packageName,
4114            String message) {
4115        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4116                != PackageManager.PERMISSION_GRANTED) {
4117            String msg = "Permission Denial: crashApplication() from pid="
4118                    + Binder.getCallingPid()
4119                    + ", uid=" + Binder.getCallingUid()
4120                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4121            Slog.w(TAG, msg);
4122            throw new SecurityException(msg);
4123        }
4124
4125        synchronized(this) {
4126            ProcessRecord proc = null;
4127
4128            // Figure out which process to kill.  We don't trust that initialPid
4129            // still has any relation to current pids, so must scan through the
4130            // list.
4131            synchronized (mPidsSelfLocked) {
4132                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4133                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4134                    if (p.uid != uid) {
4135                        continue;
4136                    }
4137                    if (p.pid == initialPid) {
4138                        proc = p;
4139                        break;
4140                    }
4141                    if (p.pkgList.containsKey(packageName)) {
4142                        proc = p;
4143                    }
4144                }
4145            }
4146
4147            if (proc == null) {
4148                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4149                        + " initialPid=" + initialPid
4150                        + " packageName=" + packageName);
4151                return;
4152            }
4153
4154            if (proc.thread != null) {
4155                if (proc.pid == Process.myPid()) {
4156                    Log.w(TAG, "crashApplication: trying to crash self!");
4157                    return;
4158                }
4159                long ident = Binder.clearCallingIdentity();
4160                try {
4161                    proc.thread.scheduleCrash(message);
4162                } catch (RemoteException e) {
4163                }
4164                Binder.restoreCallingIdentity(ident);
4165            }
4166        }
4167    }
4168
4169    @Override
4170    public final void finishSubActivity(IBinder token, String resultWho,
4171            int requestCode) {
4172        synchronized(this) {
4173            final long origId = Binder.clearCallingIdentity();
4174            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4175            if (r != null) {
4176                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4177            }
4178            Binder.restoreCallingIdentity(origId);
4179        }
4180    }
4181
4182    @Override
4183    public boolean finishActivityAffinity(IBinder token) {
4184        synchronized(this) {
4185            final long origId = Binder.clearCallingIdentity();
4186            try {
4187                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4188                if (r == null) {
4189                    return false;
4190                }
4191
4192                // Do not allow the last non-launchable task to finish in Lock Task mode.
4193                final TaskRecord task = r.task;
4194                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE &&
4195                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4196                    mStackSupervisor.showLockTaskToast();
4197                    return false;
4198                }
4199                return task.stack.finishActivityAffinityLocked(r);
4200            } finally {
4201                Binder.restoreCallingIdentity(origId);
4202            }
4203        }
4204    }
4205
4206    @Override
4207    public void finishVoiceTask(IVoiceInteractionSession session) {
4208        synchronized(this) {
4209            final long origId = Binder.clearCallingIdentity();
4210            try {
4211                mStackSupervisor.finishVoiceTask(session);
4212            } finally {
4213                Binder.restoreCallingIdentity(origId);
4214            }
4215        }
4216
4217    }
4218
4219    @Override
4220    public boolean releaseActivityInstance(IBinder token) {
4221        synchronized(this) {
4222            final long origId = Binder.clearCallingIdentity();
4223            try {
4224                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4225                if (r == null) {
4226                    return false;
4227                }
4228                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4229            } finally {
4230                Binder.restoreCallingIdentity(origId);
4231            }
4232        }
4233    }
4234
4235    @Override
4236    public void releaseSomeActivities(IApplicationThread appInt) {
4237        synchronized(this) {
4238            final long origId = Binder.clearCallingIdentity();
4239            try {
4240                ProcessRecord app = getRecordForAppLocked(appInt);
4241                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4242            } finally {
4243                Binder.restoreCallingIdentity(origId);
4244            }
4245        }
4246    }
4247
4248    @Override
4249    public boolean willActivityBeVisible(IBinder token) {
4250        synchronized(this) {
4251            ActivityStack stack = ActivityRecord.getStackLocked(token);
4252            if (stack != null) {
4253                return stack.willActivityBeVisibleLocked(token);
4254            }
4255            return false;
4256        }
4257    }
4258
4259    @Override
4260    public void overridePendingTransition(IBinder token, String packageName,
4261            int enterAnim, int exitAnim) {
4262        synchronized(this) {
4263            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4264            if (self == null) {
4265                return;
4266            }
4267
4268            final long origId = Binder.clearCallingIdentity();
4269
4270            if (self.state == ActivityState.RESUMED
4271                    || self.state == ActivityState.PAUSING) {
4272                mWindowManager.overridePendingAppTransition(packageName,
4273                        enterAnim, exitAnim, null);
4274            }
4275
4276            Binder.restoreCallingIdentity(origId);
4277        }
4278    }
4279
4280    /**
4281     * Main function for removing an existing process from the activity manager
4282     * as a result of that process going away.  Clears out all connections
4283     * to the process.
4284     */
4285    private final void handleAppDiedLocked(ProcessRecord app,
4286            boolean restarting, boolean allowRestart) {
4287        int pid = app.pid;
4288        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4289        if (!kept && !restarting) {
4290            removeLruProcessLocked(app);
4291            if (pid > 0) {
4292                ProcessList.remove(pid);
4293            }
4294        }
4295
4296        if (mProfileProc == app) {
4297            clearProfilerLocked();
4298        }
4299
4300        // Remove this application's activities from active lists.
4301        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4302
4303        app.activities.clear();
4304
4305        if (app.instrumentationClass != null) {
4306            Slog.w(TAG, "Crash of app " + app.processName
4307                  + " running instrumentation " + app.instrumentationClass);
4308            Bundle info = new Bundle();
4309            info.putString("shortMsg", "Process crashed.");
4310            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4311        }
4312
4313        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4314            // If there was nothing to resume, and we are not already
4315            // restarting this process, but there is a visible activity that
4316            // is hosted by the process...  then make sure all visible
4317            // activities are running, taking care of restarting this
4318            // process.
4319            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4320        }
4321    }
4322
4323    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4324        IBinder threadBinder = thread.asBinder();
4325        // Find the application record.
4326        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4327            ProcessRecord rec = mLruProcesses.get(i);
4328            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4329                return i;
4330            }
4331        }
4332        return -1;
4333    }
4334
4335    final ProcessRecord getRecordForAppLocked(
4336            IApplicationThread thread) {
4337        if (thread == null) {
4338            return null;
4339        }
4340
4341        int appIndex = getLRURecordIndexForAppLocked(thread);
4342        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4343    }
4344
4345    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4346        // If there are no longer any background processes running,
4347        // and the app that died was not running instrumentation,
4348        // then tell everyone we are now low on memory.
4349        boolean haveBg = false;
4350        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4351            ProcessRecord rec = mLruProcesses.get(i);
4352            if (rec.thread != null
4353                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4354                haveBg = true;
4355                break;
4356            }
4357        }
4358
4359        if (!haveBg) {
4360            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4361            if (doReport) {
4362                long now = SystemClock.uptimeMillis();
4363                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4364                    doReport = false;
4365                } else {
4366                    mLastMemUsageReportTime = now;
4367                }
4368            }
4369            final ArrayList<ProcessMemInfo> memInfos
4370                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4371            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4372            long now = SystemClock.uptimeMillis();
4373            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4374                ProcessRecord rec = mLruProcesses.get(i);
4375                if (rec == dyingProc || rec.thread == null) {
4376                    continue;
4377                }
4378                if (doReport) {
4379                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4380                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4381                }
4382                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4383                    // The low memory report is overriding any current
4384                    // state for a GC request.  Make sure to do
4385                    // heavy/important/visible/foreground processes first.
4386                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4387                        rec.lastRequestedGc = 0;
4388                    } else {
4389                        rec.lastRequestedGc = rec.lastLowMemory;
4390                    }
4391                    rec.reportLowMemory = true;
4392                    rec.lastLowMemory = now;
4393                    mProcessesToGc.remove(rec);
4394                    addProcessToGcListLocked(rec);
4395                }
4396            }
4397            if (doReport) {
4398                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4399                mHandler.sendMessage(msg);
4400            }
4401            scheduleAppGcsLocked();
4402        }
4403    }
4404
4405    final void appDiedLocked(ProcessRecord app) {
4406       appDiedLocked(app, app.pid, app.thread, false);
4407    }
4408
4409    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4410            boolean fromBinderDied) {
4411        // First check if this ProcessRecord is actually active for the pid.
4412        synchronized (mPidsSelfLocked) {
4413            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4414            if (curProc != app) {
4415                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4416                return;
4417            }
4418        }
4419
4420        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4421        synchronized (stats) {
4422            stats.noteProcessDiedLocked(app.info.uid, pid);
4423        }
4424
4425        if (!app.killed) {
4426            if (!fromBinderDied) {
4427                Process.killProcessQuiet(pid);
4428            }
4429            Process.killProcessGroup(app.info.uid, pid);
4430            app.killed = true;
4431        }
4432
4433        // Clean up already done if the process has been re-started.
4434        if (app.pid == pid && app.thread != null &&
4435                app.thread.asBinder() == thread.asBinder()) {
4436            boolean doLowMem = app.instrumentationClass == null;
4437            boolean doOomAdj = doLowMem;
4438            if (!app.killedByAm) {
4439                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4440                        + ") has died");
4441                mAllowLowerMemLevel = true;
4442            } else {
4443                // Note that we always want to do oom adj to update our state with the
4444                // new number of procs.
4445                mAllowLowerMemLevel = false;
4446                doLowMem = false;
4447            }
4448            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4449            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4450                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4451            handleAppDiedLocked(app, false, true);
4452
4453            if (doOomAdj) {
4454                updateOomAdjLocked();
4455            }
4456            if (doLowMem) {
4457                doLowMemReportIfNeededLocked(app);
4458            }
4459        } else if (app.pid != pid) {
4460            // A new process has already been started.
4461            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4462                    + ") has died and restarted (pid " + app.pid + ").");
4463            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4464        } else if (DEBUG_PROCESSES) {
4465            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4466                    + thread.asBinder());
4467        }
4468    }
4469
4470    /**
4471     * If a stack trace dump file is configured, dump process stack traces.
4472     * @param clearTraces causes the dump file to be erased prior to the new
4473     *    traces being written, if true; when false, the new traces will be
4474     *    appended to any existing file content.
4475     * @param firstPids of dalvik VM processes to dump stack traces for first
4476     * @param lastPids of dalvik VM processes to dump stack traces for last
4477     * @param nativeProcs optional list of native process names to dump stack crawls
4478     * @return file containing stack traces, or null if no dump file is configured
4479     */
4480    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4481            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4482        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4483        if (tracesPath == null || tracesPath.length() == 0) {
4484            return null;
4485        }
4486
4487        File tracesFile = new File(tracesPath);
4488        try {
4489            File tracesDir = tracesFile.getParentFile();
4490            if (!tracesDir.exists()) {
4491                tracesDir.mkdirs();
4492                if (!SELinux.restorecon(tracesDir)) {
4493                    return null;
4494                }
4495            }
4496            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4497
4498            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4499            tracesFile.createNewFile();
4500            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4501        } catch (IOException e) {
4502            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4503            return null;
4504        }
4505
4506        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4507        return tracesFile;
4508    }
4509
4510    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4511            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4512        // Use a FileObserver to detect when traces finish writing.
4513        // The order of traces is considered important to maintain for legibility.
4514        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4515            @Override
4516            public synchronized void onEvent(int event, String path) { notify(); }
4517        };
4518
4519        try {
4520            observer.startWatching();
4521
4522            // First collect all of the stacks of the most important pids.
4523            if (firstPids != null) {
4524                try {
4525                    int num = firstPids.size();
4526                    for (int i = 0; i < num; i++) {
4527                        synchronized (observer) {
4528                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4529                            observer.wait(200);  // Wait for write-close, give up after 200msec
4530                        }
4531                    }
4532                } catch (InterruptedException e) {
4533                    Slog.wtf(TAG, e);
4534                }
4535            }
4536
4537            // Next collect the stacks of the native pids
4538            if (nativeProcs != null) {
4539                int[] pids = Process.getPidsForCommands(nativeProcs);
4540                if (pids != null) {
4541                    for (int pid : pids) {
4542                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4543                    }
4544                }
4545            }
4546
4547            // Lastly, measure CPU usage.
4548            if (processCpuTracker != null) {
4549                processCpuTracker.init();
4550                System.gc();
4551                processCpuTracker.update();
4552                try {
4553                    synchronized (processCpuTracker) {
4554                        processCpuTracker.wait(500); // measure over 1/2 second.
4555                    }
4556                } catch (InterruptedException e) {
4557                }
4558                processCpuTracker.update();
4559
4560                // We'll take the stack crawls of just the top apps using CPU.
4561                final int N = processCpuTracker.countWorkingStats();
4562                int numProcs = 0;
4563                for (int i=0; i<N && numProcs<5; i++) {
4564                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4565                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4566                        numProcs++;
4567                        try {
4568                            synchronized (observer) {
4569                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4570                                observer.wait(200);  // Wait for write-close, give up after 200msec
4571                            }
4572                        } catch (InterruptedException e) {
4573                            Slog.wtf(TAG, e);
4574                        }
4575
4576                    }
4577                }
4578            }
4579        } finally {
4580            observer.stopWatching();
4581        }
4582    }
4583
4584    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4585        if (true || IS_USER_BUILD) {
4586            return;
4587        }
4588        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4589        if (tracesPath == null || tracesPath.length() == 0) {
4590            return;
4591        }
4592
4593        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4594        StrictMode.allowThreadDiskWrites();
4595        try {
4596            final File tracesFile = new File(tracesPath);
4597            final File tracesDir = tracesFile.getParentFile();
4598            final File tracesTmp = new File(tracesDir, "__tmp__");
4599            try {
4600                if (!tracesDir.exists()) {
4601                    tracesDir.mkdirs();
4602                    if (!SELinux.restorecon(tracesDir.getPath())) {
4603                        return;
4604                    }
4605                }
4606                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4607
4608                if (tracesFile.exists()) {
4609                    tracesTmp.delete();
4610                    tracesFile.renameTo(tracesTmp);
4611                }
4612                StringBuilder sb = new StringBuilder();
4613                Time tobj = new Time();
4614                tobj.set(System.currentTimeMillis());
4615                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4616                sb.append(": ");
4617                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4618                sb.append(" since ");
4619                sb.append(msg);
4620                FileOutputStream fos = new FileOutputStream(tracesFile);
4621                fos.write(sb.toString().getBytes());
4622                if (app == null) {
4623                    fos.write("\n*** No application process!".getBytes());
4624                }
4625                fos.close();
4626                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4627            } catch (IOException e) {
4628                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4629                return;
4630            }
4631
4632            if (app != null) {
4633                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4634                firstPids.add(app.pid);
4635                dumpStackTraces(tracesPath, firstPids, null, null, null);
4636            }
4637
4638            File lastTracesFile = null;
4639            File curTracesFile = null;
4640            for (int i=9; i>=0; i--) {
4641                String name = String.format(Locale.US, "slow%02d.txt", i);
4642                curTracesFile = new File(tracesDir, name);
4643                if (curTracesFile.exists()) {
4644                    if (lastTracesFile != null) {
4645                        curTracesFile.renameTo(lastTracesFile);
4646                    } else {
4647                        curTracesFile.delete();
4648                    }
4649                }
4650                lastTracesFile = curTracesFile;
4651            }
4652            tracesFile.renameTo(curTracesFile);
4653            if (tracesTmp.exists()) {
4654                tracesTmp.renameTo(tracesFile);
4655            }
4656        } finally {
4657            StrictMode.setThreadPolicy(oldPolicy);
4658        }
4659    }
4660
4661    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4662            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4663        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4664        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4665
4666        if (mController != null) {
4667            try {
4668                // 0 == continue, -1 = kill process immediately
4669                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4670                if (res < 0 && app.pid != MY_PID) {
4671                    app.kill("anr", true);
4672                }
4673            } catch (RemoteException e) {
4674                mController = null;
4675                Watchdog.getInstance().setActivityController(null);
4676            }
4677        }
4678
4679        long anrTime = SystemClock.uptimeMillis();
4680        if (MONITOR_CPU_USAGE) {
4681            updateCpuStatsNow();
4682        }
4683
4684        synchronized (this) {
4685            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4686            if (mShuttingDown) {
4687                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4688                return;
4689            } else if (app.notResponding) {
4690                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4691                return;
4692            } else if (app.crashing) {
4693                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4694                return;
4695            }
4696
4697            // In case we come through here for the same app before completing
4698            // this one, mark as anring now so we will bail out.
4699            app.notResponding = true;
4700
4701            // Log the ANR to the event log.
4702            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4703                    app.processName, app.info.flags, annotation);
4704
4705            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4706            firstPids.add(app.pid);
4707
4708            int parentPid = app.pid;
4709            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4710            if (parentPid != app.pid) firstPids.add(parentPid);
4711
4712            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4713
4714            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4715                ProcessRecord r = mLruProcesses.get(i);
4716                if (r != null && r.thread != null) {
4717                    int pid = r.pid;
4718                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4719                        if (r.persistent) {
4720                            firstPids.add(pid);
4721                        } else {
4722                            lastPids.put(pid, Boolean.TRUE);
4723                        }
4724                    }
4725                }
4726            }
4727        }
4728
4729        // Log the ANR to the main log.
4730        StringBuilder info = new StringBuilder();
4731        info.setLength(0);
4732        info.append("ANR in ").append(app.processName);
4733        if (activity != null && activity.shortComponentName != null) {
4734            info.append(" (").append(activity.shortComponentName).append(")");
4735        }
4736        info.append("\n");
4737        info.append("PID: ").append(app.pid).append("\n");
4738        if (annotation != null) {
4739            info.append("Reason: ").append(annotation).append("\n");
4740        }
4741        if (parent != null && parent != activity) {
4742            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4743        }
4744
4745        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4746
4747        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4748                NATIVE_STACKS_OF_INTEREST);
4749
4750        String cpuInfo = null;
4751        if (MONITOR_CPU_USAGE) {
4752            updateCpuStatsNow();
4753            synchronized (mProcessCpuTracker) {
4754                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4755            }
4756            info.append(processCpuTracker.printCurrentLoad());
4757            info.append(cpuInfo);
4758        }
4759
4760        info.append(processCpuTracker.printCurrentState(anrTime));
4761
4762        Slog.e(TAG, info.toString());
4763        if (tracesFile == null) {
4764            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4765            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4766        }
4767
4768        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4769                cpuInfo, tracesFile, null);
4770
4771        if (mController != null) {
4772            try {
4773                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4774                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4775                if (res != 0) {
4776                    if (res < 0 && app.pid != MY_PID) {
4777                        app.kill("anr", true);
4778                    } else {
4779                        synchronized (this) {
4780                            mServices.scheduleServiceTimeoutLocked(app);
4781                        }
4782                    }
4783                    return;
4784                }
4785            } catch (RemoteException e) {
4786                mController = null;
4787                Watchdog.getInstance().setActivityController(null);
4788            }
4789        }
4790
4791        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4792        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4793                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4794
4795        synchronized (this) {
4796            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4797
4798            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4799                app.kill("bg anr", true);
4800                return;
4801            }
4802
4803            // Set the app's notResponding state, and look up the errorReportReceiver
4804            makeAppNotRespondingLocked(app,
4805                    activity != null ? activity.shortComponentName : null,
4806                    annotation != null ? "ANR " + annotation : "ANR",
4807                    info.toString());
4808
4809            // Bring up the infamous App Not Responding dialog
4810            Message msg = Message.obtain();
4811            HashMap<String, Object> map = new HashMap<String, Object>();
4812            msg.what = SHOW_NOT_RESPONDING_MSG;
4813            msg.obj = map;
4814            msg.arg1 = aboveSystem ? 1 : 0;
4815            map.put("app", app);
4816            if (activity != null) {
4817                map.put("activity", activity);
4818            }
4819
4820            mUiHandler.sendMessage(msg);
4821        }
4822    }
4823
4824    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4825        if (!mLaunchWarningShown) {
4826            mLaunchWarningShown = true;
4827            mUiHandler.post(new Runnable() {
4828                @Override
4829                public void run() {
4830                    synchronized (ActivityManagerService.this) {
4831                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4832                        d.show();
4833                        mUiHandler.postDelayed(new Runnable() {
4834                            @Override
4835                            public void run() {
4836                                synchronized (ActivityManagerService.this) {
4837                                    d.dismiss();
4838                                    mLaunchWarningShown = false;
4839                                }
4840                            }
4841                        }, 4000);
4842                    }
4843                }
4844            });
4845        }
4846    }
4847
4848    @Override
4849    public boolean clearApplicationUserData(final String packageName,
4850            final IPackageDataObserver observer, int userId) {
4851        enforceNotIsolatedCaller("clearApplicationUserData");
4852        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
4853            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
4854        }
4855        int uid = Binder.getCallingUid();
4856        int pid = Binder.getCallingPid();
4857        userId = handleIncomingUser(pid, uid,
4858                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4859        long callingId = Binder.clearCallingIdentity();
4860        try {
4861            IPackageManager pm = AppGlobals.getPackageManager();
4862            int pkgUid = -1;
4863            synchronized(this) {
4864                try {
4865                    pkgUid = pm.getPackageUid(packageName, userId);
4866                } catch (RemoteException e) {
4867                }
4868                if (pkgUid == -1) {
4869                    Slog.w(TAG, "Invalid packageName: " + packageName);
4870                    if (observer != null) {
4871                        try {
4872                            observer.onRemoveCompleted(packageName, false);
4873                        } catch (RemoteException e) {
4874                            Slog.i(TAG, "Observer no longer exists.");
4875                        }
4876                    }
4877                    return false;
4878                }
4879                if (uid == pkgUid || checkComponentPermission(
4880                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4881                        pid, uid, -1, true)
4882                        == PackageManager.PERMISSION_GRANTED) {
4883                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4884                } else {
4885                    throw new SecurityException("PID " + pid + " does not have permission "
4886                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4887                                    + " of package " + packageName);
4888                }
4889
4890                // Remove all tasks match the cleared application package and user
4891                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4892                    final TaskRecord tr = mRecentTasks.get(i);
4893                    final String taskPackageName =
4894                            tr.getBaseIntent().getComponent().getPackageName();
4895                    if (tr.userId != userId) continue;
4896                    if (!taskPackageName.equals(packageName)) continue;
4897                    removeTaskByIdLocked(tr.taskId, false);
4898                }
4899            }
4900
4901            try {
4902                // Clear application user data
4903                pm.clearApplicationUserData(packageName, observer, userId);
4904
4905                synchronized(this) {
4906                    // Remove all permissions granted from/to this package
4907                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4908                }
4909
4910                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4911                        Uri.fromParts("package", packageName, null));
4912                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4913                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4914                        null, null, 0, null, null, null, false, false, userId);
4915            } catch (RemoteException e) {
4916            }
4917        } finally {
4918            Binder.restoreCallingIdentity(callingId);
4919        }
4920        return true;
4921    }
4922
4923    @Override
4924    public void killBackgroundProcesses(final String packageName, int userId) {
4925        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4926                != PackageManager.PERMISSION_GRANTED &&
4927                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4928                        != PackageManager.PERMISSION_GRANTED) {
4929            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4930                    + Binder.getCallingPid()
4931                    + ", uid=" + Binder.getCallingUid()
4932                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4933            Slog.w(TAG, msg);
4934            throw new SecurityException(msg);
4935        }
4936
4937        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4938                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4939        long callingId = Binder.clearCallingIdentity();
4940        try {
4941            IPackageManager pm = AppGlobals.getPackageManager();
4942            synchronized(this) {
4943                int appId = -1;
4944                try {
4945                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4946                } catch (RemoteException e) {
4947                }
4948                if (appId == -1) {
4949                    Slog.w(TAG, "Invalid packageName: " + packageName);
4950                    return;
4951                }
4952                killPackageProcessesLocked(packageName, appId, userId,
4953                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4954            }
4955        } finally {
4956            Binder.restoreCallingIdentity(callingId);
4957        }
4958    }
4959
4960    @Override
4961    public void killAllBackgroundProcesses() {
4962        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4963                != PackageManager.PERMISSION_GRANTED) {
4964            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4965                    + Binder.getCallingPid()
4966                    + ", uid=" + Binder.getCallingUid()
4967                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4968            Slog.w(TAG, msg);
4969            throw new SecurityException(msg);
4970        }
4971
4972        long callingId = Binder.clearCallingIdentity();
4973        try {
4974            synchronized(this) {
4975                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4976                final int NP = mProcessNames.getMap().size();
4977                for (int ip=0; ip<NP; ip++) {
4978                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4979                    final int NA = apps.size();
4980                    for (int ia=0; ia<NA; ia++) {
4981                        ProcessRecord app = apps.valueAt(ia);
4982                        if (app.persistent) {
4983                            // we don't kill persistent processes
4984                            continue;
4985                        }
4986                        if (app.removed) {
4987                            procs.add(app);
4988                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4989                            app.removed = true;
4990                            procs.add(app);
4991                        }
4992                    }
4993                }
4994
4995                int N = procs.size();
4996                for (int i=0; i<N; i++) {
4997                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4998                }
4999                mAllowLowerMemLevel = true;
5000                updateOomAdjLocked();
5001                doLowMemReportIfNeededLocked(null);
5002            }
5003        } finally {
5004            Binder.restoreCallingIdentity(callingId);
5005        }
5006    }
5007
5008    @Override
5009    public void forceStopPackage(final String packageName, int userId) {
5010        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5011                != PackageManager.PERMISSION_GRANTED) {
5012            String msg = "Permission Denial: forceStopPackage() from pid="
5013                    + Binder.getCallingPid()
5014                    + ", uid=" + Binder.getCallingUid()
5015                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5016            Slog.w(TAG, msg);
5017            throw new SecurityException(msg);
5018        }
5019        final int callingPid = Binder.getCallingPid();
5020        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5021                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5022        long callingId = Binder.clearCallingIdentity();
5023        try {
5024            IPackageManager pm = AppGlobals.getPackageManager();
5025            synchronized(this) {
5026                int[] users = userId == UserHandle.USER_ALL
5027                        ? getUsersLocked() : new int[] { userId };
5028                for (int user : users) {
5029                    int pkgUid = -1;
5030                    try {
5031                        pkgUid = pm.getPackageUid(packageName, user);
5032                    } catch (RemoteException e) {
5033                    }
5034                    if (pkgUid == -1) {
5035                        Slog.w(TAG, "Invalid packageName: " + packageName);
5036                        continue;
5037                    }
5038                    try {
5039                        pm.setPackageStoppedState(packageName, true, user);
5040                    } catch (RemoteException e) {
5041                    } catch (IllegalArgumentException e) {
5042                        Slog.w(TAG, "Failed trying to unstop package "
5043                                + packageName + ": " + e);
5044                    }
5045                    if (isUserRunningLocked(user, false)) {
5046                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5047                    }
5048                }
5049            }
5050        } finally {
5051            Binder.restoreCallingIdentity(callingId);
5052        }
5053    }
5054
5055    @Override
5056    public void addPackageDependency(String packageName) {
5057        synchronized (this) {
5058            int callingPid = Binder.getCallingPid();
5059            if (callingPid == Process.myPid()) {
5060                //  Yeah, um, no.
5061                return;
5062            }
5063            ProcessRecord proc;
5064            synchronized (mPidsSelfLocked) {
5065                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5066            }
5067            if (proc != null) {
5068                if (proc.pkgDeps == null) {
5069                    proc.pkgDeps = new ArraySet<String>(1);
5070                }
5071                proc.pkgDeps.add(packageName);
5072            }
5073        }
5074    }
5075
5076    /*
5077     * The pkg name and app id have to be specified.
5078     */
5079    @Override
5080    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5081        if (pkg == null) {
5082            return;
5083        }
5084        // Make sure the uid is valid.
5085        if (appid < 0) {
5086            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5087            return;
5088        }
5089        int callerUid = Binder.getCallingUid();
5090        // Only the system server can kill an application
5091        if (callerUid == Process.SYSTEM_UID) {
5092            // Post an aysnc message to kill the application
5093            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5094            msg.arg1 = appid;
5095            msg.arg2 = 0;
5096            Bundle bundle = new Bundle();
5097            bundle.putString("pkg", pkg);
5098            bundle.putString("reason", reason);
5099            msg.obj = bundle;
5100            mHandler.sendMessage(msg);
5101        } else {
5102            throw new SecurityException(callerUid + " cannot kill pkg: " +
5103                    pkg);
5104        }
5105    }
5106
5107    @Override
5108    public void closeSystemDialogs(String reason) {
5109        enforceNotIsolatedCaller("closeSystemDialogs");
5110
5111        final int pid = Binder.getCallingPid();
5112        final int uid = Binder.getCallingUid();
5113        final long origId = Binder.clearCallingIdentity();
5114        try {
5115            synchronized (this) {
5116                // Only allow this from foreground processes, so that background
5117                // applications can't abuse it to prevent system UI from being shown.
5118                if (uid >= Process.FIRST_APPLICATION_UID) {
5119                    ProcessRecord proc;
5120                    synchronized (mPidsSelfLocked) {
5121                        proc = mPidsSelfLocked.get(pid);
5122                    }
5123                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5124                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5125                                + " from background process " + proc);
5126                        return;
5127                    }
5128                }
5129                closeSystemDialogsLocked(reason);
5130            }
5131        } finally {
5132            Binder.restoreCallingIdentity(origId);
5133        }
5134    }
5135
5136    void closeSystemDialogsLocked(String reason) {
5137        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5138        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5139                | Intent.FLAG_RECEIVER_FOREGROUND);
5140        if (reason != null) {
5141            intent.putExtra("reason", reason);
5142        }
5143        mWindowManager.closeSystemDialogs(reason);
5144
5145        mStackSupervisor.closeSystemDialogsLocked();
5146
5147        broadcastIntentLocked(null, null, intent, null,
5148                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5149                Process.SYSTEM_UID, UserHandle.USER_ALL);
5150    }
5151
5152    @Override
5153    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5154        enforceNotIsolatedCaller("getProcessMemoryInfo");
5155        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5156        for (int i=pids.length-1; i>=0; i--) {
5157            ProcessRecord proc;
5158            int oomAdj;
5159            synchronized (this) {
5160                synchronized (mPidsSelfLocked) {
5161                    proc = mPidsSelfLocked.get(pids[i]);
5162                    oomAdj = proc != null ? proc.setAdj : 0;
5163                }
5164            }
5165            infos[i] = new Debug.MemoryInfo();
5166            Debug.getMemoryInfo(pids[i], infos[i]);
5167            if (proc != null) {
5168                synchronized (this) {
5169                    if (proc.thread != null && proc.setAdj == oomAdj) {
5170                        // Record this for posterity if the process has been stable.
5171                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5172                                infos[i].getTotalUss(), false, proc.pkgList);
5173                    }
5174                }
5175            }
5176        }
5177        return infos;
5178    }
5179
5180    @Override
5181    public long[] getProcessPss(int[] pids) {
5182        enforceNotIsolatedCaller("getProcessPss");
5183        long[] pss = new long[pids.length];
5184        for (int i=pids.length-1; i>=0; i--) {
5185            ProcessRecord proc;
5186            int oomAdj;
5187            synchronized (this) {
5188                synchronized (mPidsSelfLocked) {
5189                    proc = mPidsSelfLocked.get(pids[i]);
5190                    oomAdj = proc != null ? proc.setAdj : 0;
5191                }
5192            }
5193            long[] tmpUss = new long[1];
5194            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5195            if (proc != null) {
5196                synchronized (this) {
5197                    if (proc.thread != null && proc.setAdj == oomAdj) {
5198                        // Record this for posterity if the process has been stable.
5199                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5200                    }
5201                }
5202            }
5203        }
5204        return pss;
5205    }
5206
5207    @Override
5208    public void killApplicationProcess(String processName, int uid) {
5209        if (processName == null) {
5210            return;
5211        }
5212
5213        int callerUid = Binder.getCallingUid();
5214        // Only the system server can kill an application
5215        if (callerUid == Process.SYSTEM_UID) {
5216            synchronized (this) {
5217                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5218                if (app != null && app.thread != null) {
5219                    try {
5220                        app.thread.scheduleSuicide();
5221                    } catch (RemoteException e) {
5222                        // If the other end already died, then our work here is done.
5223                    }
5224                } else {
5225                    Slog.w(TAG, "Process/uid not found attempting kill of "
5226                            + processName + " / " + uid);
5227                }
5228            }
5229        } else {
5230            throw new SecurityException(callerUid + " cannot kill app process: " +
5231                    processName);
5232        }
5233    }
5234
5235    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5236        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5237                false, true, false, false, UserHandle.getUserId(uid), reason);
5238        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5239                Uri.fromParts("package", packageName, null));
5240        if (!mProcessesReady) {
5241            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5242                    | Intent.FLAG_RECEIVER_FOREGROUND);
5243        }
5244        intent.putExtra(Intent.EXTRA_UID, uid);
5245        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5246        broadcastIntentLocked(null, null, intent,
5247                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5248                false, false,
5249                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5250    }
5251
5252    private void forceStopUserLocked(int userId, String reason) {
5253        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5254        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5255        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5256                | Intent.FLAG_RECEIVER_FOREGROUND);
5257        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5258        broadcastIntentLocked(null, null, intent,
5259                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5260                false, false,
5261                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5262    }
5263
5264    private final boolean killPackageProcessesLocked(String packageName, int appId,
5265            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5266            boolean doit, boolean evenPersistent, String reason) {
5267        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5268
5269        // Remove all processes this package may have touched: all with the
5270        // same UID (except for the system or root user), and all whose name
5271        // matches the package name.
5272        final int NP = mProcessNames.getMap().size();
5273        for (int ip=0; ip<NP; ip++) {
5274            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5275            final int NA = apps.size();
5276            for (int ia=0; ia<NA; ia++) {
5277                ProcessRecord app = apps.valueAt(ia);
5278                if (app.persistent && !evenPersistent) {
5279                    // we don't kill persistent processes
5280                    continue;
5281                }
5282                if (app.removed) {
5283                    if (doit) {
5284                        procs.add(app);
5285                    }
5286                    continue;
5287                }
5288
5289                // Skip process if it doesn't meet our oom adj requirement.
5290                if (app.setAdj < minOomAdj) {
5291                    continue;
5292                }
5293
5294                // If no package is specified, we call all processes under the
5295                // give user id.
5296                if (packageName == null) {
5297                    if (app.userId != userId) {
5298                        continue;
5299                    }
5300                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5301                        continue;
5302                    }
5303                // Package has been specified, we want to hit all processes
5304                // that match it.  We need to qualify this by the processes
5305                // that are running under the specified app and user ID.
5306                } else {
5307                    final boolean isDep = app.pkgDeps != null
5308                            && app.pkgDeps.contains(packageName);
5309                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5310                        continue;
5311                    }
5312                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5313                        continue;
5314                    }
5315                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5316                        continue;
5317                    }
5318                }
5319
5320                // Process has passed all conditions, kill it!
5321                if (!doit) {
5322                    return true;
5323                }
5324                app.removed = true;
5325                procs.add(app);
5326            }
5327        }
5328
5329        int N = procs.size();
5330        for (int i=0; i<N; i++) {
5331            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5332        }
5333        updateOomAdjLocked();
5334        return N > 0;
5335    }
5336
5337    private final boolean forceStopPackageLocked(String name, int appId,
5338            boolean callerWillRestart, boolean purgeCache, boolean doit,
5339            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5340        int i;
5341        int N;
5342
5343        if (userId == UserHandle.USER_ALL && name == null) {
5344            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5345        }
5346
5347        if (appId < 0 && name != null) {
5348            try {
5349                appId = UserHandle.getAppId(
5350                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5351            } catch (RemoteException e) {
5352            }
5353        }
5354
5355        if (doit) {
5356            if (name != null) {
5357                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5358                        + " user=" + userId + ": " + reason);
5359            } else {
5360                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5361            }
5362
5363            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5364            for (int ip=pmap.size()-1; ip>=0; ip--) {
5365                SparseArray<Long> ba = pmap.valueAt(ip);
5366                for (i=ba.size()-1; i>=0; i--) {
5367                    boolean remove = false;
5368                    final int entUid = ba.keyAt(i);
5369                    if (name != null) {
5370                        if (userId == UserHandle.USER_ALL) {
5371                            if (UserHandle.getAppId(entUid) == appId) {
5372                                remove = true;
5373                            }
5374                        } else {
5375                            if (entUid == UserHandle.getUid(userId, appId)) {
5376                                remove = true;
5377                            }
5378                        }
5379                    } else if (UserHandle.getUserId(entUid) == userId) {
5380                        remove = true;
5381                    }
5382                    if (remove) {
5383                        ba.removeAt(i);
5384                    }
5385                }
5386                if (ba.size() == 0) {
5387                    pmap.removeAt(ip);
5388                }
5389            }
5390        }
5391
5392        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5393                -100, callerWillRestart, true, doit, evenPersistent,
5394                name == null ? ("stop user " + userId) : ("stop " + name));
5395
5396        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5397            if (!doit) {
5398                return true;
5399            }
5400            didSomething = true;
5401        }
5402
5403        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5404            if (!doit) {
5405                return true;
5406            }
5407            didSomething = true;
5408        }
5409
5410        if (name == null) {
5411            // Remove all sticky broadcasts from this user.
5412            mStickyBroadcasts.remove(userId);
5413        }
5414
5415        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5416        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5417                userId, providers)) {
5418            if (!doit) {
5419                return true;
5420            }
5421            didSomething = true;
5422        }
5423        N = providers.size();
5424        for (i=0; i<N; i++) {
5425            removeDyingProviderLocked(null, providers.get(i), true);
5426        }
5427
5428        // Remove transient permissions granted from/to this package/user
5429        removeUriPermissionsForPackageLocked(name, userId, false);
5430
5431        if (name == null || uninstalling) {
5432            // Remove pending intents.  For now we only do this when force
5433            // stopping users, because we have some problems when doing this
5434            // for packages -- app widgets are not currently cleaned up for
5435            // such packages, so they can be left with bad pending intents.
5436            if (mIntentSenderRecords.size() > 0) {
5437                Iterator<WeakReference<PendingIntentRecord>> it
5438                        = mIntentSenderRecords.values().iterator();
5439                while (it.hasNext()) {
5440                    WeakReference<PendingIntentRecord> wpir = it.next();
5441                    if (wpir == null) {
5442                        it.remove();
5443                        continue;
5444                    }
5445                    PendingIntentRecord pir = wpir.get();
5446                    if (pir == null) {
5447                        it.remove();
5448                        continue;
5449                    }
5450                    if (name == null) {
5451                        // Stopping user, remove all objects for the user.
5452                        if (pir.key.userId != userId) {
5453                            // Not the same user, skip it.
5454                            continue;
5455                        }
5456                    } else {
5457                        if (UserHandle.getAppId(pir.uid) != appId) {
5458                            // Different app id, skip it.
5459                            continue;
5460                        }
5461                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5462                            // Different user, skip it.
5463                            continue;
5464                        }
5465                        if (!pir.key.packageName.equals(name)) {
5466                            // Different package, skip it.
5467                            continue;
5468                        }
5469                    }
5470                    if (!doit) {
5471                        return true;
5472                    }
5473                    didSomething = true;
5474                    it.remove();
5475                    pir.canceled = true;
5476                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5477                        pir.key.activity.pendingResults.remove(pir.ref);
5478                    }
5479                }
5480            }
5481        }
5482
5483        if (doit) {
5484            if (purgeCache && name != null) {
5485                AttributeCache ac = AttributeCache.instance();
5486                if (ac != null) {
5487                    ac.removePackage(name);
5488                }
5489            }
5490            if (mBooted) {
5491                mStackSupervisor.resumeTopActivitiesLocked();
5492                mStackSupervisor.scheduleIdleLocked();
5493            }
5494        }
5495
5496        return didSomething;
5497    }
5498
5499    private final boolean removeProcessLocked(ProcessRecord app,
5500            boolean callerWillRestart, boolean allowRestart, String reason) {
5501        final String name = app.processName;
5502        final int uid = app.uid;
5503        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5504            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5505
5506        mProcessNames.remove(name, uid);
5507        mIsolatedProcesses.remove(app.uid);
5508        if (mHeavyWeightProcess == app) {
5509            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5510                    mHeavyWeightProcess.userId, 0));
5511            mHeavyWeightProcess = null;
5512        }
5513        boolean needRestart = false;
5514        if (app.pid > 0 && app.pid != MY_PID) {
5515            int pid = app.pid;
5516            synchronized (mPidsSelfLocked) {
5517                mPidsSelfLocked.remove(pid);
5518                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5519            }
5520            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5521            if (app.isolated) {
5522                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5523            }
5524            boolean willRestart = false;
5525            if (app.persistent && !app.isolated) {
5526                if (!callerWillRestart) {
5527                    willRestart = true;
5528                } else {
5529                    needRestart = true;
5530                }
5531            }
5532            app.kill(reason, true);
5533            handleAppDiedLocked(app, willRestart, allowRestart);
5534            if (willRestart) {
5535                removeLruProcessLocked(app);
5536                addAppLocked(app.info, false, null /* ABI override */);
5537            }
5538        } else {
5539            mRemovedProcesses.add(app);
5540        }
5541
5542        return needRestart;
5543    }
5544
5545    private final void processStartTimedOutLocked(ProcessRecord app) {
5546        final int pid = app.pid;
5547        boolean gone = false;
5548        synchronized (mPidsSelfLocked) {
5549            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5550            if (knownApp != null && knownApp.thread == null) {
5551                mPidsSelfLocked.remove(pid);
5552                gone = true;
5553            }
5554        }
5555
5556        if (gone) {
5557            Slog.w(TAG, "Process " + app + " failed to attach");
5558            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5559                    pid, app.uid, app.processName);
5560            mProcessNames.remove(app.processName, app.uid);
5561            mIsolatedProcesses.remove(app.uid);
5562            if (mHeavyWeightProcess == app) {
5563                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5564                        mHeavyWeightProcess.userId, 0));
5565                mHeavyWeightProcess = null;
5566            }
5567            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5568            if (app.isolated) {
5569                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5570            }
5571            // Take care of any launching providers waiting for this process.
5572            checkAppInLaunchingProvidersLocked(app, true);
5573            // Take care of any services that are waiting for the process.
5574            mServices.processStartTimedOutLocked(app);
5575            app.kill("start timeout", true);
5576            removeLruProcessLocked(app);
5577            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5578                Slog.w(TAG, "Unattached app died before backup, skipping");
5579                try {
5580                    IBackupManager bm = IBackupManager.Stub.asInterface(
5581                            ServiceManager.getService(Context.BACKUP_SERVICE));
5582                    bm.agentDisconnected(app.info.packageName);
5583                } catch (RemoteException e) {
5584                    // Can't happen; the backup manager is local
5585                }
5586            }
5587            if (isPendingBroadcastProcessLocked(pid)) {
5588                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5589                skipPendingBroadcastLocked(pid);
5590            }
5591        } else {
5592            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5593        }
5594    }
5595
5596    private final boolean attachApplicationLocked(IApplicationThread thread,
5597            int pid) {
5598
5599        // Find the application record that is being attached...  either via
5600        // the pid if we are running in multiple processes, or just pull the
5601        // next app record if we are emulating process with anonymous threads.
5602        ProcessRecord app;
5603        if (pid != MY_PID && pid >= 0) {
5604            synchronized (mPidsSelfLocked) {
5605                app = mPidsSelfLocked.get(pid);
5606            }
5607        } else {
5608            app = null;
5609        }
5610
5611        if (app == null) {
5612            Slog.w(TAG, "No pending application record for pid " + pid
5613                    + " (IApplicationThread " + thread + "); dropping process");
5614            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5615            if (pid > 0 && pid != MY_PID) {
5616                Process.killProcessQuiet(pid);
5617                //TODO: Process.killProcessGroup(app.info.uid, pid);
5618            } else {
5619                try {
5620                    thread.scheduleExit();
5621                } catch (Exception e) {
5622                    // Ignore exceptions.
5623                }
5624            }
5625            return false;
5626        }
5627
5628        // If this application record is still attached to a previous
5629        // process, clean it up now.
5630        if (app.thread != null) {
5631            handleAppDiedLocked(app, true, true);
5632        }
5633
5634        // Tell the process all about itself.
5635
5636        if (DEBUG_ALL) Slog.v(
5637                TAG, "Binding process pid " + pid + " to record " + app);
5638
5639        final String processName = app.processName;
5640        try {
5641            AppDeathRecipient adr = new AppDeathRecipient(
5642                    app, pid, thread);
5643            thread.asBinder().linkToDeath(adr, 0);
5644            app.deathRecipient = adr;
5645        } catch (RemoteException e) {
5646            app.resetPackageList(mProcessStats);
5647            startProcessLocked(app, "link fail", processName);
5648            return false;
5649        }
5650
5651        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5652
5653        app.makeActive(thread, mProcessStats);
5654        app.curAdj = app.setAdj = -100;
5655        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5656        app.forcingToForeground = null;
5657        updateProcessForegroundLocked(app, false, false);
5658        app.hasShownUi = false;
5659        app.debugging = false;
5660        app.cached = false;
5661        app.killedByAm = false;
5662
5663        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5664
5665        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5666        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5667
5668        if (!normalMode) {
5669            Slog.i(TAG, "Launching preboot mode app: " + app);
5670        }
5671
5672        if (DEBUG_ALL) Slog.v(
5673            TAG, "New app record " + app
5674            + " thread=" + thread.asBinder() + " pid=" + pid);
5675        try {
5676            int testMode = IApplicationThread.DEBUG_OFF;
5677            if (mDebugApp != null && mDebugApp.equals(processName)) {
5678                testMode = mWaitForDebugger
5679                    ? IApplicationThread.DEBUG_WAIT
5680                    : IApplicationThread.DEBUG_ON;
5681                app.debugging = true;
5682                if (mDebugTransient) {
5683                    mDebugApp = mOrigDebugApp;
5684                    mWaitForDebugger = mOrigWaitForDebugger;
5685                }
5686            }
5687            String profileFile = app.instrumentationProfileFile;
5688            ParcelFileDescriptor profileFd = null;
5689            int samplingInterval = 0;
5690            boolean profileAutoStop = false;
5691            if (mProfileApp != null && mProfileApp.equals(processName)) {
5692                mProfileProc = app;
5693                profileFile = mProfileFile;
5694                profileFd = mProfileFd;
5695                samplingInterval = mSamplingInterval;
5696                profileAutoStop = mAutoStopProfiler;
5697            }
5698            boolean enableOpenGlTrace = false;
5699            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5700                enableOpenGlTrace = true;
5701                mOpenGlTraceApp = null;
5702            }
5703
5704            // If the app is being launched for restore or full backup, set it up specially
5705            boolean isRestrictedBackupMode = false;
5706            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5707                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5708                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5709                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5710            }
5711
5712            ensurePackageDexOpt(app.instrumentationInfo != null
5713                    ? app.instrumentationInfo.packageName
5714                    : app.info.packageName);
5715            if (app.instrumentationClass != null) {
5716                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5717            }
5718            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
5719                    + processName + " with config " + mConfiguration);
5720            ApplicationInfo appInfo = app.instrumentationInfo != null
5721                    ? app.instrumentationInfo : app.info;
5722            app.compat = compatibilityInfoForPackageLocked(appInfo);
5723            if (profileFd != null) {
5724                profileFd = profileFd.dup();
5725            }
5726            ProfilerInfo profilerInfo = profileFile == null ? null
5727                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5728            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5729                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5730                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5731                    isRestrictedBackupMode || !normalMode, app.persistent,
5732                    new Configuration(mConfiguration), app.compat,
5733                    getCommonServicesLocked(app.isolated),
5734                    mCoreSettingsObserver.getCoreSettingsLocked());
5735            updateLruProcessLocked(app, false, null);
5736            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5737        } catch (Exception e) {
5738            // todo: Yikes!  What should we do?  For now we will try to
5739            // start another process, but that could easily get us in
5740            // an infinite loop of restarting processes...
5741            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5742
5743            app.resetPackageList(mProcessStats);
5744            app.unlinkDeathRecipient();
5745            startProcessLocked(app, "bind fail", processName);
5746            return false;
5747        }
5748
5749        // Remove this record from the list of starting applications.
5750        mPersistentStartingProcesses.remove(app);
5751        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
5752                "Attach application locked removing on hold: " + app);
5753        mProcessesOnHold.remove(app);
5754
5755        boolean badApp = false;
5756        boolean didSomething = false;
5757
5758        // See if the top visible activity is waiting to run in this process...
5759        if (normalMode) {
5760            try {
5761                if (mStackSupervisor.attachApplicationLocked(app)) {
5762                    didSomething = true;
5763                }
5764            } catch (Exception e) {
5765                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5766                badApp = true;
5767            }
5768        }
5769
5770        // Find any services that should be running in this process...
5771        if (!badApp) {
5772            try {
5773                didSomething |= mServices.attachApplicationLocked(app, processName);
5774            } catch (Exception e) {
5775                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5776                badApp = true;
5777            }
5778        }
5779
5780        // Check if a next-broadcast receiver is in this process...
5781        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5782            try {
5783                didSomething |= sendPendingBroadcastsLocked(app);
5784            } catch (Exception e) {
5785                // If the app died trying to launch the receiver we declare it 'bad'
5786                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5787                badApp = true;
5788            }
5789        }
5790
5791        // Check whether the next backup agent is in this process...
5792        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5793            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
5794                    "New app is backup target, launching agent for " + app);
5795            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5796            try {
5797                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5798                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5799                        mBackupTarget.backupMode);
5800            } catch (Exception e) {
5801                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5802                badApp = true;
5803            }
5804        }
5805
5806        if (badApp) {
5807            app.kill("error during init", true);
5808            handleAppDiedLocked(app, false, true);
5809            return false;
5810        }
5811
5812        if (!didSomething) {
5813            updateOomAdjLocked();
5814        }
5815
5816        return true;
5817    }
5818
5819    @Override
5820    public final void attachApplication(IApplicationThread thread) {
5821        synchronized (this) {
5822            int callingPid = Binder.getCallingPid();
5823            final long origId = Binder.clearCallingIdentity();
5824            attachApplicationLocked(thread, callingPid);
5825            Binder.restoreCallingIdentity(origId);
5826        }
5827    }
5828
5829    @Override
5830    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5831        final long origId = Binder.clearCallingIdentity();
5832        synchronized (this) {
5833            ActivityStack stack = ActivityRecord.getStackLocked(token);
5834            if (stack != null) {
5835                ActivityRecord r =
5836                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5837                if (stopProfiling) {
5838                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5839                        try {
5840                            mProfileFd.close();
5841                        } catch (IOException e) {
5842                        }
5843                        clearProfilerLocked();
5844                    }
5845                }
5846            }
5847        }
5848        Binder.restoreCallingIdentity(origId);
5849    }
5850
5851    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5852        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5853                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5854    }
5855
5856    void enableScreenAfterBoot() {
5857        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5858                SystemClock.uptimeMillis());
5859        mWindowManager.enableScreenAfterBoot();
5860
5861        synchronized (this) {
5862            updateEventDispatchingLocked();
5863        }
5864    }
5865
5866    @Override
5867    public void showBootMessage(final CharSequence msg, final boolean always) {
5868        if (Binder.getCallingUid() != Process.myUid()) {
5869            // These days only the core system can call this, so apps can't get in
5870            // the way of what we show about running them.
5871        }
5872        mWindowManager.showBootMessage(msg, always);
5873    }
5874
5875    @Override
5876    public void keyguardWaitingForActivityDrawn() {
5877        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5878        final long token = Binder.clearCallingIdentity();
5879        try {
5880            synchronized (this) {
5881                if (DEBUG_LOCKSCREEN) logLockScreen("");
5882                mWindowManager.keyguardWaitingForActivityDrawn();
5883                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5884                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5885                    updateSleepIfNeededLocked();
5886                }
5887            }
5888        } finally {
5889            Binder.restoreCallingIdentity(token);
5890        }
5891    }
5892
5893    final void finishBooting() {
5894        synchronized (this) {
5895            if (!mBootAnimationComplete) {
5896                mCallFinishBooting = true;
5897                return;
5898            }
5899            mCallFinishBooting = false;
5900        }
5901
5902        ArraySet<String> completedIsas = new ArraySet<String>();
5903        for (String abi : Build.SUPPORTED_ABIS) {
5904            Process.establishZygoteConnectionForAbi(abi);
5905            final String instructionSet = VMRuntime.getInstructionSet(abi);
5906            if (!completedIsas.contains(instructionSet)) {
5907                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5908                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5909                }
5910                completedIsas.add(instructionSet);
5911            }
5912        }
5913
5914        IntentFilter pkgFilter = new IntentFilter();
5915        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5916        pkgFilter.addDataScheme("package");
5917        mContext.registerReceiver(new BroadcastReceiver() {
5918            @Override
5919            public void onReceive(Context context, Intent intent) {
5920                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5921                if (pkgs != null) {
5922                    for (String pkg : pkgs) {
5923                        synchronized (ActivityManagerService.this) {
5924                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5925                                    0, "query restart")) {
5926                                setResultCode(Activity.RESULT_OK);
5927                                return;
5928                            }
5929                        }
5930                    }
5931                }
5932            }
5933        }, pkgFilter);
5934
5935        IntentFilter dumpheapFilter = new IntentFilter();
5936        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
5937        mContext.registerReceiver(new BroadcastReceiver() {
5938            @Override
5939            public void onReceive(Context context, Intent intent) {
5940                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
5941                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
5942                } else {
5943                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
5944                }
5945            }
5946        }, dumpheapFilter);
5947
5948        // Let system services know.
5949        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5950
5951        synchronized (this) {
5952            // Ensure that any processes we had put on hold are now started
5953            // up.
5954            final int NP = mProcessesOnHold.size();
5955            if (NP > 0) {
5956                ArrayList<ProcessRecord> procs =
5957                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5958                for (int ip=0; ip<NP; ip++) {
5959                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
5960                            + procs.get(ip));
5961                    startProcessLocked(procs.get(ip), "on-hold", null);
5962                }
5963            }
5964
5965            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5966                // Start looking for apps that are abusing wake locks.
5967                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5968                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5969                // Tell anyone interested that we are done booting!
5970                SystemProperties.set("sys.boot_completed", "1");
5971
5972                // And trigger dev.bootcomplete if we are not showing encryption progress
5973                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5974                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5975                    SystemProperties.set("dev.bootcomplete", "1");
5976                }
5977                for (int i=0; i<mStartedUsers.size(); i++) {
5978                    UserStartedState uss = mStartedUsers.valueAt(i);
5979                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5980                        uss.mState = UserStartedState.STATE_RUNNING;
5981                        final int userId = mStartedUsers.keyAt(i);
5982                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5983                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5984                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5985                        broadcastIntentLocked(null, null, intent, null,
5986                                new IIntentReceiver.Stub() {
5987                                    @Override
5988                                    public void performReceive(Intent intent, int resultCode,
5989                                            String data, Bundle extras, boolean ordered,
5990                                            boolean sticky, int sendingUser) {
5991                                        synchronized (ActivityManagerService.this) {
5992                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5993                                                    true, false);
5994                                        }
5995                                    }
5996                                },
5997                                0, null, null,
5998                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5999                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6000                                userId);
6001                    }
6002                }
6003                scheduleStartProfilesLocked();
6004            }
6005        }
6006    }
6007
6008    @Override
6009    public void bootAnimationComplete() {
6010        final boolean callFinishBooting;
6011        synchronized (this) {
6012            callFinishBooting = mCallFinishBooting;
6013            mBootAnimationComplete = true;
6014        }
6015        if (callFinishBooting) {
6016            finishBooting();
6017        }
6018    }
6019
6020    @Override
6021    public void systemBackupRestored() {
6022        synchronized (this) {
6023            if (mSystemReady) {
6024                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6025            } else {
6026                Slog.w(TAG, "System backup restored before system is ready");
6027            }
6028        }
6029    }
6030
6031    final void ensureBootCompleted() {
6032        boolean booting;
6033        boolean enableScreen;
6034        synchronized (this) {
6035            booting = mBooting;
6036            mBooting = false;
6037            enableScreen = !mBooted;
6038            mBooted = true;
6039        }
6040
6041        if (booting) {
6042            finishBooting();
6043        }
6044
6045        if (enableScreen) {
6046            enableScreenAfterBoot();
6047        }
6048    }
6049
6050    @Override
6051    public final void activityResumed(IBinder token) {
6052        final long origId = Binder.clearCallingIdentity();
6053        synchronized(this) {
6054            ActivityStack stack = ActivityRecord.getStackLocked(token);
6055            if (stack != null) {
6056                ActivityRecord.activityResumedLocked(token);
6057            }
6058        }
6059        Binder.restoreCallingIdentity(origId);
6060    }
6061
6062    @Override
6063    public final void activityPaused(IBinder token) {
6064        final long origId = Binder.clearCallingIdentity();
6065        synchronized(this) {
6066            ActivityStack stack = ActivityRecord.getStackLocked(token);
6067            if (stack != null) {
6068                stack.activityPausedLocked(token, false);
6069            }
6070        }
6071        Binder.restoreCallingIdentity(origId);
6072    }
6073
6074    @Override
6075    public final void activityStopped(IBinder token, Bundle icicle,
6076            PersistableBundle persistentState, CharSequence description) {
6077        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6078
6079        // Refuse possible leaked file descriptors
6080        if (icicle != null && icicle.hasFileDescriptors()) {
6081            throw new IllegalArgumentException("File descriptors passed in Bundle");
6082        }
6083
6084        final long origId = Binder.clearCallingIdentity();
6085
6086        synchronized (this) {
6087            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6088            if (r != null) {
6089                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6090            }
6091        }
6092
6093        trimApplications();
6094
6095        Binder.restoreCallingIdentity(origId);
6096    }
6097
6098    @Override
6099    public final void activityDestroyed(IBinder token) {
6100        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6101        synchronized (this) {
6102            ActivityStack stack = ActivityRecord.getStackLocked(token);
6103            if (stack != null) {
6104                stack.activityDestroyedLocked(token, "activityDestroyed");
6105            }
6106        }
6107    }
6108
6109    @Override
6110    public final void backgroundResourcesReleased(IBinder token) {
6111        final long origId = Binder.clearCallingIdentity();
6112        try {
6113            synchronized (this) {
6114                ActivityStack stack = ActivityRecord.getStackLocked(token);
6115                if (stack != null) {
6116                    stack.backgroundResourcesReleased();
6117                }
6118            }
6119        } finally {
6120            Binder.restoreCallingIdentity(origId);
6121        }
6122    }
6123
6124    @Override
6125    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6126        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6127    }
6128
6129    @Override
6130    public final void notifyEnterAnimationComplete(IBinder token) {
6131        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6132    }
6133
6134    @Override
6135    public String getCallingPackage(IBinder token) {
6136        synchronized (this) {
6137            ActivityRecord r = getCallingRecordLocked(token);
6138            return r != null ? r.info.packageName : null;
6139        }
6140    }
6141
6142    @Override
6143    public ComponentName getCallingActivity(IBinder token) {
6144        synchronized (this) {
6145            ActivityRecord r = getCallingRecordLocked(token);
6146            return r != null ? r.intent.getComponent() : null;
6147        }
6148    }
6149
6150    private ActivityRecord getCallingRecordLocked(IBinder token) {
6151        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6152        if (r == null) {
6153            return null;
6154        }
6155        return r.resultTo;
6156    }
6157
6158    @Override
6159    public ComponentName getActivityClassForToken(IBinder token) {
6160        synchronized(this) {
6161            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6162            if (r == null) {
6163                return null;
6164            }
6165            return r.intent.getComponent();
6166        }
6167    }
6168
6169    @Override
6170    public String getPackageForToken(IBinder token) {
6171        synchronized(this) {
6172            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6173            if (r == null) {
6174                return null;
6175            }
6176            return r.packageName;
6177        }
6178    }
6179
6180    @Override
6181    public IIntentSender getIntentSender(int type,
6182            String packageName, IBinder token, String resultWho,
6183            int requestCode, Intent[] intents, String[] resolvedTypes,
6184            int flags, Bundle options, int userId) {
6185        enforceNotIsolatedCaller("getIntentSender");
6186        // Refuse possible leaked file descriptors
6187        if (intents != null) {
6188            if (intents.length < 1) {
6189                throw new IllegalArgumentException("Intents array length must be >= 1");
6190            }
6191            for (int i=0; i<intents.length; i++) {
6192                Intent intent = intents[i];
6193                if (intent != null) {
6194                    if (intent.hasFileDescriptors()) {
6195                        throw new IllegalArgumentException("File descriptors passed in Intent");
6196                    }
6197                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6198                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6199                        throw new IllegalArgumentException(
6200                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6201                    }
6202                    intents[i] = new Intent(intent);
6203                }
6204            }
6205            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6206                throw new IllegalArgumentException(
6207                        "Intent array length does not match resolvedTypes length");
6208            }
6209        }
6210        if (options != null) {
6211            if (options.hasFileDescriptors()) {
6212                throw new IllegalArgumentException("File descriptors passed in options");
6213            }
6214        }
6215
6216        synchronized(this) {
6217            int callingUid = Binder.getCallingUid();
6218            int origUserId = userId;
6219            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6220                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6221                    ALLOW_NON_FULL, "getIntentSender", null);
6222            if (origUserId == UserHandle.USER_CURRENT) {
6223                // We don't want to evaluate this until the pending intent is
6224                // actually executed.  However, we do want to always do the
6225                // security checking for it above.
6226                userId = UserHandle.USER_CURRENT;
6227            }
6228            try {
6229                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6230                    int uid = AppGlobals.getPackageManager()
6231                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6232                    if (!UserHandle.isSameApp(callingUid, uid)) {
6233                        String msg = "Permission Denial: getIntentSender() from pid="
6234                            + Binder.getCallingPid()
6235                            + ", uid=" + Binder.getCallingUid()
6236                            + ", (need uid=" + uid + ")"
6237                            + " is not allowed to send as package " + packageName;
6238                        Slog.w(TAG, msg);
6239                        throw new SecurityException(msg);
6240                    }
6241                }
6242
6243                return getIntentSenderLocked(type, packageName, callingUid, userId,
6244                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6245
6246            } catch (RemoteException e) {
6247                throw new SecurityException(e);
6248            }
6249        }
6250    }
6251
6252    IIntentSender getIntentSenderLocked(int type, String packageName,
6253            int callingUid, int userId, IBinder token, String resultWho,
6254            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6255            Bundle options) {
6256        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6257        ActivityRecord activity = null;
6258        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6259            activity = ActivityRecord.isInStackLocked(token);
6260            if (activity == null) {
6261                return null;
6262            }
6263            if (activity.finishing) {
6264                return null;
6265            }
6266        }
6267
6268        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6269        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6270        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6271        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6272                |PendingIntent.FLAG_UPDATE_CURRENT);
6273
6274        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6275                type, packageName, activity, resultWho,
6276                requestCode, intents, resolvedTypes, flags, options, userId);
6277        WeakReference<PendingIntentRecord> ref;
6278        ref = mIntentSenderRecords.get(key);
6279        PendingIntentRecord rec = ref != null ? ref.get() : null;
6280        if (rec != null) {
6281            if (!cancelCurrent) {
6282                if (updateCurrent) {
6283                    if (rec.key.requestIntent != null) {
6284                        rec.key.requestIntent.replaceExtras(intents != null ?
6285                                intents[intents.length - 1] : null);
6286                    }
6287                    if (intents != null) {
6288                        intents[intents.length-1] = rec.key.requestIntent;
6289                        rec.key.allIntents = intents;
6290                        rec.key.allResolvedTypes = resolvedTypes;
6291                    } else {
6292                        rec.key.allIntents = null;
6293                        rec.key.allResolvedTypes = null;
6294                    }
6295                }
6296                return rec;
6297            }
6298            rec.canceled = true;
6299            mIntentSenderRecords.remove(key);
6300        }
6301        if (noCreate) {
6302            return rec;
6303        }
6304        rec = new PendingIntentRecord(this, key, callingUid);
6305        mIntentSenderRecords.put(key, rec.ref);
6306        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6307            if (activity.pendingResults == null) {
6308                activity.pendingResults
6309                        = new HashSet<WeakReference<PendingIntentRecord>>();
6310            }
6311            activity.pendingResults.add(rec.ref);
6312        }
6313        return rec;
6314    }
6315
6316    @Override
6317    public void cancelIntentSender(IIntentSender sender) {
6318        if (!(sender instanceof PendingIntentRecord)) {
6319            return;
6320        }
6321        synchronized(this) {
6322            PendingIntentRecord rec = (PendingIntentRecord)sender;
6323            try {
6324                int uid = AppGlobals.getPackageManager()
6325                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6326                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6327                    String msg = "Permission Denial: cancelIntentSender() from pid="
6328                        + Binder.getCallingPid()
6329                        + ", uid=" + Binder.getCallingUid()
6330                        + " is not allowed to cancel packges "
6331                        + rec.key.packageName;
6332                    Slog.w(TAG, msg);
6333                    throw new SecurityException(msg);
6334                }
6335            } catch (RemoteException e) {
6336                throw new SecurityException(e);
6337            }
6338            cancelIntentSenderLocked(rec, true);
6339        }
6340    }
6341
6342    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6343        rec.canceled = true;
6344        mIntentSenderRecords.remove(rec.key);
6345        if (cleanActivity && rec.key.activity != null) {
6346            rec.key.activity.pendingResults.remove(rec.ref);
6347        }
6348    }
6349
6350    @Override
6351    public String getPackageForIntentSender(IIntentSender pendingResult) {
6352        if (!(pendingResult instanceof PendingIntentRecord)) {
6353            return null;
6354        }
6355        try {
6356            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6357            return res.key.packageName;
6358        } catch (ClassCastException e) {
6359        }
6360        return null;
6361    }
6362
6363    @Override
6364    public int getUidForIntentSender(IIntentSender sender) {
6365        if (sender instanceof PendingIntentRecord) {
6366            try {
6367                PendingIntentRecord res = (PendingIntentRecord)sender;
6368                return res.uid;
6369            } catch (ClassCastException e) {
6370            }
6371        }
6372        return -1;
6373    }
6374
6375    @Override
6376    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6377        if (!(pendingResult instanceof PendingIntentRecord)) {
6378            return false;
6379        }
6380        try {
6381            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6382            if (res.key.allIntents == null) {
6383                return false;
6384            }
6385            for (int i=0; i<res.key.allIntents.length; i++) {
6386                Intent intent = res.key.allIntents[i];
6387                if (intent.getPackage() != null && intent.getComponent() != null) {
6388                    return false;
6389                }
6390            }
6391            return true;
6392        } catch (ClassCastException e) {
6393        }
6394        return false;
6395    }
6396
6397    @Override
6398    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6399        if (!(pendingResult instanceof PendingIntentRecord)) {
6400            return false;
6401        }
6402        try {
6403            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6404            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6405                return true;
6406            }
6407            return false;
6408        } catch (ClassCastException e) {
6409        }
6410        return false;
6411    }
6412
6413    @Override
6414    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6415        if (!(pendingResult instanceof PendingIntentRecord)) {
6416            return null;
6417        }
6418        try {
6419            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6420            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6421        } catch (ClassCastException e) {
6422        }
6423        return null;
6424    }
6425
6426    @Override
6427    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6428        if (!(pendingResult instanceof PendingIntentRecord)) {
6429            return null;
6430        }
6431        try {
6432            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6433            synchronized (this) {
6434                return getTagForIntentSenderLocked(res, prefix);
6435            }
6436        } catch (ClassCastException e) {
6437        }
6438        return null;
6439    }
6440
6441    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6442        final Intent intent = res.key.requestIntent;
6443        if (intent != null) {
6444            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6445                    || res.lastTagPrefix.equals(prefix))) {
6446                return res.lastTag;
6447            }
6448            res.lastTagPrefix = prefix;
6449            final StringBuilder sb = new StringBuilder(128);
6450            if (prefix != null) {
6451                sb.append(prefix);
6452            }
6453            if (intent.getAction() != null) {
6454                sb.append(intent.getAction());
6455            } else if (intent.getComponent() != null) {
6456                intent.getComponent().appendShortString(sb);
6457            } else {
6458                sb.append("?");
6459            }
6460            return res.lastTag = sb.toString();
6461        }
6462        return null;
6463    }
6464
6465    @Override
6466    public void setProcessLimit(int max) {
6467        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6468                "setProcessLimit()");
6469        synchronized (this) {
6470            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6471            mProcessLimitOverride = max;
6472        }
6473        trimApplications();
6474    }
6475
6476    @Override
6477    public int getProcessLimit() {
6478        synchronized (this) {
6479            return mProcessLimitOverride;
6480        }
6481    }
6482
6483    void foregroundTokenDied(ForegroundToken token) {
6484        synchronized (ActivityManagerService.this) {
6485            synchronized (mPidsSelfLocked) {
6486                ForegroundToken cur
6487                    = mForegroundProcesses.get(token.pid);
6488                if (cur != token) {
6489                    return;
6490                }
6491                mForegroundProcesses.remove(token.pid);
6492                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6493                if (pr == null) {
6494                    return;
6495                }
6496                pr.forcingToForeground = null;
6497                updateProcessForegroundLocked(pr, false, false);
6498            }
6499            updateOomAdjLocked();
6500        }
6501    }
6502
6503    @Override
6504    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6505        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6506                "setProcessForeground()");
6507        synchronized(this) {
6508            boolean changed = false;
6509
6510            synchronized (mPidsSelfLocked) {
6511                ProcessRecord pr = mPidsSelfLocked.get(pid);
6512                if (pr == null && isForeground) {
6513                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6514                    return;
6515                }
6516                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6517                if (oldToken != null) {
6518                    oldToken.token.unlinkToDeath(oldToken, 0);
6519                    mForegroundProcesses.remove(pid);
6520                    if (pr != null) {
6521                        pr.forcingToForeground = null;
6522                    }
6523                    changed = true;
6524                }
6525                if (isForeground && token != null) {
6526                    ForegroundToken newToken = new ForegroundToken() {
6527                        @Override
6528                        public void binderDied() {
6529                            foregroundTokenDied(this);
6530                        }
6531                    };
6532                    newToken.pid = pid;
6533                    newToken.token = token;
6534                    try {
6535                        token.linkToDeath(newToken, 0);
6536                        mForegroundProcesses.put(pid, newToken);
6537                        pr.forcingToForeground = token;
6538                        changed = true;
6539                    } catch (RemoteException e) {
6540                        // If the process died while doing this, we will later
6541                        // do the cleanup with the process death link.
6542                    }
6543                }
6544            }
6545
6546            if (changed) {
6547                updateOomAdjLocked();
6548            }
6549        }
6550    }
6551
6552    // =========================================================
6553    // PROCESS INFO
6554    // =========================================================
6555
6556    static class ProcessInfoService extends IProcessInfoService.Stub {
6557        final ActivityManagerService mActivityManagerService;
6558        ProcessInfoService(ActivityManagerService activityManagerService) {
6559            mActivityManagerService = activityManagerService;
6560        }
6561
6562        @Override
6563        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6564            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6565        }
6566    }
6567
6568    /**
6569     * For each PID in the given input array, write the current process state
6570     * for that process into the output array, or -1 to indicate that no
6571     * process with the given PID exists.
6572     */
6573    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6574        if (pids == null) {
6575            throw new NullPointerException("pids");
6576        } else if (states == null) {
6577            throw new NullPointerException("states");
6578        } else if (pids.length != states.length) {
6579            throw new IllegalArgumentException("input and output arrays have different lengths!");
6580        }
6581
6582        synchronized (mPidsSelfLocked) {
6583            for (int i = 0; i < pids.length; i++) {
6584                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6585                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6586                        pr.curProcState;
6587            }
6588        }
6589    }
6590
6591    // =========================================================
6592    // PERMISSIONS
6593    // =========================================================
6594
6595    static class PermissionController extends IPermissionController.Stub {
6596        ActivityManagerService mActivityManagerService;
6597        PermissionController(ActivityManagerService activityManagerService) {
6598            mActivityManagerService = activityManagerService;
6599        }
6600
6601        @Override
6602        public boolean checkPermission(String permission, int pid, int uid) {
6603            return mActivityManagerService.checkPermission(permission, pid,
6604                    uid) == PackageManager.PERMISSION_GRANTED;
6605        }
6606
6607        @Override
6608        public String[] getPackagesForUid(int uid) {
6609            return mActivityManagerService.mContext.getPackageManager()
6610                    .getPackagesForUid(uid);
6611        }
6612    }
6613
6614    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6615        @Override
6616        public int checkComponentPermission(String permission, int pid, int uid,
6617                int owningUid, boolean exported) {
6618            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6619                    owningUid, exported);
6620        }
6621
6622        @Override
6623        public Object getAMSLock() {
6624            return ActivityManagerService.this;
6625        }
6626    }
6627
6628    /**
6629     * This can be called with or without the global lock held.
6630     */
6631    int checkComponentPermission(String permission, int pid, int uid,
6632            int owningUid, boolean exported) {
6633        if (pid == MY_PID) {
6634            return PackageManager.PERMISSION_GRANTED;
6635        }
6636        return ActivityManager.checkComponentPermission(permission, uid,
6637                owningUid, exported);
6638    }
6639
6640    /**
6641     * As the only public entry point for permissions checking, this method
6642     * can enforce the semantic that requesting a check on a null global
6643     * permission is automatically denied.  (Internally a null permission
6644     * string is used when calling {@link #checkComponentPermission} in cases
6645     * when only uid-based security is needed.)
6646     *
6647     * This can be called with or without the global lock held.
6648     */
6649    @Override
6650    public int checkPermission(String permission, int pid, int uid) {
6651        if (permission == null) {
6652            return PackageManager.PERMISSION_DENIED;
6653        }
6654        return checkComponentPermission(permission, pid, uid, -1, true);
6655    }
6656
6657    @Override
6658    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6659        if (permission == null) {
6660            return PackageManager.PERMISSION_DENIED;
6661        }
6662
6663        // We might be performing an operation on behalf of an indirect binder
6664        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6665        // client identity accordingly before proceeding.
6666        Identity tlsIdentity = sCallerIdentity.get();
6667        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6668            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6669                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6670            uid = tlsIdentity.uid;
6671            pid = tlsIdentity.pid;
6672        }
6673
6674        return checkComponentPermission(permission, pid, uid, -1, true);
6675    }
6676
6677    /**
6678     * Binder IPC calls go through the public entry point.
6679     * This can be called with or without the global lock held.
6680     */
6681    int checkCallingPermission(String permission) {
6682        return checkPermission(permission,
6683                Binder.getCallingPid(),
6684                UserHandle.getAppId(Binder.getCallingUid()));
6685    }
6686
6687    /**
6688     * This can be called with or without the global lock held.
6689     */
6690    void enforceCallingPermission(String permission, String func) {
6691        if (checkCallingPermission(permission)
6692                == PackageManager.PERMISSION_GRANTED) {
6693            return;
6694        }
6695
6696        String msg = "Permission Denial: " + func + " from pid="
6697                + Binder.getCallingPid()
6698                + ", uid=" + Binder.getCallingUid()
6699                + " requires " + permission;
6700        Slog.w(TAG, msg);
6701        throw new SecurityException(msg);
6702    }
6703
6704    /**
6705     * Determine if UID is holding permissions required to access {@link Uri} in
6706     * the given {@link ProviderInfo}. Final permission checking is always done
6707     * in {@link ContentProvider}.
6708     */
6709    private final boolean checkHoldingPermissionsLocked(
6710            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6711        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6712                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6713        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6714            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6715                    != PERMISSION_GRANTED) {
6716                return false;
6717            }
6718        }
6719        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6720    }
6721
6722    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6723            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6724        if (pi.applicationInfo.uid == uid) {
6725            return true;
6726        } else if (!pi.exported) {
6727            return false;
6728        }
6729
6730        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6731        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6732        try {
6733            // check if target holds top-level <provider> permissions
6734            if (!readMet && pi.readPermission != null && considerUidPermissions
6735                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6736                readMet = true;
6737            }
6738            if (!writeMet && pi.writePermission != null && considerUidPermissions
6739                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6740                writeMet = true;
6741            }
6742
6743            // track if unprotected read/write is allowed; any denied
6744            // <path-permission> below removes this ability
6745            boolean allowDefaultRead = pi.readPermission == null;
6746            boolean allowDefaultWrite = pi.writePermission == null;
6747
6748            // check if target holds any <path-permission> that match uri
6749            final PathPermission[] pps = pi.pathPermissions;
6750            if (pps != null) {
6751                final String path = grantUri.uri.getPath();
6752                int i = pps.length;
6753                while (i > 0 && (!readMet || !writeMet)) {
6754                    i--;
6755                    PathPermission pp = pps[i];
6756                    if (pp.match(path)) {
6757                        if (!readMet) {
6758                            final String pprperm = pp.getReadPermission();
6759                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6760                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
6761                                    + ": match=" + pp.match(path)
6762                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6763                            if (pprperm != null) {
6764                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6765                                        == PERMISSION_GRANTED) {
6766                                    readMet = true;
6767                                } else {
6768                                    allowDefaultRead = false;
6769                                }
6770                            }
6771                        }
6772                        if (!writeMet) {
6773                            final String ppwperm = pp.getWritePermission();
6774                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6775                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
6776                                    + ": match=" + pp.match(path)
6777                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6778                            if (ppwperm != null) {
6779                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6780                                        == PERMISSION_GRANTED) {
6781                                    writeMet = true;
6782                                } else {
6783                                    allowDefaultWrite = false;
6784                                }
6785                            }
6786                        }
6787                    }
6788                }
6789            }
6790
6791            // grant unprotected <provider> read/write, if not blocked by
6792            // <path-permission> above
6793            if (allowDefaultRead) readMet = true;
6794            if (allowDefaultWrite) writeMet = true;
6795
6796        } catch (RemoteException e) {
6797            return false;
6798        }
6799
6800        return readMet && writeMet;
6801    }
6802
6803    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6804        ProviderInfo pi = null;
6805        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6806        if (cpr != null) {
6807            pi = cpr.info;
6808        } else {
6809            try {
6810                pi = AppGlobals.getPackageManager().resolveContentProvider(
6811                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6812            } catch (RemoteException ex) {
6813            }
6814        }
6815        return pi;
6816    }
6817
6818    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6819        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6820        if (targetUris != null) {
6821            return targetUris.get(grantUri);
6822        }
6823        return null;
6824    }
6825
6826    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6827            String targetPkg, int targetUid, GrantUri grantUri) {
6828        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6829        if (targetUris == null) {
6830            targetUris = Maps.newArrayMap();
6831            mGrantedUriPermissions.put(targetUid, targetUris);
6832        }
6833
6834        UriPermission perm = targetUris.get(grantUri);
6835        if (perm == null) {
6836            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6837            targetUris.put(grantUri, perm);
6838        }
6839
6840        return perm;
6841    }
6842
6843    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6844            final int modeFlags) {
6845        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6846        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6847                : UriPermission.STRENGTH_OWNED;
6848
6849        // Root gets to do everything.
6850        if (uid == 0) {
6851            return true;
6852        }
6853
6854        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6855        if (perms == null) return false;
6856
6857        // First look for exact match
6858        final UriPermission exactPerm = perms.get(grantUri);
6859        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6860            return true;
6861        }
6862
6863        // No exact match, look for prefixes
6864        final int N = perms.size();
6865        for (int i = 0; i < N; i++) {
6866            final UriPermission perm = perms.valueAt(i);
6867            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6868                    && perm.getStrength(modeFlags) >= minStrength) {
6869                return true;
6870            }
6871        }
6872
6873        return false;
6874    }
6875
6876    /**
6877     * @param uri This uri must NOT contain an embedded userId.
6878     * @param userId The userId in which the uri is to be resolved.
6879     */
6880    @Override
6881    public int checkUriPermission(Uri uri, int pid, int uid,
6882            final int modeFlags, int userId, IBinder callerToken) {
6883        enforceNotIsolatedCaller("checkUriPermission");
6884
6885        // Another redirected-binder-call permissions check as in
6886        // {@link checkPermissionWithToken}.
6887        Identity tlsIdentity = sCallerIdentity.get();
6888        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6889            uid = tlsIdentity.uid;
6890            pid = tlsIdentity.pid;
6891        }
6892
6893        // Our own process gets to do everything.
6894        if (pid == MY_PID) {
6895            return PackageManager.PERMISSION_GRANTED;
6896        }
6897        synchronized (this) {
6898            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6899                    ? PackageManager.PERMISSION_GRANTED
6900                    : PackageManager.PERMISSION_DENIED;
6901        }
6902    }
6903
6904    /**
6905     * Check if the targetPkg can be granted permission to access uri by
6906     * the callingUid using the given modeFlags.  Throws a security exception
6907     * if callingUid is not allowed to do this.  Returns the uid of the target
6908     * if the URI permission grant should be performed; returns -1 if it is not
6909     * needed (for example targetPkg already has permission to access the URI).
6910     * If you already know the uid of the target, you can supply it in
6911     * lastTargetUid else set that to -1.
6912     */
6913    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6914            final int modeFlags, int lastTargetUid) {
6915        if (!Intent.isAccessUriMode(modeFlags)) {
6916            return -1;
6917        }
6918
6919        if (targetPkg != null) {
6920            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6921                    "Checking grant " + targetPkg + " permission to " + grantUri);
6922        }
6923
6924        final IPackageManager pm = AppGlobals.getPackageManager();
6925
6926        // If this is not a content: uri, we can't do anything with it.
6927        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6928            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6929                    "Can't grant URI permission for non-content URI: " + grantUri);
6930            return -1;
6931        }
6932
6933        final String authority = grantUri.uri.getAuthority();
6934        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6935        if (pi == null) {
6936            Slog.w(TAG, "No content provider found for permission check: " +
6937                    grantUri.uri.toSafeString());
6938            return -1;
6939        }
6940
6941        int targetUid = lastTargetUid;
6942        if (targetUid < 0 && targetPkg != null) {
6943            try {
6944                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6945                if (targetUid < 0) {
6946                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6947                            "Can't grant URI permission no uid for: " + targetPkg);
6948                    return -1;
6949                }
6950            } catch (RemoteException ex) {
6951                return -1;
6952            }
6953        }
6954
6955        if (targetUid >= 0) {
6956            // First...  does the target actually need this permission?
6957            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6958                // No need to grant the target this permission.
6959                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6960                        "Target " + targetPkg + " already has full permission to " + grantUri);
6961                return -1;
6962            }
6963        } else {
6964            // First...  there is no target package, so can anyone access it?
6965            boolean allowed = pi.exported;
6966            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6967                if (pi.readPermission != null) {
6968                    allowed = false;
6969                }
6970            }
6971            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6972                if (pi.writePermission != null) {
6973                    allowed = false;
6974                }
6975            }
6976            if (allowed) {
6977                return -1;
6978            }
6979        }
6980
6981        /* There is a special cross user grant if:
6982         * - The target is on another user.
6983         * - Apps on the current user can access the uri without any uid permissions.
6984         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6985         * grant uri permissions.
6986         */
6987        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6988                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6989                modeFlags, false /*without considering the uid permissions*/);
6990
6991        // Second...  is the provider allowing granting of URI permissions?
6992        if (!specialCrossUserGrant) {
6993            if (!pi.grantUriPermissions) {
6994                throw new SecurityException("Provider " + pi.packageName
6995                        + "/" + pi.name
6996                        + " does not allow granting of Uri permissions (uri "
6997                        + grantUri + ")");
6998            }
6999            if (pi.uriPermissionPatterns != null) {
7000                final int N = pi.uriPermissionPatterns.length;
7001                boolean allowed = false;
7002                for (int i=0; i<N; i++) {
7003                    if (pi.uriPermissionPatterns[i] != null
7004                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7005                        allowed = true;
7006                        break;
7007                    }
7008                }
7009                if (!allowed) {
7010                    throw new SecurityException("Provider " + pi.packageName
7011                            + "/" + pi.name
7012                            + " does not allow granting of permission to path of Uri "
7013                            + grantUri);
7014                }
7015            }
7016        }
7017
7018        // Third...  does the caller itself have permission to access
7019        // this uri?
7020        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7021            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7022                // Require they hold a strong enough Uri permission
7023                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7024                    throw new SecurityException("Uid " + callingUid
7025                            + " does not have permission to uri " + grantUri);
7026                }
7027            }
7028        }
7029        return targetUid;
7030    }
7031
7032    /**
7033     * @param uri This uri must NOT contain an embedded userId.
7034     * @param userId The userId in which the uri is to be resolved.
7035     */
7036    @Override
7037    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7038            final int modeFlags, int userId) {
7039        enforceNotIsolatedCaller("checkGrantUriPermission");
7040        synchronized(this) {
7041            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7042                    new GrantUri(userId, uri, false), modeFlags, -1);
7043        }
7044    }
7045
7046    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7047            final int modeFlags, UriPermissionOwner owner) {
7048        if (!Intent.isAccessUriMode(modeFlags)) {
7049            return;
7050        }
7051
7052        // So here we are: the caller has the assumed permission
7053        // to the uri, and the target doesn't.  Let's now give this to
7054        // the target.
7055
7056        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7057                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7058
7059        final String authority = grantUri.uri.getAuthority();
7060        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7061        if (pi == null) {
7062            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7063            return;
7064        }
7065
7066        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7067            grantUri.prefix = true;
7068        }
7069        final UriPermission perm = findOrCreateUriPermissionLocked(
7070                pi.packageName, targetPkg, targetUid, grantUri);
7071        perm.grantModes(modeFlags, owner);
7072    }
7073
7074    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7075            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7076        if (targetPkg == null) {
7077            throw new NullPointerException("targetPkg");
7078        }
7079        int targetUid;
7080        final IPackageManager pm = AppGlobals.getPackageManager();
7081        try {
7082            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7083        } catch (RemoteException ex) {
7084            return;
7085        }
7086
7087        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7088                targetUid);
7089        if (targetUid < 0) {
7090            return;
7091        }
7092
7093        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7094                owner);
7095    }
7096
7097    static class NeededUriGrants extends ArrayList<GrantUri> {
7098        final String targetPkg;
7099        final int targetUid;
7100        final int flags;
7101
7102        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7103            this.targetPkg = targetPkg;
7104            this.targetUid = targetUid;
7105            this.flags = flags;
7106        }
7107    }
7108
7109    /**
7110     * Like checkGrantUriPermissionLocked, but takes an Intent.
7111     */
7112    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7113            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7114        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7115                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7116                + " clip=" + (intent != null ? intent.getClipData() : null)
7117                + " from " + intent + "; flags=0x"
7118                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7119
7120        if (targetPkg == null) {
7121            throw new NullPointerException("targetPkg");
7122        }
7123
7124        if (intent == null) {
7125            return null;
7126        }
7127        Uri data = intent.getData();
7128        ClipData clip = intent.getClipData();
7129        if (data == null && clip == null) {
7130            return null;
7131        }
7132        // Default userId for uris in the intent (if they don't specify it themselves)
7133        int contentUserHint = intent.getContentUserHint();
7134        if (contentUserHint == UserHandle.USER_CURRENT) {
7135            contentUserHint = UserHandle.getUserId(callingUid);
7136        }
7137        final IPackageManager pm = AppGlobals.getPackageManager();
7138        int targetUid;
7139        if (needed != null) {
7140            targetUid = needed.targetUid;
7141        } else {
7142            try {
7143                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7144            } catch (RemoteException ex) {
7145                return null;
7146            }
7147            if (targetUid < 0) {
7148                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7149                        "Can't grant URI permission no uid for: " + targetPkg
7150                        + " on user " + targetUserId);
7151                return null;
7152            }
7153        }
7154        if (data != null) {
7155            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7156            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7157                    targetUid);
7158            if (targetUid > 0) {
7159                if (needed == null) {
7160                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7161                }
7162                needed.add(grantUri);
7163            }
7164        }
7165        if (clip != null) {
7166            for (int i=0; i<clip.getItemCount(); i++) {
7167                Uri uri = clip.getItemAt(i).getUri();
7168                if (uri != null) {
7169                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7170                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7171                            targetUid);
7172                    if (targetUid > 0) {
7173                        if (needed == null) {
7174                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7175                        }
7176                        needed.add(grantUri);
7177                    }
7178                } else {
7179                    Intent clipIntent = clip.getItemAt(i).getIntent();
7180                    if (clipIntent != null) {
7181                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7182                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7183                        if (newNeeded != null) {
7184                            needed = newNeeded;
7185                        }
7186                    }
7187                }
7188            }
7189        }
7190
7191        return needed;
7192    }
7193
7194    /**
7195     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7196     */
7197    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7198            UriPermissionOwner owner) {
7199        if (needed != null) {
7200            for (int i=0; i<needed.size(); i++) {
7201                GrantUri grantUri = needed.get(i);
7202                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7203                        grantUri, needed.flags, owner);
7204            }
7205        }
7206    }
7207
7208    void grantUriPermissionFromIntentLocked(int callingUid,
7209            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7210        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7211                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7212        if (needed == null) {
7213            return;
7214        }
7215
7216        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7217    }
7218
7219    /**
7220     * @param uri This uri must NOT contain an embedded userId.
7221     * @param userId The userId in which the uri is to be resolved.
7222     */
7223    @Override
7224    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7225            final int modeFlags, int userId) {
7226        enforceNotIsolatedCaller("grantUriPermission");
7227        GrantUri grantUri = new GrantUri(userId, uri, false);
7228        synchronized(this) {
7229            final ProcessRecord r = getRecordForAppLocked(caller);
7230            if (r == null) {
7231                throw new SecurityException("Unable to find app for caller "
7232                        + caller
7233                        + " when granting permission to uri " + grantUri);
7234            }
7235            if (targetPkg == null) {
7236                throw new IllegalArgumentException("null target");
7237            }
7238            if (grantUri == null) {
7239                throw new IllegalArgumentException("null uri");
7240            }
7241
7242            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7243                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7244                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7245                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7246
7247            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7248                    UserHandle.getUserId(r.uid));
7249        }
7250    }
7251
7252    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7253        if (perm.modeFlags == 0) {
7254            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7255                    perm.targetUid);
7256            if (perms != null) {
7257                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7258                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7259
7260                perms.remove(perm.uri);
7261                if (perms.isEmpty()) {
7262                    mGrantedUriPermissions.remove(perm.targetUid);
7263                }
7264            }
7265        }
7266    }
7267
7268    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7269        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7270                "Revoking all granted permissions to " + grantUri);
7271
7272        final IPackageManager pm = AppGlobals.getPackageManager();
7273        final String authority = grantUri.uri.getAuthority();
7274        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7275        if (pi == null) {
7276            Slog.w(TAG, "No content provider found for permission revoke: "
7277                    + grantUri.toSafeString());
7278            return;
7279        }
7280
7281        // Does the caller have this permission on the URI?
7282        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7283            // If they don't have direct access to the URI, then revoke any
7284            // ownerless URI permissions that have been granted to them.
7285            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7286            if (perms != null) {
7287                boolean persistChanged = false;
7288                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7289                    final UriPermission perm = it.next();
7290                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7291                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7292                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7293                                "Revoking non-owned " + perm.targetUid
7294                                + " permission to " + perm.uri);
7295                        persistChanged |= perm.revokeModes(
7296                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7297                        if (perm.modeFlags == 0) {
7298                            it.remove();
7299                        }
7300                    }
7301                }
7302                if (perms.isEmpty()) {
7303                    mGrantedUriPermissions.remove(callingUid);
7304                }
7305                if (persistChanged) {
7306                    schedulePersistUriGrants();
7307                }
7308            }
7309            return;
7310        }
7311
7312        boolean persistChanged = false;
7313
7314        // Go through all of the permissions and remove any that match.
7315        int N = mGrantedUriPermissions.size();
7316        for (int i = 0; i < N; i++) {
7317            final int targetUid = mGrantedUriPermissions.keyAt(i);
7318            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7319
7320            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7321                final UriPermission perm = it.next();
7322                if (perm.uri.sourceUserId == grantUri.sourceUserId
7323                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7324                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7325                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7326                    persistChanged |= perm.revokeModes(
7327                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7328                    if (perm.modeFlags == 0) {
7329                        it.remove();
7330                    }
7331                }
7332            }
7333
7334            if (perms.isEmpty()) {
7335                mGrantedUriPermissions.remove(targetUid);
7336                N--;
7337                i--;
7338            }
7339        }
7340
7341        if (persistChanged) {
7342            schedulePersistUriGrants();
7343        }
7344    }
7345
7346    /**
7347     * @param uri This uri must NOT contain an embedded userId.
7348     * @param userId The userId in which the uri is to be resolved.
7349     */
7350    @Override
7351    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7352            int userId) {
7353        enforceNotIsolatedCaller("revokeUriPermission");
7354        synchronized(this) {
7355            final ProcessRecord r = getRecordForAppLocked(caller);
7356            if (r == null) {
7357                throw new SecurityException("Unable to find app for caller "
7358                        + caller
7359                        + " when revoking permission to uri " + uri);
7360            }
7361            if (uri == null) {
7362                Slog.w(TAG, "revokeUriPermission: null uri");
7363                return;
7364            }
7365
7366            if (!Intent.isAccessUriMode(modeFlags)) {
7367                return;
7368            }
7369
7370            final String authority = uri.getAuthority();
7371            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7372            if (pi == null) {
7373                Slog.w(TAG, "No content provider found for permission revoke: "
7374                        + uri.toSafeString());
7375                return;
7376            }
7377
7378            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7379        }
7380    }
7381
7382    /**
7383     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7384     * given package.
7385     *
7386     * @param packageName Package name to match, or {@code null} to apply to all
7387     *            packages.
7388     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7389     *            to all users.
7390     * @param persistable If persistable grants should be removed.
7391     */
7392    private void removeUriPermissionsForPackageLocked(
7393            String packageName, int userHandle, boolean persistable) {
7394        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7395            throw new IllegalArgumentException("Must narrow by either package or user");
7396        }
7397
7398        boolean persistChanged = false;
7399
7400        int N = mGrantedUriPermissions.size();
7401        for (int i = 0; i < N; i++) {
7402            final int targetUid = mGrantedUriPermissions.keyAt(i);
7403            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7404
7405            // Only inspect grants matching user
7406            if (userHandle == UserHandle.USER_ALL
7407                    || userHandle == UserHandle.getUserId(targetUid)) {
7408                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7409                    final UriPermission perm = it.next();
7410
7411                    // Only inspect grants matching package
7412                    if (packageName == null || perm.sourcePkg.equals(packageName)
7413                            || perm.targetPkg.equals(packageName)) {
7414                        persistChanged |= perm.revokeModes(persistable
7415                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7416
7417                        // Only remove when no modes remain; any persisted grants
7418                        // will keep this alive.
7419                        if (perm.modeFlags == 0) {
7420                            it.remove();
7421                        }
7422                    }
7423                }
7424
7425                if (perms.isEmpty()) {
7426                    mGrantedUriPermissions.remove(targetUid);
7427                    N--;
7428                    i--;
7429                }
7430            }
7431        }
7432
7433        if (persistChanged) {
7434            schedulePersistUriGrants();
7435        }
7436    }
7437
7438    @Override
7439    public IBinder newUriPermissionOwner(String name) {
7440        enforceNotIsolatedCaller("newUriPermissionOwner");
7441        synchronized(this) {
7442            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7443            return owner.getExternalTokenLocked();
7444        }
7445    }
7446
7447    /**
7448     * @param uri This uri must NOT contain an embedded userId.
7449     * @param sourceUserId The userId in which the uri is to be resolved.
7450     * @param targetUserId The userId of the app that receives the grant.
7451     */
7452    @Override
7453    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7454            final int modeFlags, int sourceUserId, int targetUserId) {
7455        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7456                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7457        synchronized(this) {
7458            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7459            if (owner == null) {
7460                throw new IllegalArgumentException("Unknown owner: " + token);
7461            }
7462            if (fromUid != Binder.getCallingUid()) {
7463                if (Binder.getCallingUid() != Process.myUid()) {
7464                    // Only system code can grant URI permissions on behalf
7465                    // of other users.
7466                    throw new SecurityException("nice try");
7467                }
7468            }
7469            if (targetPkg == null) {
7470                throw new IllegalArgumentException("null target");
7471            }
7472            if (uri == null) {
7473                throw new IllegalArgumentException("null uri");
7474            }
7475
7476            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7477                    modeFlags, owner, targetUserId);
7478        }
7479    }
7480
7481    /**
7482     * @param uri This uri must NOT contain an embedded userId.
7483     * @param userId The userId in which the uri is to be resolved.
7484     */
7485    @Override
7486    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7487        synchronized(this) {
7488            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7489            if (owner == null) {
7490                throw new IllegalArgumentException("Unknown owner: " + token);
7491            }
7492
7493            if (uri == null) {
7494                owner.removeUriPermissionsLocked(mode);
7495            } else {
7496                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7497            }
7498        }
7499    }
7500
7501    private void schedulePersistUriGrants() {
7502        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7503            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7504                    10 * DateUtils.SECOND_IN_MILLIS);
7505        }
7506    }
7507
7508    private void writeGrantedUriPermissions() {
7509        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7510
7511        // Snapshot permissions so we can persist without lock
7512        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7513        synchronized (this) {
7514            final int size = mGrantedUriPermissions.size();
7515            for (int i = 0; i < size; i++) {
7516                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7517                for (UriPermission perm : perms.values()) {
7518                    if (perm.persistedModeFlags != 0) {
7519                        persist.add(perm.snapshot());
7520                    }
7521                }
7522            }
7523        }
7524
7525        FileOutputStream fos = null;
7526        try {
7527            fos = mGrantFile.startWrite();
7528
7529            XmlSerializer out = new FastXmlSerializer();
7530            out.setOutput(fos, "utf-8");
7531            out.startDocument(null, true);
7532            out.startTag(null, TAG_URI_GRANTS);
7533            for (UriPermission.Snapshot perm : persist) {
7534                out.startTag(null, TAG_URI_GRANT);
7535                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7536                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7537                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7538                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7539                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7540                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7541                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7542                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7543                out.endTag(null, TAG_URI_GRANT);
7544            }
7545            out.endTag(null, TAG_URI_GRANTS);
7546            out.endDocument();
7547
7548            mGrantFile.finishWrite(fos);
7549        } catch (IOException e) {
7550            if (fos != null) {
7551                mGrantFile.failWrite(fos);
7552            }
7553        }
7554    }
7555
7556    private void readGrantedUriPermissionsLocked() {
7557        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7558
7559        final long now = System.currentTimeMillis();
7560
7561        FileInputStream fis = null;
7562        try {
7563            fis = mGrantFile.openRead();
7564            final XmlPullParser in = Xml.newPullParser();
7565            in.setInput(fis, null);
7566
7567            int type;
7568            while ((type = in.next()) != END_DOCUMENT) {
7569                final String tag = in.getName();
7570                if (type == START_TAG) {
7571                    if (TAG_URI_GRANT.equals(tag)) {
7572                        final int sourceUserId;
7573                        final int targetUserId;
7574                        final int userHandle = readIntAttribute(in,
7575                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7576                        if (userHandle != UserHandle.USER_NULL) {
7577                            // For backwards compatibility.
7578                            sourceUserId = userHandle;
7579                            targetUserId = userHandle;
7580                        } else {
7581                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7582                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7583                        }
7584                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7585                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7586                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7587                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7588                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7589                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7590
7591                        // Sanity check that provider still belongs to source package
7592                        final ProviderInfo pi = getProviderInfoLocked(
7593                                uri.getAuthority(), sourceUserId);
7594                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7595                            int targetUid = -1;
7596                            try {
7597                                targetUid = AppGlobals.getPackageManager()
7598                                        .getPackageUid(targetPkg, targetUserId);
7599                            } catch (RemoteException e) {
7600                            }
7601                            if (targetUid != -1) {
7602                                final UriPermission perm = findOrCreateUriPermissionLocked(
7603                                        sourcePkg, targetPkg, targetUid,
7604                                        new GrantUri(sourceUserId, uri, prefix));
7605                                perm.initPersistedModes(modeFlags, createdTime);
7606                            }
7607                        } else {
7608                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7609                                    + " but instead found " + pi);
7610                        }
7611                    }
7612                }
7613            }
7614        } catch (FileNotFoundException e) {
7615            // Missing grants is okay
7616        } catch (IOException e) {
7617            Slog.wtf(TAG, "Failed reading Uri grants", e);
7618        } catch (XmlPullParserException e) {
7619            Slog.wtf(TAG, "Failed reading Uri grants", e);
7620        } finally {
7621            IoUtils.closeQuietly(fis);
7622        }
7623    }
7624
7625    /**
7626     * @param uri This uri must NOT contain an embedded userId.
7627     * @param userId The userId in which the uri is to be resolved.
7628     */
7629    @Override
7630    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7631        enforceNotIsolatedCaller("takePersistableUriPermission");
7632
7633        Preconditions.checkFlagsArgument(modeFlags,
7634                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7635
7636        synchronized (this) {
7637            final int callingUid = Binder.getCallingUid();
7638            boolean persistChanged = false;
7639            GrantUri grantUri = new GrantUri(userId, uri, false);
7640
7641            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7642                    new GrantUri(userId, uri, false));
7643            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7644                    new GrantUri(userId, uri, true));
7645
7646            final boolean exactValid = (exactPerm != null)
7647                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7648            final boolean prefixValid = (prefixPerm != null)
7649                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7650
7651            if (!(exactValid || prefixValid)) {
7652                throw new SecurityException("No persistable permission grants found for UID "
7653                        + callingUid + " and Uri " + grantUri.toSafeString());
7654            }
7655
7656            if (exactValid) {
7657                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7658            }
7659            if (prefixValid) {
7660                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7661            }
7662
7663            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7664
7665            if (persistChanged) {
7666                schedulePersistUriGrants();
7667            }
7668        }
7669    }
7670
7671    /**
7672     * @param uri This uri must NOT contain an embedded userId.
7673     * @param userId The userId in which the uri is to be resolved.
7674     */
7675    @Override
7676    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7677        enforceNotIsolatedCaller("releasePersistableUriPermission");
7678
7679        Preconditions.checkFlagsArgument(modeFlags,
7680                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7681
7682        synchronized (this) {
7683            final int callingUid = Binder.getCallingUid();
7684            boolean persistChanged = false;
7685
7686            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7687                    new GrantUri(userId, uri, false));
7688            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7689                    new GrantUri(userId, uri, true));
7690            if (exactPerm == null && prefixPerm == null) {
7691                throw new SecurityException("No permission grants found for UID " + callingUid
7692                        + " and Uri " + uri.toSafeString());
7693            }
7694
7695            if (exactPerm != null) {
7696                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7697                removeUriPermissionIfNeededLocked(exactPerm);
7698            }
7699            if (prefixPerm != null) {
7700                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7701                removeUriPermissionIfNeededLocked(prefixPerm);
7702            }
7703
7704            if (persistChanged) {
7705                schedulePersistUriGrants();
7706            }
7707        }
7708    }
7709
7710    /**
7711     * Prune any older {@link UriPermission} for the given UID until outstanding
7712     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7713     *
7714     * @return if any mutations occured that require persisting.
7715     */
7716    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7717        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7718        if (perms == null) return false;
7719        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7720
7721        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7722        for (UriPermission perm : perms.values()) {
7723            if (perm.persistedModeFlags != 0) {
7724                persisted.add(perm);
7725            }
7726        }
7727
7728        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7729        if (trimCount <= 0) return false;
7730
7731        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7732        for (int i = 0; i < trimCount; i++) {
7733            final UriPermission perm = persisted.get(i);
7734
7735            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7736                    "Trimming grant created at " + perm.persistedCreateTime);
7737
7738            perm.releasePersistableModes(~0);
7739            removeUriPermissionIfNeededLocked(perm);
7740        }
7741
7742        return true;
7743    }
7744
7745    @Override
7746    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7747            String packageName, boolean incoming) {
7748        enforceNotIsolatedCaller("getPersistedUriPermissions");
7749        Preconditions.checkNotNull(packageName, "packageName");
7750
7751        final int callingUid = Binder.getCallingUid();
7752        final IPackageManager pm = AppGlobals.getPackageManager();
7753        try {
7754            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7755            if (packageUid != callingUid) {
7756                throw new SecurityException(
7757                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7758            }
7759        } catch (RemoteException e) {
7760            throw new SecurityException("Failed to verify package name ownership");
7761        }
7762
7763        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7764        synchronized (this) {
7765            if (incoming) {
7766                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7767                        callingUid);
7768                if (perms == null) {
7769                    Slog.w(TAG, "No permission grants found for " + packageName);
7770                } else {
7771                    for (UriPermission perm : perms.values()) {
7772                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7773                            result.add(perm.buildPersistedPublicApiObject());
7774                        }
7775                    }
7776                }
7777            } else {
7778                final int size = mGrantedUriPermissions.size();
7779                for (int i = 0; i < size; i++) {
7780                    final ArrayMap<GrantUri, UriPermission> perms =
7781                            mGrantedUriPermissions.valueAt(i);
7782                    for (UriPermission perm : perms.values()) {
7783                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7784                            result.add(perm.buildPersistedPublicApiObject());
7785                        }
7786                    }
7787                }
7788            }
7789        }
7790        return new ParceledListSlice<android.content.UriPermission>(result);
7791    }
7792
7793    @Override
7794    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7795        synchronized (this) {
7796            ProcessRecord app =
7797                who != null ? getRecordForAppLocked(who) : null;
7798            if (app == null) return;
7799
7800            Message msg = Message.obtain();
7801            msg.what = WAIT_FOR_DEBUGGER_MSG;
7802            msg.obj = app;
7803            msg.arg1 = waiting ? 1 : 0;
7804            mUiHandler.sendMessage(msg);
7805        }
7806    }
7807
7808    @Override
7809    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7810        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7811        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7812        outInfo.availMem = Process.getFreeMemory();
7813        outInfo.totalMem = Process.getTotalMemory();
7814        outInfo.threshold = homeAppMem;
7815        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7816        outInfo.hiddenAppThreshold = cachedAppMem;
7817        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7818                ProcessList.SERVICE_ADJ);
7819        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7820                ProcessList.VISIBLE_APP_ADJ);
7821        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7822                ProcessList.FOREGROUND_APP_ADJ);
7823    }
7824
7825    // =========================================================
7826    // TASK MANAGEMENT
7827    // =========================================================
7828
7829    @Override
7830    public List<IAppTask> getAppTasks(String callingPackage) {
7831        int callingUid = Binder.getCallingUid();
7832        long ident = Binder.clearCallingIdentity();
7833
7834        synchronized(this) {
7835            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7836            try {
7837                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
7838
7839                final int N = mRecentTasks.size();
7840                for (int i = 0; i < N; i++) {
7841                    TaskRecord tr = mRecentTasks.get(i);
7842                    // Skip tasks that do not match the caller.  We don't need to verify
7843                    // callingPackage, because we are also limiting to callingUid and know
7844                    // that will limit to the correct security sandbox.
7845                    if (tr.effectiveUid != callingUid) {
7846                        continue;
7847                    }
7848                    Intent intent = tr.getBaseIntent();
7849                    if (intent == null ||
7850                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7851                        continue;
7852                    }
7853                    ActivityManager.RecentTaskInfo taskInfo =
7854                            createRecentTaskInfoFromTaskRecord(tr);
7855                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7856                    list.add(taskImpl);
7857                }
7858            } finally {
7859                Binder.restoreCallingIdentity(ident);
7860            }
7861            return list;
7862        }
7863    }
7864
7865    @Override
7866    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7867        final int callingUid = Binder.getCallingUid();
7868        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7869
7870        synchronized(this) {
7871            if (DEBUG_ALL) Slog.v(
7872                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7873
7874            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7875                    callingUid);
7876
7877            // TODO: Improve with MRU list from all ActivityStacks.
7878            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7879        }
7880
7881        return list;
7882    }
7883
7884    /**
7885     * Creates a new RecentTaskInfo from a TaskRecord.
7886     */
7887    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7888        // Update the task description to reflect any changes in the task stack
7889        tr.updateTaskDescription();
7890
7891        // Compose the recent task info
7892        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7893        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7894        rti.persistentId = tr.taskId;
7895        rti.baseIntent = new Intent(tr.getBaseIntent());
7896        rti.origActivity = tr.origActivity;
7897        rti.description = tr.lastDescription;
7898        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7899        rti.userId = tr.userId;
7900        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7901        rti.firstActiveTime = tr.firstActiveTime;
7902        rti.lastActiveTime = tr.lastActiveTime;
7903        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7904        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7905        rti.numActivities = 0;
7906
7907        ActivityRecord base = null;
7908        ActivityRecord top = null;
7909        ActivityRecord tmp;
7910
7911        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
7912            tmp = tr.mActivities.get(i);
7913            if (tmp.finishing) {
7914                continue;
7915            }
7916            base = tmp;
7917            if (top == null || (top.state == ActivityState.INITIALIZING)) {
7918                top = base;
7919            }
7920            rti.numActivities++;
7921        }
7922
7923        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
7924        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
7925
7926        return rti;
7927    }
7928
7929    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7930        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7931                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7932        if (!allowed) {
7933            if (checkPermission(android.Manifest.permission.GET_TASKS,
7934                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7935                // Temporary compatibility: some existing apps on the system image may
7936                // still be requesting the old permission and not switched to the new
7937                // one; if so, we'll still allow them full access.  This means we need
7938                // to see if they are holding the old permission and are a system app.
7939                try {
7940                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7941                        allowed = true;
7942                        Slog.w(TAG, caller + ": caller " + callingUid
7943                                + " is using old GET_TASKS but privileged; allowing");
7944                    }
7945                } catch (RemoteException e) {
7946                }
7947            }
7948        }
7949        if (!allowed) {
7950            Slog.w(TAG, caller + ": caller " + callingUid
7951                    + " does not hold REAL_GET_TASKS; limiting output");
7952        }
7953        return allowed;
7954    }
7955
7956    @Override
7957    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7958        final int callingUid = Binder.getCallingUid();
7959        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7960                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7961
7962        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7963        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7964        synchronized (this) {
7965            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7966                    callingUid);
7967            final boolean detailed = checkCallingPermission(
7968                    android.Manifest.permission.GET_DETAILED_TASKS)
7969                    == PackageManager.PERMISSION_GRANTED;
7970
7971            final int recentsCount = mRecentTasks.size();
7972            ArrayList<ActivityManager.RecentTaskInfo> res =
7973                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
7974
7975            final Set<Integer> includedUsers;
7976            if (includeProfiles) {
7977                includedUsers = getProfileIdsLocked(userId);
7978            } else {
7979                includedUsers = new HashSet<>();
7980            }
7981            includedUsers.add(Integer.valueOf(userId));
7982
7983            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
7984                TaskRecord tr = mRecentTasks.get(i);
7985                // Only add calling user or related users recent tasks
7986                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7987                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
7988                    continue;
7989                }
7990
7991                // Return the entry if desired by the caller.  We always return
7992                // the first entry, because callers always expect this to be the
7993                // foreground app.  We may filter others if the caller has
7994                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7995                // we should exclude the entry.
7996
7997                if (i == 0
7998                        || withExcluded
7999                        || (tr.intent == null)
8000                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8001                                == 0)) {
8002                    if (!allowed) {
8003                        // If the caller doesn't have the GET_TASKS permission, then only
8004                        // allow them to see a small subset of tasks -- their own and home.
8005                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8006                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8007                            continue;
8008                        }
8009                    }
8010                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8011                        if (tr.stack != null && tr.stack.isHomeStack()) {
8012                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8013                                    "Skipping, home stack task: " + tr);
8014                            continue;
8015                        }
8016                    }
8017                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8018                        // Don't include auto remove tasks that are finished or finishing.
8019                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8020                                "Skipping, auto-remove without activity: " + tr);
8021                        continue;
8022                    }
8023                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8024                            && !tr.isAvailable) {
8025                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8026                                "Skipping, unavail real act: " + tr);
8027                        continue;
8028                    }
8029
8030                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8031                    if (!detailed) {
8032                        rti.baseIntent.replaceExtras((Bundle)null);
8033                    }
8034
8035                    res.add(rti);
8036                    maxNum--;
8037                }
8038            }
8039            return res;
8040        }
8041    }
8042
8043    @Override
8044    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8045        synchronized (this) {
8046            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8047                    "getTaskThumbnail()");
8048            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8049            if (tr != null) {
8050                return tr.getTaskThumbnailLocked();
8051            }
8052        }
8053        return null;
8054    }
8055
8056    @Override
8057    public int addAppTask(IBinder activityToken, Intent intent,
8058            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8059        final int callingUid = Binder.getCallingUid();
8060        final long callingIdent = Binder.clearCallingIdentity();
8061
8062        try {
8063            synchronized (this) {
8064                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8065                if (r == null) {
8066                    throw new IllegalArgumentException("Activity does not exist; token="
8067                            + activityToken);
8068                }
8069                ComponentName comp = intent.getComponent();
8070                if (comp == null) {
8071                    throw new IllegalArgumentException("Intent " + intent
8072                            + " must specify explicit component");
8073                }
8074                if (thumbnail.getWidth() != mThumbnailWidth
8075                        || thumbnail.getHeight() != mThumbnailHeight) {
8076                    throw new IllegalArgumentException("Bad thumbnail size: got "
8077                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8078                            + mThumbnailWidth + "x" + mThumbnailHeight);
8079                }
8080                if (intent.getSelector() != null) {
8081                    intent.setSelector(null);
8082                }
8083                if (intent.getSourceBounds() != null) {
8084                    intent.setSourceBounds(null);
8085                }
8086                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8087                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8088                        // The caller has added this as an auto-remove task...  that makes no
8089                        // sense, so turn off auto-remove.
8090                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8091                    }
8092                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8093                    // Must be a new task.
8094                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8095                }
8096                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8097                    mLastAddedTaskActivity = null;
8098                }
8099                ActivityInfo ainfo = mLastAddedTaskActivity;
8100                if (ainfo == null) {
8101                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8102                            comp, 0, UserHandle.getUserId(callingUid));
8103                    if (ainfo.applicationInfo.uid != callingUid) {
8104                        throw new SecurityException(
8105                                "Can't add task for another application: target uid="
8106                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8107                    }
8108                }
8109
8110                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8111                        intent, description);
8112
8113                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8114                if (trimIdx >= 0) {
8115                    // If this would have caused a trim, then we'll abort because that
8116                    // means it would be added at the end of the list but then just removed.
8117                    return INVALID_TASK_ID;
8118                }
8119
8120                final int N = mRecentTasks.size();
8121                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8122                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8123                    tr.removedFromRecents();
8124                }
8125
8126                task.inRecents = true;
8127                mRecentTasks.add(task);
8128                r.task.stack.addTask(task, false, false);
8129
8130                task.setLastThumbnail(thumbnail);
8131                task.freeLastThumbnail();
8132
8133                return task.taskId;
8134            }
8135        } finally {
8136            Binder.restoreCallingIdentity(callingIdent);
8137        }
8138    }
8139
8140    @Override
8141    public Point getAppTaskThumbnailSize() {
8142        synchronized (this) {
8143            return new Point(mThumbnailWidth,  mThumbnailHeight);
8144        }
8145    }
8146
8147    @Override
8148    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8149        synchronized (this) {
8150            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8151            if (r != null) {
8152                r.setTaskDescription(td);
8153                r.task.updateTaskDescription();
8154            }
8155        }
8156    }
8157
8158    @Override
8159    public void setTaskResizeable(int taskId, boolean resizeable) {
8160        synchronized (this) {
8161            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8162            if (task == null) {
8163                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8164                return;
8165            }
8166            if (task.mResizeable != resizeable) {
8167                task.mResizeable = resizeable;
8168                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8169                mStackSupervisor.resumeTopActivitiesLocked();
8170            }
8171        }
8172    }
8173
8174    @Override
8175    public void resizeTask(int taskId, Rect bounds) {
8176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8177                "resizeTask()");
8178        long ident = Binder.clearCallingIdentity();
8179        try {
8180            synchronized (this) {
8181                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8182                if (task == null) {
8183                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8184                    return;
8185                }
8186                mStackSupervisor.resizeTaskLocked(task, bounds);
8187            }
8188        } finally {
8189            Binder.restoreCallingIdentity(ident);
8190        }
8191    }
8192
8193    @Override
8194    public Bitmap getTaskDescriptionIcon(String filename) {
8195        if (!FileUtils.isValidExtFilename(filename)
8196                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8197            throw new IllegalArgumentException("Bad filename: " + filename);
8198        }
8199        return mTaskPersister.getTaskDescriptionIcon(filename);
8200    }
8201
8202    @Override
8203    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8204            throws RemoteException {
8205        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8206                opts.getCustomInPlaceResId() == 0) {
8207            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8208                    "with valid animation");
8209        }
8210        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8211        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8212                opts.getCustomInPlaceResId());
8213        mWindowManager.executeAppTransition();
8214    }
8215
8216    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8217        mRecentTasks.remove(tr);
8218        tr.removedFromRecents();
8219        ComponentName component = tr.getBaseIntent().getComponent();
8220        if (component == null) {
8221            Slog.w(TAG, "No component for base intent of task: " + tr);
8222            return;
8223        }
8224
8225        if (!killProcess) {
8226            return;
8227        }
8228
8229        // Determine if the process(es) for this task should be killed.
8230        final String pkg = component.getPackageName();
8231        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8232        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8233        for (int i = 0; i < pmap.size(); i++) {
8234
8235            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8236            for (int j = 0; j < uids.size(); j++) {
8237                ProcessRecord proc = uids.valueAt(j);
8238                if (proc.userId != tr.userId) {
8239                    // Don't kill process for a different user.
8240                    continue;
8241                }
8242                if (proc == mHomeProcess) {
8243                    // Don't kill the home process along with tasks from the same package.
8244                    continue;
8245                }
8246                if (!proc.pkgList.containsKey(pkg)) {
8247                    // Don't kill process that is not associated with this task.
8248                    continue;
8249                }
8250
8251                for (int k = 0; k < proc.activities.size(); k++) {
8252                    TaskRecord otherTask = proc.activities.get(k).task;
8253                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8254                        // Don't kill process(es) that has an activity in a different task that is
8255                        // also in recents.
8256                        return;
8257                    }
8258                }
8259
8260                // Add process to kill list.
8261                procsToKill.add(proc);
8262            }
8263        }
8264
8265        // Find any running services associated with this app and stop if needed.
8266        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8267
8268        // Kill the running processes.
8269        for (int i = 0; i < procsToKill.size(); i++) {
8270            ProcessRecord pr = procsToKill.get(i);
8271            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8272                pr.kill("remove task", true);
8273            } else {
8274                pr.waitingToKill = "remove task";
8275            }
8276        }
8277    }
8278
8279    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8280        // Remove all tasks with activities in the specified package from the list of recent tasks
8281        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8282            TaskRecord tr = mRecentTasks.get(i);
8283            if (tr.userId != userId) continue;
8284
8285            ComponentName cn = tr.intent.getComponent();
8286            if (cn != null && cn.getPackageName().equals(packageName)) {
8287                // If the package name matches, remove the task.
8288                removeTaskByIdLocked(tr.taskId, true);
8289            }
8290        }
8291    }
8292
8293    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8294        final IPackageManager pm = AppGlobals.getPackageManager();
8295        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8296
8297        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8298            TaskRecord tr = mRecentTasks.get(i);
8299            if (tr.userId != userId) continue;
8300
8301            ComponentName cn = tr.intent.getComponent();
8302            if (cn != null && cn.getPackageName().equals(packageName)) {
8303                // Skip if component still exists in the package.
8304                if (componentsKnownToExist.contains(cn)) continue;
8305
8306                try {
8307                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8308                    if (info != null) {
8309                        componentsKnownToExist.add(cn);
8310                    } else {
8311                        removeTaskByIdLocked(tr.taskId, false);
8312                    }
8313                } catch (RemoteException e) {
8314                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8315                }
8316            }
8317        }
8318    }
8319
8320    /**
8321     * Removes the task with the specified task id.
8322     *
8323     * @param taskId Identifier of the task to be removed.
8324     * @param killProcess Kill any process associated with the task if possible.
8325     * @return Returns true if the given task was found and removed.
8326     */
8327    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8328        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8329        if (tr != null) {
8330            tr.removeTaskActivitiesLocked();
8331            cleanUpRemovedTaskLocked(tr, killProcess);
8332            if (tr.isPersistable) {
8333                notifyTaskPersisterLocked(null, true);
8334            }
8335            return true;
8336        }
8337        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8338        return false;
8339    }
8340
8341    @Override
8342    public boolean removeTask(int taskId) {
8343        synchronized (this) {
8344            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8345                    "removeTask()");
8346            long ident = Binder.clearCallingIdentity();
8347            try {
8348                return removeTaskByIdLocked(taskId, true);
8349            } finally {
8350                Binder.restoreCallingIdentity(ident);
8351            }
8352        }
8353    }
8354
8355    /**
8356     * TODO: Add mController hook
8357     */
8358    @Override
8359    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8360        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8361
8362        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8363        synchronized(this) {
8364            moveTaskToFrontLocked(taskId, flags, options);
8365        }
8366    }
8367
8368    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8369        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8370                Binder.getCallingUid(), -1, -1, "Task to front")) {
8371            ActivityOptions.abort(options);
8372            return;
8373        }
8374        final long origId = Binder.clearCallingIdentity();
8375        try {
8376            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8377            if (task == null) {
8378                Slog.d(TAG, "Could not find task for id: "+ taskId);
8379                return;
8380            }
8381            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8382                mStackSupervisor.showLockTaskToast();
8383                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8384                return;
8385            }
8386            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8387            if (prev != null && prev.isRecentsActivity()) {
8388                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8389            }
8390            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8391        } finally {
8392            Binder.restoreCallingIdentity(origId);
8393        }
8394        ActivityOptions.abort(options);
8395    }
8396
8397    /**
8398     * Moves an activity, and all of the other activities within the same task, to the bottom
8399     * of the history stack.  The activity's order within the task is unchanged.
8400     *
8401     * @param token A reference to the activity we wish to move
8402     * @param nonRoot If false then this only works if the activity is the root
8403     *                of a task; if true it will work for any activity in a task.
8404     * @return Returns true if the move completed, false if not.
8405     */
8406    @Override
8407    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8408        enforceNotIsolatedCaller("moveActivityTaskToBack");
8409        synchronized(this) {
8410            final long origId = Binder.clearCallingIdentity();
8411            try {
8412                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8413                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8414                if (task != null) {
8415                    if (mStackSupervisor.isLockedTask(task)) {
8416                        mStackSupervisor.showLockTaskToast();
8417                        return false;
8418                    }
8419                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8420                }
8421            } finally {
8422                Binder.restoreCallingIdentity(origId);
8423            }
8424        }
8425        return false;
8426    }
8427
8428    @Override
8429    public void moveTaskBackwards(int task) {
8430        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8431                "moveTaskBackwards()");
8432
8433        synchronized(this) {
8434            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8435                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8436                return;
8437            }
8438            final long origId = Binder.clearCallingIdentity();
8439            moveTaskBackwardsLocked(task);
8440            Binder.restoreCallingIdentity(origId);
8441        }
8442    }
8443
8444    private final void moveTaskBackwardsLocked(int task) {
8445        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8446    }
8447
8448    @Override
8449    public IBinder getHomeActivityToken() throws RemoteException {
8450        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8451                "getHomeActivityToken()");
8452        synchronized (this) {
8453            return mStackSupervisor.getHomeActivityToken();
8454        }
8455    }
8456
8457    @Override
8458    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8459            IActivityContainerCallback callback) throws RemoteException {
8460        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8461                "createActivityContainer()");
8462        synchronized (this) {
8463            if (parentActivityToken == null) {
8464                throw new IllegalArgumentException("parent token must not be null");
8465            }
8466            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8467            if (r == null) {
8468                return null;
8469            }
8470            if (callback == null) {
8471                throw new IllegalArgumentException("callback must not be null");
8472            }
8473            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8474        }
8475    }
8476
8477    @Override
8478    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8479        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8480                "deleteActivityContainer()");
8481        synchronized (this) {
8482            mStackSupervisor.deleteActivityContainer(container);
8483        }
8484    }
8485
8486    @Override
8487    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8488        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8489                "createStackOnDisplay()");
8490        synchronized (this) {
8491            final int stackId = mStackSupervisor.getNextStackId();
8492            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8493            if (stack == null) {
8494                return null;
8495            }
8496            return stack.mActivityContainer;
8497        }
8498    }
8499
8500    @Override
8501    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8502        synchronized (this) {
8503            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8504            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8505                return stack.mActivityContainer.getDisplayId();
8506            }
8507            return Display.DEFAULT_DISPLAY;
8508        }
8509    }
8510
8511    @Override
8512    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8514                "moveTaskToStack()");
8515        if (stackId == HOME_STACK_ID) {
8516            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8517                    new RuntimeException("here").fillInStackTrace());
8518        }
8519        synchronized (this) {
8520            long ident = Binder.clearCallingIdentity();
8521            try {
8522                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8523                        + " to stackId=" + stackId + " toTop=" + toTop);
8524                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8525            } finally {
8526                Binder.restoreCallingIdentity(ident);
8527            }
8528        }
8529    }
8530
8531    @Override
8532    public void resizeStack(int stackId, Rect bounds) {
8533        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8534                "resizeStack()");
8535        long ident = Binder.clearCallingIdentity();
8536        try {
8537            synchronized (this) {
8538                mStackSupervisor.resizeStackLocked(stackId, bounds);
8539            }
8540        } finally {
8541            Binder.restoreCallingIdentity(ident);
8542        }
8543    }
8544
8545    @Override
8546    public List<StackInfo> getAllStackInfos() {
8547        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8548                "getAllStackInfos()");
8549        long ident = Binder.clearCallingIdentity();
8550        try {
8551            synchronized (this) {
8552                return mStackSupervisor.getAllStackInfosLocked();
8553            }
8554        } finally {
8555            Binder.restoreCallingIdentity(ident);
8556        }
8557    }
8558
8559    @Override
8560    public StackInfo getStackInfo(int stackId) {
8561        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8562                "getStackInfo()");
8563        long ident = Binder.clearCallingIdentity();
8564        try {
8565            synchronized (this) {
8566                return mStackSupervisor.getStackInfoLocked(stackId);
8567            }
8568        } finally {
8569            Binder.restoreCallingIdentity(ident);
8570        }
8571    }
8572
8573    @Override
8574    public boolean isInHomeStack(int taskId) {
8575        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8576                "getStackInfo()");
8577        long ident = Binder.clearCallingIdentity();
8578        try {
8579            synchronized (this) {
8580                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8581                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8582            }
8583        } finally {
8584            Binder.restoreCallingIdentity(ident);
8585        }
8586    }
8587
8588    @Override
8589    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8590        synchronized(this) {
8591            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8592        }
8593    }
8594
8595    @Override
8596    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId) {
8597        final int callingUid = Binder.getCallingUid();
8598        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8599            throw new SecurityException(
8600                    "updatePreferredSetupActivity called from non-system process");
8601        }
8602        synchronized (this) {
8603            if (preferredActivity == null) {
8604                mPreferredSetupActivities.delete(userId);
8605            } else {
8606                mPreferredSetupActivities.put(userId, preferredActivity);
8607            }
8608        }
8609    }
8610
8611    @Override
8612    public void updateDeviceOwner(String packageName) {
8613        final int callingUid = Binder.getCallingUid();
8614        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8615            throw new SecurityException("updateDeviceOwner called from non-system process");
8616        }
8617        synchronized (this) {
8618            mDeviceOwnerName = packageName;
8619        }
8620    }
8621
8622    @Override
8623    public void updateLockTaskPackages(int userId, String[] packages) {
8624        final int callingUid = Binder.getCallingUid();
8625        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8626            throw new SecurityException("updateLockTaskPackage called from non-system process");
8627        }
8628        synchronized (this) {
8629            mLockTaskPackages.put(userId, packages);
8630            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8631        }
8632    }
8633
8634
8635    void startLockTaskModeLocked(TaskRecord task) {
8636        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8637            return;
8638        }
8639
8640        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8641        // is initiated by system after the pinning request was shown and locked mode is initiated
8642        // by an authorized app directly
8643        final int callingUid = Binder.getCallingUid();
8644        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8645        long ident = Binder.clearCallingIdentity();
8646        try {
8647            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8648            if (!isSystemInitiated) {
8649                task.mLockTaskUid = callingUid;
8650                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8651                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8652                    StatusBarManagerInternal statusBarManager =
8653                            LocalServices.getService(StatusBarManagerInternal.class);
8654                    if (statusBarManager != null) {
8655                        statusBarManager.showScreenPinningRequest();
8656                    }
8657                    return;
8658                }
8659
8660                if (stack == null || task != stack.topTask()) {
8661                    throw new IllegalArgumentException("Invalid task, not in foreground");
8662                }
8663            }
8664            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8665                    ActivityManager.LOCK_TASK_MODE_PINNED :
8666                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8667                    "startLockTask");
8668        } finally {
8669            Binder.restoreCallingIdentity(ident);
8670        }
8671    }
8672
8673    @Override
8674    public void startLockTaskMode(int taskId) {
8675        synchronized (this) {
8676            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8677            if (task != null) {
8678                startLockTaskModeLocked(task);
8679            }
8680        }
8681    }
8682
8683    @Override
8684    public void startLockTaskMode(IBinder token) {
8685        synchronized (this) {
8686            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8687            if (r == null) {
8688                return;
8689            }
8690            final TaskRecord task = r.task;
8691            if (task != null) {
8692                startLockTaskModeLocked(task);
8693            }
8694        }
8695    }
8696
8697    @Override
8698    public void startLockTaskModeOnCurrent() throws RemoteException {
8699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8700                "startLockTaskModeOnCurrent");
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            synchronized (this) {
8704                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
8705                if (r != null) {
8706                    startLockTaskModeLocked(r.task);
8707                }
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public void stopLockTaskMode() {
8716        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
8717        if (lockTask == null) {
8718            // Our work here is done.
8719            return;
8720        }
8721        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
8722        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
8723                Binder.getCallingUid() != lockTask.mLockTaskUid) {
8724            throw new SecurityException("Invalid uid, expected " + lockTask.mLockTaskUid);
8725        }
8726        long ident = Binder.clearCallingIdentity();
8727        try {
8728            Log.d(TAG, "stopLockTaskMode");
8729            // Stop lock task
8730            synchronized (this) {
8731                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
8732                        "stopLockTask");
8733            }
8734        } finally {
8735            Binder.restoreCallingIdentity(ident);
8736        }
8737    }
8738
8739    @Override
8740    public void stopLockTaskModeOnCurrent() throws RemoteException {
8741        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8742                "stopLockTaskModeOnCurrent");
8743        long ident = Binder.clearCallingIdentity();
8744        try {
8745            stopLockTaskMode();
8746        } finally {
8747            Binder.restoreCallingIdentity(ident);
8748        }
8749    }
8750
8751    @Override
8752    public boolean isInLockTaskMode() {
8753        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
8754    }
8755
8756    @Override
8757    public int getLockTaskModeState() {
8758        synchronized (this) {
8759            return mStackSupervisor.getLockTaskModeState();
8760        }
8761    }
8762
8763    @Override
8764    public void showLockTaskEscapeMessage(IBinder token) {
8765        synchronized (this) {
8766            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8767            if (r == null) {
8768                return;
8769            }
8770            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
8771        }
8772    }
8773
8774    // =========================================================
8775    // CONTENT PROVIDERS
8776    // =========================================================
8777
8778    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8779        List<ProviderInfo> providers = null;
8780        try {
8781            providers = AppGlobals.getPackageManager().
8782                queryContentProviders(app.processName, app.uid,
8783                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8784        } catch (RemoteException ex) {
8785        }
8786        if (DEBUG_MU) Slog.v(TAG_MU,
8787                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8788        int userId = app.userId;
8789        if (providers != null) {
8790            int N = providers.size();
8791            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8792            for (int i=0; i<N; i++) {
8793                ProviderInfo cpi =
8794                    (ProviderInfo)providers.get(i);
8795                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8796                        cpi.name, cpi.flags);
8797                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
8798                    // This is a singleton provider, but a user besides the
8799                    // default user is asking to initialize a process it runs
8800                    // in...  well, no, it doesn't actually run in this process,
8801                    // it runs in the process of the default user.  Get rid of it.
8802                    providers.remove(i);
8803                    N--;
8804                    i--;
8805                    continue;
8806                }
8807
8808                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8809                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8810                if (cpr == null) {
8811                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8812                    mProviderMap.putProviderByClass(comp, cpr);
8813                }
8814                if (DEBUG_MU) Slog.v(TAG_MU,
8815                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8816                app.pubProviders.put(cpi.name, cpr);
8817                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8818                    // Don't add this if it is a platform component that is marked
8819                    // to run in multiple processes, because this is actually
8820                    // part of the framework so doesn't make sense to track as a
8821                    // separate apk in the process.
8822                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8823                            mProcessStats);
8824                }
8825                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8826            }
8827        }
8828        return providers;
8829    }
8830
8831    /**
8832     * Check if {@link ProcessRecord} has a possible chance at accessing the
8833     * given {@link ProviderInfo}. Final permission checking is always done
8834     * in {@link ContentProvider}.
8835     */
8836    private final String checkContentProviderPermissionLocked(
8837            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8838        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8839        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8840        boolean checkedGrants = false;
8841        if (checkUser) {
8842            // Looking for cross-user grants before enforcing the typical cross-users permissions
8843            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8844            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8845                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8846                    return null;
8847                }
8848                checkedGrants = true;
8849            }
8850            userId = handleIncomingUser(callingPid, callingUid, userId,
8851                    false, ALLOW_NON_FULL,
8852                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8853            if (userId != tmpTargetUserId) {
8854                // When we actually went to determine the final targer user ID, this ended
8855                // up different than our initial check for the authority.  This is because
8856                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8857                // SELF.  So we need to re-check the grants again.
8858                checkedGrants = false;
8859            }
8860        }
8861        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8862                cpi.applicationInfo.uid, cpi.exported)
8863                == PackageManager.PERMISSION_GRANTED) {
8864            return null;
8865        }
8866        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8867                cpi.applicationInfo.uid, cpi.exported)
8868                == PackageManager.PERMISSION_GRANTED) {
8869            return null;
8870        }
8871
8872        PathPermission[] pps = cpi.pathPermissions;
8873        if (pps != null) {
8874            int i = pps.length;
8875            while (i > 0) {
8876                i--;
8877                PathPermission pp = pps[i];
8878                String pprperm = pp.getReadPermission();
8879                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8880                        cpi.applicationInfo.uid, cpi.exported)
8881                        == PackageManager.PERMISSION_GRANTED) {
8882                    return null;
8883                }
8884                String ppwperm = pp.getWritePermission();
8885                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8886                        cpi.applicationInfo.uid, cpi.exported)
8887                        == PackageManager.PERMISSION_GRANTED) {
8888                    return null;
8889                }
8890            }
8891        }
8892        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8893            return null;
8894        }
8895
8896        String msg;
8897        if (!cpi.exported) {
8898            msg = "Permission Denial: opening provider " + cpi.name
8899                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8900                    + ", uid=" + callingUid + ") that is not exported from uid "
8901                    + cpi.applicationInfo.uid;
8902        } else {
8903            msg = "Permission Denial: opening provider " + cpi.name
8904                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8905                    + ", uid=" + callingUid + ") requires "
8906                    + cpi.readPermission + " or " + cpi.writePermission;
8907        }
8908        Slog.w(TAG, msg);
8909        return msg;
8910    }
8911
8912    /**
8913     * Returns if the ContentProvider has granted a uri to callingUid
8914     */
8915    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8916        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8917        if (perms != null) {
8918            for (int i=perms.size()-1; i>=0; i--) {
8919                GrantUri grantUri = perms.keyAt(i);
8920                if (grantUri.sourceUserId == userId || !checkUser) {
8921                    if (matchesProvider(grantUri.uri, cpi)) {
8922                        return true;
8923                    }
8924                }
8925            }
8926        }
8927        return false;
8928    }
8929
8930    /**
8931     * Returns true if the uri authority is one of the authorities specified in the provider.
8932     */
8933    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8934        String uriAuth = uri.getAuthority();
8935        String cpiAuth = cpi.authority;
8936        if (cpiAuth.indexOf(';') == -1) {
8937            return cpiAuth.equals(uriAuth);
8938        }
8939        String[] cpiAuths = cpiAuth.split(";");
8940        int length = cpiAuths.length;
8941        for (int i = 0; i < length; i++) {
8942            if (cpiAuths[i].equals(uriAuth)) return true;
8943        }
8944        return false;
8945    }
8946
8947    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8948            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8949        if (r != null) {
8950            for (int i=0; i<r.conProviders.size(); i++) {
8951                ContentProviderConnection conn = r.conProviders.get(i);
8952                if (conn.provider == cpr) {
8953                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
8954                            "Adding provider requested by "
8955                            + r.processName + " from process "
8956                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8957                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8958                    if (stable) {
8959                        conn.stableCount++;
8960                        conn.numStableIncs++;
8961                    } else {
8962                        conn.unstableCount++;
8963                        conn.numUnstableIncs++;
8964                    }
8965                    return conn;
8966                }
8967            }
8968            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8969            if (stable) {
8970                conn.stableCount = 1;
8971                conn.numStableIncs = 1;
8972            } else {
8973                conn.unstableCount = 1;
8974                conn.numUnstableIncs = 1;
8975            }
8976            cpr.connections.add(conn);
8977            r.conProviders.add(conn);
8978            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8979            return conn;
8980        }
8981        cpr.addExternalProcessHandleLocked(externalProcessToken);
8982        return null;
8983    }
8984
8985    boolean decProviderCountLocked(ContentProviderConnection conn,
8986            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8987        if (conn != null) {
8988            cpr = conn.provider;
8989            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
8990                    "Removing provider requested by "
8991                    + conn.client.processName + " from process "
8992                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8993                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8994            if (stable) {
8995                conn.stableCount--;
8996            } else {
8997                conn.unstableCount--;
8998            }
8999            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9000                cpr.connections.remove(conn);
9001                conn.client.conProviders.remove(conn);
9002                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9003                return true;
9004            }
9005            return false;
9006        }
9007        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9008        return false;
9009    }
9010
9011    private void checkTime(long startTime, String where) {
9012        long now = SystemClock.elapsedRealtime();
9013        if ((now-startTime) > 1000) {
9014            // If we are taking more than a second, log about it.
9015            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9016        }
9017    }
9018
9019    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9020            String name, IBinder token, boolean stable, int userId) {
9021        ContentProviderRecord cpr;
9022        ContentProviderConnection conn = null;
9023        ProviderInfo cpi = null;
9024
9025        synchronized(this) {
9026            long startTime = SystemClock.elapsedRealtime();
9027
9028            ProcessRecord r = null;
9029            if (caller != null) {
9030                r = getRecordForAppLocked(caller);
9031                if (r == null) {
9032                    throw new SecurityException(
9033                            "Unable to find app for caller " + caller
9034                          + " (pid=" + Binder.getCallingPid()
9035                          + ") when getting content provider " + name);
9036                }
9037            }
9038
9039            boolean checkCrossUser = true;
9040
9041            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9042
9043            // First check if this content provider has been published...
9044            cpr = mProviderMap.getProviderByName(name, userId);
9045            // If that didn't work, check if it exists for user 0 and then
9046            // verify that it's a singleton provider before using it.
9047            if (cpr == null && userId != UserHandle.USER_OWNER) {
9048                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9049                if (cpr != null) {
9050                    cpi = cpr.info;
9051                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9052                            cpi.name, cpi.flags)
9053                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9054                        userId = UserHandle.USER_OWNER;
9055                        checkCrossUser = false;
9056                    } else {
9057                        cpr = null;
9058                        cpi = null;
9059                    }
9060                }
9061            }
9062
9063            boolean providerRunning = cpr != null;
9064            if (providerRunning) {
9065                cpi = cpr.info;
9066                String msg;
9067                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9068                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9069                        != null) {
9070                    throw new SecurityException(msg);
9071                }
9072                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9073
9074                if (r != null && cpr.canRunHere(r)) {
9075                    // This provider has been published or is in the process
9076                    // of being published...  but it is also allowed to run
9077                    // in the caller's process, so don't make a connection
9078                    // and just let the caller instantiate its own instance.
9079                    ContentProviderHolder holder = cpr.newHolder(null);
9080                    // don't give caller the provider object, it needs
9081                    // to make its own.
9082                    holder.provider = null;
9083                    return holder;
9084                }
9085
9086                final long origId = Binder.clearCallingIdentity();
9087
9088                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9089
9090                // In this case the provider instance already exists, so we can
9091                // return it right away.
9092                conn = incProviderCountLocked(r, cpr, token, stable);
9093                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9094                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9095                        // If this is a perceptible app accessing the provider,
9096                        // make sure to count it as being accessed and thus
9097                        // back up on the LRU list.  This is good because
9098                        // content providers are often expensive to start.
9099                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9100                        updateLruProcessLocked(cpr.proc, false, null);
9101                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9102                    }
9103                }
9104
9105                if (cpr.proc != null) {
9106                    if (false) {
9107                        if (cpr.name.flattenToShortString().equals(
9108                                "com.android.providers.calendar/.CalendarProvider2")) {
9109                            Slog.v(TAG, "****************** KILLING "
9110                                + cpr.name.flattenToShortString());
9111                            Process.killProcess(cpr.proc.pid);
9112                        }
9113                    }
9114                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9115                    boolean success = updateOomAdjLocked(cpr.proc);
9116                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9117                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9118                    // NOTE: there is still a race here where a signal could be
9119                    // pending on the process even though we managed to update its
9120                    // adj level.  Not sure what to do about this, but at least
9121                    // the race is now smaller.
9122                    if (!success) {
9123                        // Uh oh...  it looks like the provider's process
9124                        // has been killed on us.  We need to wait for a new
9125                        // process to be started, and make sure its death
9126                        // doesn't kill our process.
9127                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9128                                + " is crashing; detaching " + r);
9129                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9130                        checkTime(startTime, "getContentProviderImpl: before appDied");
9131                        appDiedLocked(cpr.proc);
9132                        checkTime(startTime, "getContentProviderImpl: after appDied");
9133                        if (!lastRef) {
9134                            // This wasn't the last ref our process had on
9135                            // the provider...  we have now been killed, bail.
9136                            return null;
9137                        }
9138                        providerRunning = false;
9139                        conn = null;
9140                    }
9141                }
9142
9143                Binder.restoreCallingIdentity(origId);
9144            }
9145
9146            boolean singleton;
9147            if (!providerRunning) {
9148                try {
9149                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9150                    cpi = AppGlobals.getPackageManager().
9151                        resolveContentProvider(name,
9152                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9153                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9154                } catch (RemoteException ex) {
9155                }
9156                if (cpi == null) {
9157                    return null;
9158                }
9159                // If the provider is a singleton AND
9160                // (it's a call within the same user || the provider is a
9161                // privileged app)
9162                // Then allow connecting to the singleton provider
9163                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9164                        cpi.name, cpi.flags)
9165                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9166                if (singleton) {
9167                    userId = UserHandle.USER_OWNER;
9168                }
9169                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9170                checkTime(startTime, "getContentProviderImpl: got app info for user");
9171
9172                String msg;
9173                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9174                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9175                        != null) {
9176                    throw new SecurityException(msg);
9177                }
9178                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9179
9180                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9181                        && !cpi.processName.equals("system")) {
9182                    // If this content provider does not run in the system
9183                    // process, and the system is not yet ready to run other
9184                    // processes, then fail fast instead of hanging.
9185                    throw new IllegalArgumentException(
9186                            "Attempt to launch content provider before system ready");
9187                }
9188
9189                // Make sure that the user who owns this provider is running.  If not,
9190                // we don't want to allow it to run.
9191                if (!isUserRunningLocked(userId, false)) {
9192                    Slog.w(TAG, "Unable to launch app "
9193                            + cpi.applicationInfo.packageName + "/"
9194                            + cpi.applicationInfo.uid + " for provider "
9195                            + name + ": user " + userId + " is stopped");
9196                    return null;
9197                }
9198
9199                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9200                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9201                cpr = mProviderMap.getProviderByClass(comp, userId);
9202                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9203                final boolean firstClass = cpr == null;
9204                if (firstClass) {
9205                    final long ident = Binder.clearCallingIdentity();
9206                    try {
9207                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9208                        ApplicationInfo ai =
9209                            AppGlobals.getPackageManager().
9210                                getApplicationInfo(
9211                                        cpi.applicationInfo.packageName,
9212                                        STOCK_PM_FLAGS, userId);
9213                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9214                        if (ai == null) {
9215                            Slog.w(TAG, "No package info for content provider "
9216                                    + cpi.name);
9217                            return null;
9218                        }
9219                        ai = getAppInfoForUser(ai, userId);
9220                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9221                    } catch (RemoteException ex) {
9222                        // pm is in same process, this will never happen.
9223                    } finally {
9224                        Binder.restoreCallingIdentity(ident);
9225                    }
9226                }
9227
9228                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9229
9230                if (r != null && cpr.canRunHere(r)) {
9231                    // If this is a multiprocess provider, then just return its
9232                    // info and allow the caller to instantiate it.  Only do
9233                    // this if the provider is the same user as the caller's
9234                    // process, or can run as root (so can be in any process).
9235                    return cpr.newHolder(null);
9236                }
9237
9238                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9239                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9240                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9241
9242                // This is single process, and our app is now connecting to it.
9243                // See if we are already in the process of launching this
9244                // provider.
9245                final int N = mLaunchingProviders.size();
9246                int i;
9247                for (i = 0; i < N; i++) {
9248                    if (mLaunchingProviders.get(i) == cpr) {
9249                        break;
9250                    }
9251                }
9252
9253                // If the provider is not already being launched, then get it
9254                // started.
9255                if (i >= N) {
9256                    final long origId = Binder.clearCallingIdentity();
9257
9258                    try {
9259                        // Content provider is now in use, its package can't be stopped.
9260                        try {
9261                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9262                            AppGlobals.getPackageManager().setPackageStoppedState(
9263                                    cpr.appInfo.packageName, false, userId);
9264                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9265                        } catch (RemoteException e) {
9266                        } catch (IllegalArgumentException e) {
9267                            Slog.w(TAG, "Failed trying to unstop package "
9268                                    + cpr.appInfo.packageName + ": " + e);
9269                        }
9270
9271                        // Use existing process if already started
9272                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9273                        ProcessRecord proc = getProcessRecordLocked(
9274                                cpi.processName, cpr.appInfo.uid, false);
9275                        if (proc != null && proc.thread != null) {
9276                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9277                                    "Installing in existing process " + proc);
9278                            if (!proc.pubProviders.containsKey(cpi.name)) {
9279                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9280                                proc.pubProviders.put(cpi.name, cpr);
9281                                try {
9282                                    proc.thread.scheduleInstallProvider(cpi);
9283                                } catch (RemoteException e) {
9284                                }
9285                            }
9286                        } else {
9287                            checkTime(startTime, "getContentProviderImpl: before start process");
9288                            proc = startProcessLocked(cpi.processName,
9289                                    cpr.appInfo, false, 0, "content provider",
9290                                    new ComponentName(cpi.applicationInfo.packageName,
9291                                            cpi.name), false, false, false);
9292                            checkTime(startTime, "getContentProviderImpl: after start process");
9293                            if (proc == null) {
9294                                Slog.w(TAG, "Unable to launch app "
9295                                        + cpi.applicationInfo.packageName + "/"
9296                                        + cpi.applicationInfo.uid + " for provider "
9297                                        + name + ": process is bad");
9298                                return null;
9299                            }
9300                        }
9301                        cpr.launchingApp = proc;
9302                        mLaunchingProviders.add(cpr);
9303                    } finally {
9304                        Binder.restoreCallingIdentity(origId);
9305                    }
9306                }
9307
9308                checkTime(startTime, "getContentProviderImpl: updating data structures");
9309
9310                // Make sure the provider is published (the same provider class
9311                // may be published under multiple names).
9312                if (firstClass) {
9313                    mProviderMap.putProviderByClass(comp, cpr);
9314                }
9315
9316                mProviderMap.putProviderByName(name, cpr);
9317                conn = incProviderCountLocked(r, cpr, token, stable);
9318                if (conn != null) {
9319                    conn.waiting = true;
9320                }
9321            }
9322            checkTime(startTime, "getContentProviderImpl: done!");
9323        }
9324
9325        // Wait for the provider to be published...
9326        synchronized (cpr) {
9327            while (cpr.provider == null) {
9328                if (cpr.launchingApp == null) {
9329                    Slog.w(TAG, "Unable to launch app "
9330                            + cpi.applicationInfo.packageName + "/"
9331                            + cpi.applicationInfo.uid + " for provider "
9332                            + name + ": launching app became null");
9333                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9334                            UserHandle.getUserId(cpi.applicationInfo.uid),
9335                            cpi.applicationInfo.packageName,
9336                            cpi.applicationInfo.uid, name);
9337                    return null;
9338                }
9339                try {
9340                    if (DEBUG_MU) Slog.v(TAG_MU,
9341                            "Waiting to start provider " + cpr
9342                            + " launchingApp=" + cpr.launchingApp);
9343                    if (conn != null) {
9344                        conn.waiting = true;
9345                    }
9346                    cpr.wait();
9347                } catch (InterruptedException ex) {
9348                } finally {
9349                    if (conn != null) {
9350                        conn.waiting = false;
9351                    }
9352                }
9353            }
9354        }
9355        return cpr != null ? cpr.newHolder(conn) : null;
9356    }
9357
9358    @Override
9359    public final ContentProviderHolder getContentProvider(
9360            IApplicationThread caller, String name, int userId, boolean stable) {
9361        enforceNotIsolatedCaller("getContentProvider");
9362        if (caller == null) {
9363            String msg = "null IApplicationThread when getting content provider "
9364                    + name;
9365            Slog.w(TAG, msg);
9366            throw new SecurityException(msg);
9367        }
9368        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9369        // with cross-user grant.
9370        return getContentProviderImpl(caller, name, null, stable, userId);
9371    }
9372
9373    public ContentProviderHolder getContentProviderExternal(
9374            String name, int userId, IBinder token) {
9375        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9376            "Do not have permission in call getContentProviderExternal()");
9377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9378                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9379        return getContentProviderExternalUnchecked(name, token, userId);
9380    }
9381
9382    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9383            IBinder token, int userId) {
9384        return getContentProviderImpl(null, name, token, true, userId);
9385    }
9386
9387    /**
9388     * Drop a content provider from a ProcessRecord's bookkeeping
9389     */
9390    public void removeContentProvider(IBinder connection, boolean stable) {
9391        enforceNotIsolatedCaller("removeContentProvider");
9392        long ident = Binder.clearCallingIdentity();
9393        try {
9394            synchronized (this) {
9395                ContentProviderConnection conn;
9396                try {
9397                    conn = (ContentProviderConnection)connection;
9398                } catch (ClassCastException e) {
9399                    String msg ="removeContentProvider: " + connection
9400                            + " not a ContentProviderConnection";
9401                    Slog.w(TAG, msg);
9402                    throw new IllegalArgumentException(msg);
9403                }
9404                if (conn == null) {
9405                    throw new NullPointerException("connection is null");
9406                }
9407                if (decProviderCountLocked(conn, null, null, stable)) {
9408                    updateOomAdjLocked();
9409                }
9410            }
9411        } finally {
9412            Binder.restoreCallingIdentity(ident);
9413        }
9414    }
9415
9416    public void removeContentProviderExternal(String name, IBinder token) {
9417        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9418            "Do not have permission in call removeContentProviderExternal()");
9419        int userId = UserHandle.getCallingUserId();
9420        long ident = Binder.clearCallingIdentity();
9421        try {
9422            removeContentProviderExternalUnchecked(name, token, userId);
9423        } finally {
9424            Binder.restoreCallingIdentity(ident);
9425        }
9426    }
9427
9428    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9429        synchronized (this) {
9430            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9431            if(cpr == null) {
9432                //remove from mProvidersByClass
9433                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9434                return;
9435            }
9436
9437            //update content provider record entry info
9438            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9439            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9440            if (localCpr.hasExternalProcessHandles()) {
9441                if (localCpr.removeExternalProcessHandleLocked(token)) {
9442                    updateOomAdjLocked();
9443                } else {
9444                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9445                            + " with no external reference for token: "
9446                            + token + ".");
9447                }
9448            } else {
9449                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9450                        + " with no external references.");
9451            }
9452        }
9453    }
9454
9455    public final void publishContentProviders(IApplicationThread caller,
9456            List<ContentProviderHolder> providers) {
9457        if (providers == null) {
9458            return;
9459        }
9460
9461        enforceNotIsolatedCaller("publishContentProviders");
9462        synchronized (this) {
9463            final ProcessRecord r = getRecordForAppLocked(caller);
9464            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9465            if (r == null) {
9466                throw new SecurityException(
9467                        "Unable to find app for caller " + caller
9468                      + " (pid=" + Binder.getCallingPid()
9469                      + ") when publishing content providers");
9470            }
9471
9472            final long origId = Binder.clearCallingIdentity();
9473
9474            final int N = providers.size();
9475            for (int i=0; i<N; i++) {
9476                ContentProviderHolder src = providers.get(i);
9477                if (src == null || src.info == null || src.provider == null) {
9478                    continue;
9479                }
9480                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9481                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9482                if (dst != null) {
9483                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9484                    mProviderMap.putProviderByClass(comp, dst);
9485                    String names[] = dst.info.authority.split(";");
9486                    for (int j = 0; j < names.length; j++) {
9487                        mProviderMap.putProviderByName(names[j], dst);
9488                    }
9489
9490                    int NL = mLaunchingProviders.size();
9491                    int j;
9492                    for (j=0; j<NL; j++) {
9493                        if (mLaunchingProviders.get(j) == dst) {
9494                            mLaunchingProviders.remove(j);
9495                            j--;
9496                            NL--;
9497                        }
9498                    }
9499                    synchronized (dst) {
9500                        dst.provider = src.provider;
9501                        dst.proc = r;
9502                        dst.notifyAll();
9503                    }
9504                    updateOomAdjLocked(r);
9505                }
9506            }
9507
9508            Binder.restoreCallingIdentity(origId);
9509        }
9510    }
9511
9512    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9513        ContentProviderConnection conn;
9514        try {
9515            conn = (ContentProviderConnection)connection;
9516        } catch (ClassCastException e) {
9517            String msg ="refContentProvider: " + connection
9518                    + " not a ContentProviderConnection";
9519            Slog.w(TAG, msg);
9520            throw new IllegalArgumentException(msg);
9521        }
9522        if (conn == null) {
9523            throw new NullPointerException("connection is null");
9524        }
9525
9526        synchronized (this) {
9527            if (stable > 0) {
9528                conn.numStableIncs += stable;
9529            }
9530            stable = conn.stableCount + stable;
9531            if (stable < 0) {
9532                throw new IllegalStateException("stableCount < 0: " + stable);
9533            }
9534
9535            if (unstable > 0) {
9536                conn.numUnstableIncs += unstable;
9537            }
9538            unstable = conn.unstableCount + unstable;
9539            if (unstable < 0) {
9540                throw new IllegalStateException("unstableCount < 0: " + unstable);
9541            }
9542
9543            if ((stable+unstable) <= 0) {
9544                throw new IllegalStateException("ref counts can't go to zero here: stable="
9545                        + stable + " unstable=" + unstable);
9546            }
9547            conn.stableCount = stable;
9548            conn.unstableCount = unstable;
9549            return !conn.dead;
9550        }
9551    }
9552
9553    public void unstableProviderDied(IBinder connection) {
9554        ContentProviderConnection conn;
9555        try {
9556            conn = (ContentProviderConnection)connection;
9557        } catch (ClassCastException e) {
9558            String msg ="refContentProvider: " + connection
9559                    + " not a ContentProviderConnection";
9560            Slog.w(TAG, msg);
9561            throw new IllegalArgumentException(msg);
9562        }
9563        if (conn == null) {
9564            throw new NullPointerException("connection is null");
9565        }
9566
9567        // Safely retrieve the content provider associated with the connection.
9568        IContentProvider provider;
9569        synchronized (this) {
9570            provider = conn.provider.provider;
9571        }
9572
9573        if (provider == null) {
9574            // Um, yeah, we're way ahead of you.
9575            return;
9576        }
9577
9578        // Make sure the caller is being honest with us.
9579        if (provider.asBinder().pingBinder()) {
9580            // Er, no, still looks good to us.
9581            synchronized (this) {
9582                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9583                        + " says " + conn + " died, but we don't agree");
9584                return;
9585            }
9586        }
9587
9588        // Well look at that!  It's dead!
9589        synchronized (this) {
9590            if (conn.provider.provider != provider) {
9591                // But something changed...  good enough.
9592                return;
9593            }
9594
9595            ProcessRecord proc = conn.provider.proc;
9596            if (proc == null || proc.thread == null) {
9597                // Seems like the process is already cleaned up.
9598                return;
9599            }
9600
9601            // As far as we're concerned, this is just like receiving a
9602            // death notification...  just a bit prematurely.
9603            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9604                    + ") early provider death");
9605            final long ident = Binder.clearCallingIdentity();
9606            try {
9607                appDiedLocked(proc);
9608            } finally {
9609                Binder.restoreCallingIdentity(ident);
9610            }
9611        }
9612    }
9613
9614    @Override
9615    public void appNotRespondingViaProvider(IBinder connection) {
9616        enforceCallingPermission(
9617                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9618
9619        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9620        if (conn == null) {
9621            Slog.w(TAG, "ContentProviderConnection is null");
9622            return;
9623        }
9624
9625        final ProcessRecord host = conn.provider.proc;
9626        if (host == null) {
9627            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9628            return;
9629        }
9630
9631        final long token = Binder.clearCallingIdentity();
9632        try {
9633            appNotResponding(host, null, null, false, "ContentProvider not responding");
9634        } finally {
9635            Binder.restoreCallingIdentity(token);
9636        }
9637    }
9638
9639    public final void installSystemProviders() {
9640        List<ProviderInfo> providers;
9641        synchronized (this) {
9642            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9643            providers = generateApplicationProvidersLocked(app);
9644            if (providers != null) {
9645                for (int i=providers.size()-1; i>=0; i--) {
9646                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9647                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9648                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9649                                + ": not system .apk");
9650                        providers.remove(i);
9651                    }
9652                }
9653            }
9654        }
9655        if (providers != null) {
9656            mSystemThread.installSystemProviders(providers);
9657        }
9658
9659        mCoreSettingsObserver = new CoreSettingsObserver(this);
9660
9661        //mUsageStatsService.monitorPackages();
9662    }
9663
9664    /**
9665     * Allows apps to retrieve the MIME type of a URI.
9666     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9667     * users, then it does not need permission to access the ContentProvider.
9668     * Either, it needs cross-user uri grants.
9669     *
9670     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9671     *
9672     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9673     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9674     */
9675    public String getProviderMimeType(Uri uri, int userId) {
9676        enforceNotIsolatedCaller("getProviderMimeType");
9677        final String name = uri.getAuthority();
9678        int callingUid = Binder.getCallingUid();
9679        int callingPid = Binder.getCallingPid();
9680        long ident = 0;
9681        boolean clearedIdentity = false;
9682        userId = unsafeConvertIncomingUser(userId);
9683        if (canClearIdentity(callingPid, callingUid, userId)) {
9684            clearedIdentity = true;
9685            ident = Binder.clearCallingIdentity();
9686        }
9687        ContentProviderHolder holder = null;
9688        try {
9689            holder = getContentProviderExternalUnchecked(name, null, userId);
9690            if (holder != null) {
9691                return holder.provider.getType(uri);
9692            }
9693        } catch (RemoteException e) {
9694            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9695            return null;
9696        } finally {
9697            // We need to clear the identity to call removeContentProviderExternalUnchecked
9698            if (!clearedIdentity) {
9699                ident = Binder.clearCallingIdentity();
9700            }
9701            try {
9702                if (holder != null) {
9703                    removeContentProviderExternalUnchecked(name, null, userId);
9704                }
9705            } finally {
9706                Binder.restoreCallingIdentity(ident);
9707            }
9708        }
9709
9710        return null;
9711    }
9712
9713    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9714        if (UserHandle.getUserId(callingUid) == userId) {
9715            return true;
9716        }
9717        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9718                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9719                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9720                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9721                return true;
9722        }
9723        return false;
9724    }
9725
9726    // =========================================================
9727    // GLOBAL MANAGEMENT
9728    // =========================================================
9729
9730    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9731            boolean isolated, int isolatedUid) {
9732        String proc = customProcess != null ? customProcess : info.processName;
9733        BatteryStatsImpl.Uid.Proc ps = null;
9734        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9735        int uid = info.uid;
9736        if (isolated) {
9737            if (isolatedUid == 0) {
9738                int userId = UserHandle.getUserId(uid);
9739                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9740                while (true) {
9741                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9742                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9743                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9744                    }
9745                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9746                    mNextIsolatedProcessUid++;
9747                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9748                        // No process for this uid, use it.
9749                        break;
9750                    }
9751                    stepsLeft--;
9752                    if (stepsLeft <= 0) {
9753                        return null;
9754                    }
9755                }
9756            } else {
9757                // Special case for startIsolatedProcess (internal only), where
9758                // the uid of the isolated process is specified by the caller.
9759                uid = isolatedUid;
9760            }
9761        }
9762        return new ProcessRecord(stats, info, proc, uid);
9763    }
9764
9765    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9766            String abiOverride) {
9767        ProcessRecord app;
9768        if (!isolated) {
9769            app = getProcessRecordLocked(info.processName, info.uid, true);
9770        } else {
9771            app = null;
9772        }
9773
9774        if (app == null) {
9775            app = newProcessRecordLocked(info, null, isolated, 0);
9776            mProcessNames.put(info.processName, app.uid, app);
9777            if (isolated) {
9778                mIsolatedProcesses.put(app.uid, app);
9779            }
9780            updateLruProcessLocked(app, false, null);
9781            updateOomAdjLocked();
9782        }
9783
9784        // This package really, really can not be stopped.
9785        try {
9786            AppGlobals.getPackageManager().setPackageStoppedState(
9787                    info.packageName, false, UserHandle.getUserId(app.uid));
9788        } catch (RemoteException e) {
9789        } catch (IllegalArgumentException e) {
9790            Slog.w(TAG, "Failed trying to unstop package "
9791                    + info.packageName + ": " + e);
9792        }
9793
9794        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9795                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9796            app.persistent = true;
9797            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9798        }
9799        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9800            mPersistentStartingProcesses.add(app);
9801            startProcessLocked(app, "added application", app.processName, abiOverride,
9802                    null /* entryPoint */, null /* entryPointArgs */);
9803        }
9804
9805        return app;
9806    }
9807
9808    public void unhandledBack() {
9809        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9810                "unhandledBack()");
9811
9812        synchronized(this) {
9813            final long origId = Binder.clearCallingIdentity();
9814            try {
9815                getFocusedStack().unhandledBackLocked();
9816            } finally {
9817                Binder.restoreCallingIdentity(origId);
9818            }
9819        }
9820    }
9821
9822    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9823        enforceNotIsolatedCaller("openContentUri");
9824        final int userId = UserHandle.getCallingUserId();
9825        String name = uri.getAuthority();
9826        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9827        ParcelFileDescriptor pfd = null;
9828        if (cph != null) {
9829            // We record the binder invoker's uid in thread-local storage before
9830            // going to the content provider to open the file.  Later, in the code
9831            // that handles all permissions checks, we look for this uid and use
9832            // that rather than the Activity Manager's own uid.  The effect is that
9833            // we do the check against the caller's permissions even though it looks
9834            // to the content provider like the Activity Manager itself is making
9835            // the request.
9836            Binder token = new Binder();
9837            sCallerIdentity.set(new Identity(
9838                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9839            try {
9840                pfd = cph.provider.openFile(null, uri, "r", null, token);
9841            } catch (FileNotFoundException e) {
9842                // do nothing; pfd will be returned null
9843            } finally {
9844                // Ensure that whatever happens, we clean up the identity state
9845                sCallerIdentity.remove();
9846                // Ensure we're done with the provider.
9847                removeContentProviderExternalUnchecked(name, null, userId);
9848            }
9849        } else {
9850            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9851        }
9852        return pfd;
9853    }
9854
9855    // Actually is sleeping or shutting down or whatever else in the future
9856    // is an inactive state.
9857    public boolean isSleepingOrShuttingDown() {
9858        return isSleeping() || mShuttingDown;
9859    }
9860
9861    public boolean isSleeping() {
9862        return mSleeping;
9863    }
9864
9865    void onWakefulnessChanged(int wakefulness) {
9866        synchronized(this) {
9867            mWakefulness = wakefulness;
9868            updateSleepIfNeededLocked();
9869        }
9870    }
9871
9872    void finishRunningVoiceLocked() {
9873        if (mRunningVoice != null) {
9874            mRunningVoice = null;
9875            updateSleepIfNeededLocked();
9876        }
9877    }
9878
9879    void updateSleepIfNeededLocked() {
9880        if (mSleeping && !shouldSleepLocked()) {
9881            mSleeping = false;
9882            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
9883            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9884            updateOomAdjLocked();
9885        } else if (!mSleeping && shouldSleepLocked()) {
9886            mSleeping = true;
9887            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
9888            mStackSupervisor.goingToSleepLocked();
9889            updateOomAdjLocked();
9890
9891            // Initialize the wake times of all processes.
9892            checkExcessivePowerUsageLocked(false);
9893            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9894            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9895            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9896        }
9897    }
9898
9899    private boolean shouldSleepLocked() {
9900        // Resume applications while running a voice interactor.
9901        if (mRunningVoice != null) {
9902            return false;
9903        }
9904
9905        // TODO: Transform the lock screen state into a sleep token instead.
9906        switch (mWakefulness) {
9907            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9908            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9909            case PowerManagerInternal.WAKEFULNESS_DOZING:
9910                // Pause applications whenever the lock screen is shown or any sleep
9911                // tokens have been acquired.
9912                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
9913            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9914            default:
9915                // If we're asleep then pause applications unconditionally.
9916                return true;
9917        }
9918    }
9919
9920    /** Pokes the task persister. */
9921    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9922        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9923            // Never persist the home stack.
9924            return;
9925        }
9926        mTaskPersister.wakeup(task, flush);
9927    }
9928
9929    /** Notifies all listeners when the task stack has changed. */
9930    void notifyTaskStackChangedLocked() {
9931        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9932        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9933        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9934    }
9935
9936    @Override
9937    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9938        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9939    }
9940
9941    @Override
9942    public boolean shutdown(int timeout) {
9943        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9944                != PackageManager.PERMISSION_GRANTED) {
9945            throw new SecurityException("Requires permission "
9946                    + android.Manifest.permission.SHUTDOWN);
9947        }
9948
9949        boolean timedout = false;
9950
9951        synchronized(this) {
9952            mShuttingDown = true;
9953            updateEventDispatchingLocked();
9954            timedout = mStackSupervisor.shutdownLocked(timeout);
9955        }
9956
9957        mAppOpsService.shutdown();
9958        if (mUsageStatsService != null) {
9959            mUsageStatsService.prepareShutdown();
9960        }
9961        mBatteryStatsService.shutdown();
9962        synchronized (this) {
9963            mProcessStats.shutdownLocked();
9964            notifyTaskPersisterLocked(null, true);
9965        }
9966
9967        return timedout;
9968    }
9969
9970    public final void activitySlept(IBinder token) {
9971        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
9972
9973        final long origId = Binder.clearCallingIdentity();
9974
9975        synchronized (this) {
9976            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9977            if (r != null) {
9978                mStackSupervisor.activitySleptLocked(r);
9979            }
9980        }
9981
9982        Binder.restoreCallingIdentity(origId);
9983    }
9984
9985    private String lockScreenShownToString() {
9986        switch (mLockScreenShown) {
9987            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9988            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9989            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9990            default: return "Unknown=" + mLockScreenShown;
9991        }
9992    }
9993
9994    void logLockScreen(String msg) {
9995        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
9996                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9997                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9998                + " mSleeping=" + mSleeping);
9999    }
10000
10001    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10002        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10003        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10004            if (mRunningVoice == null) {
10005                mVoiceWakeLock.acquire();
10006                updateSleepIfNeededLocked();
10007            }
10008            mRunningVoice = session;
10009        }
10010    }
10011
10012    private void updateEventDispatchingLocked() {
10013        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10014    }
10015
10016    public void setLockScreenShown(boolean shown) {
10017        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10018                != PackageManager.PERMISSION_GRANTED) {
10019            throw new SecurityException("Requires permission "
10020                    + android.Manifest.permission.DEVICE_POWER);
10021        }
10022
10023        synchronized(this) {
10024            long ident = Binder.clearCallingIdentity();
10025            try {
10026                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10027                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10028                updateSleepIfNeededLocked();
10029            } finally {
10030                Binder.restoreCallingIdentity(ident);
10031            }
10032        }
10033    }
10034
10035    @Override
10036    public void stopAppSwitches() {
10037        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10038                != PackageManager.PERMISSION_GRANTED) {
10039            throw new SecurityException("Requires permission "
10040                    + android.Manifest.permission.STOP_APP_SWITCHES);
10041        }
10042
10043        synchronized(this) {
10044            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10045                    + APP_SWITCH_DELAY_TIME;
10046            mDidAppSwitch = false;
10047            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10048            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10049            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10050        }
10051    }
10052
10053    public void resumeAppSwitches() {
10054        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10055                != PackageManager.PERMISSION_GRANTED) {
10056            throw new SecurityException("Requires permission "
10057                    + android.Manifest.permission.STOP_APP_SWITCHES);
10058        }
10059
10060        synchronized(this) {
10061            // Note that we don't execute any pending app switches... we will
10062            // let those wait until either the timeout, or the next start
10063            // activity request.
10064            mAppSwitchesAllowedTime = 0;
10065        }
10066    }
10067
10068    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10069            int callingPid, int callingUid, String name) {
10070        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10071            return true;
10072        }
10073
10074        int perm = checkComponentPermission(
10075                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10076                sourceUid, -1, true);
10077        if (perm == PackageManager.PERMISSION_GRANTED) {
10078            return true;
10079        }
10080
10081        // If the actual IPC caller is different from the logical source, then
10082        // also see if they are allowed to control app switches.
10083        if (callingUid != -1 && callingUid != sourceUid) {
10084            perm = checkComponentPermission(
10085                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10086                    callingUid, -1, true);
10087            if (perm == PackageManager.PERMISSION_GRANTED) {
10088                return true;
10089            }
10090        }
10091
10092        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10093        return false;
10094    }
10095
10096    public void setDebugApp(String packageName, boolean waitForDebugger,
10097            boolean persistent) {
10098        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10099                "setDebugApp()");
10100
10101        long ident = Binder.clearCallingIdentity();
10102        try {
10103            // Note that this is not really thread safe if there are multiple
10104            // callers into it at the same time, but that's not a situation we
10105            // care about.
10106            if (persistent) {
10107                final ContentResolver resolver = mContext.getContentResolver();
10108                Settings.Global.putString(
10109                    resolver, Settings.Global.DEBUG_APP,
10110                    packageName);
10111                Settings.Global.putInt(
10112                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10113                    waitForDebugger ? 1 : 0);
10114            }
10115
10116            synchronized (this) {
10117                if (!persistent) {
10118                    mOrigDebugApp = mDebugApp;
10119                    mOrigWaitForDebugger = mWaitForDebugger;
10120                }
10121                mDebugApp = packageName;
10122                mWaitForDebugger = waitForDebugger;
10123                mDebugTransient = !persistent;
10124                if (packageName != null) {
10125                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10126                            false, UserHandle.USER_ALL, "set debug app");
10127                }
10128            }
10129        } finally {
10130            Binder.restoreCallingIdentity(ident);
10131        }
10132    }
10133
10134    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10135        synchronized (this) {
10136            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10137            if (!isDebuggable) {
10138                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10139                    throw new SecurityException("Process not debuggable: " + app.packageName);
10140                }
10141            }
10142
10143            mOpenGlTraceApp = processName;
10144        }
10145    }
10146
10147    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10148        synchronized (this) {
10149            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10150            if (!isDebuggable) {
10151                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10152                    throw new SecurityException("Process not debuggable: " + app.packageName);
10153                }
10154            }
10155            mProfileApp = processName;
10156            mProfileFile = profilerInfo.profileFile;
10157            if (mProfileFd != null) {
10158                try {
10159                    mProfileFd.close();
10160                } catch (IOException e) {
10161                }
10162                mProfileFd = null;
10163            }
10164            mProfileFd = profilerInfo.profileFd;
10165            mSamplingInterval = profilerInfo.samplingInterval;
10166            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10167            mProfileType = 0;
10168        }
10169    }
10170
10171    @Override
10172    public void setAlwaysFinish(boolean enabled) {
10173        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10174                "setAlwaysFinish()");
10175
10176        Settings.Global.putInt(
10177                mContext.getContentResolver(),
10178                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10179
10180        synchronized (this) {
10181            mAlwaysFinishActivities = enabled;
10182        }
10183    }
10184
10185    @Override
10186    public void setActivityController(IActivityController controller) {
10187        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10188                "setActivityController()");
10189        synchronized (this) {
10190            mController = controller;
10191            Watchdog.getInstance().setActivityController(controller);
10192        }
10193    }
10194
10195    @Override
10196    public void setUserIsMonkey(boolean userIsMonkey) {
10197        synchronized (this) {
10198            synchronized (mPidsSelfLocked) {
10199                final int callingPid = Binder.getCallingPid();
10200                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10201                if (precessRecord == null) {
10202                    throw new SecurityException("Unknown process: " + callingPid);
10203                }
10204                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10205                    throw new SecurityException("Only an instrumentation process "
10206                            + "with a UiAutomation can call setUserIsMonkey");
10207                }
10208            }
10209            mUserIsMonkey = userIsMonkey;
10210        }
10211    }
10212
10213    @Override
10214    public boolean isUserAMonkey() {
10215        synchronized (this) {
10216            // If there is a controller also implies the user is a monkey.
10217            return (mUserIsMonkey || mController != null);
10218        }
10219    }
10220
10221    public void requestBugReport() {
10222        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10223        SystemProperties.set("ctl.start", "bugreport");
10224    }
10225
10226    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10227        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10228    }
10229
10230    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10231        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10232            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10233        }
10234        return KEY_DISPATCHING_TIMEOUT;
10235    }
10236
10237    @Override
10238    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10239        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10240                != PackageManager.PERMISSION_GRANTED) {
10241            throw new SecurityException("Requires permission "
10242                    + android.Manifest.permission.FILTER_EVENTS);
10243        }
10244        ProcessRecord proc;
10245        long timeout;
10246        synchronized (this) {
10247            synchronized (mPidsSelfLocked) {
10248                proc = mPidsSelfLocked.get(pid);
10249            }
10250            timeout = getInputDispatchingTimeoutLocked(proc);
10251        }
10252
10253        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10254            return -1;
10255        }
10256
10257        return timeout;
10258    }
10259
10260    /**
10261     * Handle input dispatching timeouts.
10262     * Returns whether input dispatching should be aborted or not.
10263     */
10264    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10265            final ActivityRecord activity, final ActivityRecord parent,
10266            final boolean aboveSystem, String reason) {
10267        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10268                != PackageManager.PERMISSION_GRANTED) {
10269            throw new SecurityException("Requires permission "
10270                    + android.Manifest.permission.FILTER_EVENTS);
10271        }
10272
10273        final String annotation;
10274        if (reason == null) {
10275            annotation = "Input dispatching timed out";
10276        } else {
10277            annotation = "Input dispatching timed out (" + reason + ")";
10278        }
10279
10280        if (proc != null) {
10281            synchronized (this) {
10282                if (proc.debugging) {
10283                    return false;
10284                }
10285
10286                if (mDidDexOpt) {
10287                    // Give more time since we were dexopting.
10288                    mDidDexOpt = false;
10289                    return false;
10290                }
10291
10292                if (proc.instrumentationClass != null) {
10293                    Bundle info = new Bundle();
10294                    info.putString("shortMsg", "keyDispatchingTimedOut");
10295                    info.putString("longMsg", annotation);
10296                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10297                    return true;
10298                }
10299            }
10300            mHandler.post(new Runnable() {
10301                @Override
10302                public void run() {
10303                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10304                }
10305            });
10306        }
10307
10308        return true;
10309    }
10310
10311    @Override
10312    public Bundle getAssistContextExtras(int requestType) {
10313        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10314                UserHandle.getCallingUserId());
10315        if (pae == null) {
10316            return null;
10317        }
10318        synchronized (pae) {
10319            while (!pae.haveResult) {
10320                try {
10321                    pae.wait();
10322                } catch (InterruptedException e) {
10323                }
10324            }
10325        }
10326        synchronized (this) {
10327            buildAssistBundleLocked(pae, pae.result);
10328            mPendingAssistExtras.remove(pae);
10329            mHandler.removeCallbacks(pae);
10330        }
10331        return pae.extras;
10332    }
10333
10334    @Override
10335    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10336        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10337    }
10338
10339    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10340            IResultReceiver receiver, int userHandle) {
10341        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10342                "enqueueAssistContext()");
10343        synchronized (this) {
10344            ActivityRecord activity = getFocusedStack().topActivity();
10345            if (activity == null) {
10346                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10347                return null;
10348            }
10349            if (activity.app == null || activity.app.thread == null) {
10350                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10351                return null;
10352            }
10353            if (activity.app.pid == Binder.getCallingPid()) {
10354                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10355                return null;
10356            }
10357            PendingAssistExtras pae;
10358            Bundle extras = new Bundle();
10359            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10360            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10361            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10362            try {
10363                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10364                        requestType);
10365                mPendingAssistExtras.add(pae);
10366                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10367            } catch (RemoteException e) {
10368                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10369                return null;
10370            }
10371            return pae;
10372        }
10373    }
10374
10375    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10376        mPendingAssistExtras.remove(pae);
10377        if (pae.receiver != null) {
10378            // Caller wants result sent back to them.
10379            try {
10380                pae.receiver.send(0, null);
10381            } catch (RemoteException e) {
10382            }
10383        }
10384    }
10385
10386    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10387        if (result != null) {
10388            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10389        }
10390        if (pae.hint != null) {
10391            pae.extras.putBoolean(pae.hint, true);
10392        }
10393    }
10394
10395    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10396        PendingAssistExtras pae = (PendingAssistExtras)token;
10397        synchronized (pae) {
10398            pae.result = extras;
10399            pae.haveResult = true;
10400            pae.notifyAll();
10401            if (pae.intent == null && pae.receiver == null) {
10402                // Caller is just waiting for the result.
10403                return;
10404            }
10405        }
10406
10407        // We are now ready to launch the assist activity.
10408        synchronized (this) {
10409            buildAssistBundleLocked(pae, extras);
10410            boolean exists = mPendingAssistExtras.remove(pae);
10411            mHandler.removeCallbacks(pae);
10412            if (!exists) {
10413                // Timed out.
10414                return;
10415            }
10416            if (pae.receiver != null) {
10417                // Caller wants result sent back to them.
10418                try {
10419                    pae.receiver.send(0, pae.extras);
10420                } catch (RemoteException e) {
10421                }
10422                return;
10423            }
10424        }
10425        pae.intent.replaceExtras(pae.extras);
10426        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10427                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10428                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10429        closeSystemDialogs("assist");
10430        try {
10431            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10432        } catch (ActivityNotFoundException e) {
10433            Slog.w(TAG, "No activity to handle assist action.", e);
10434        }
10435    }
10436
10437    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10438        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10439    }
10440
10441    public void registerProcessObserver(IProcessObserver observer) {
10442        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10443                "registerProcessObserver()");
10444        synchronized (this) {
10445            mProcessObservers.register(observer);
10446        }
10447    }
10448
10449    @Override
10450    public void unregisterProcessObserver(IProcessObserver observer) {
10451        synchronized (this) {
10452            mProcessObservers.unregister(observer);
10453        }
10454    }
10455
10456    @Override
10457    public boolean convertFromTranslucent(IBinder token) {
10458        final long origId = Binder.clearCallingIdentity();
10459        try {
10460            synchronized (this) {
10461                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10462                if (r == null) {
10463                    return false;
10464                }
10465                final boolean translucentChanged = r.changeWindowTranslucency(true);
10466                if (translucentChanged) {
10467                    r.task.stack.releaseBackgroundResources(r);
10468                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10469                }
10470                mWindowManager.setAppFullscreen(token, true);
10471                return translucentChanged;
10472            }
10473        } finally {
10474            Binder.restoreCallingIdentity(origId);
10475        }
10476    }
10477
10478    @Override
10479    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10480        final long origId = Binder.clearCallingIdentity();
10481        try {
10482            synchronized (this) {
10483                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10484                if (r == null) {
10485                    return false;
10486                }
10487                int index = r.task.mActivities.lastIndexOf(r);
10488                if (index > 0) {
10489                    ActivityRecord under = r.task.mActivities.get(index - 1);
10490                    under.returningOptions = options;
10491                }
10492                final boolean translucentChanged = r.changeWindowTranslucency(false);
10493                if (translucentChanged) {
10494                    r.task.stack.convertActivityToTranslucent(r);
10495                }
10496                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10497                mWindowManager.setAppFullscreen(token, false);
10498                return translucentChanged;
10499            }
10500        } finally {
10501            Binder.restoreCallingIdentity(origId);
10502        }
10503    }
10504
10505    @Override
10506    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10507        final long origId = Binder.clearCallingIdentity();
10508        try {
10509            synchronized (this) {
10510                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10511                if (r != null) {
10512                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10513                }
10514            }
10515            return false;
10516        } finally {
10517            Binder.restoreCallingIdentity(origId);
10518        }
10519    }
10520
10521    @Override
10522    public boolean isBackgroundVisibleBehind(IBinder token) {
10523        final long origId = Binder.clearCallingIdentity();
10524        try {
10525            synchronized (this) {
10526                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10527                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10528                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10529                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10530                return visible;
10531            }
10532        } finally {
10533            Binder.restoreCallingIdentity(origId);
10534        }
10535    }
10536
10537    @Override
10538    public ActivityOptions getActivityOptions(IBinder token) {
10539        final long origId = Binder.clearCallingIdentity();
10540        try {
10541            synchronized (this) {
10542                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10543                if (r != null) {
10544                    final ActivityOptions activityOptions = r.pendingOptions;
10545                    r.pendingOptions = null;
10546                    return activityOptions;
10547                }
10548                return null;
10549            }
10550        } finally {
10551            Binder.restoreCallingIdentity(origId);
10552        }
10553    }
10554
10555    @Override
10556    public void setImmersive(IBinder token, boolean immersive) {
10557        synchronized(this) {
10558            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10559            if (r == null) {
10560                throw new IllegalArgumentException();
10561            }
10562            r.immersive = immersive;
10563
10564            // update associated state if we're frontmost
10565            if (r == mFocusedActivity) {
10566                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10567                applyUpdateLockStateLocked(r);
10568            }
10569        }
10570    }
10571
10572    @Override
10573    public boolean isImmersive(IBinder token) {
10574        synchronized (this) {
10575            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10576            if (r == null) {
10577                throw new IllegalArgumentException();
10578            }
10579            return r.immersive;
10580        }
10581    }
10582
10583    public boolean isTopActivityImmersive() {
10584        enforceNotIsolatedCaller("startActivity");
10585        synchronized (this) {
10586            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10587            return (r != null) ? r.immersive : false;
10588        }
10589    }
10590
10591    @Override
10592    public boolean isTopOfTask(IBinder token) {
10593        synchronized (this) {
10594            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10595            if (r == null) {
10596                throw new IllegalArgumentException();
10597            }
10598            return r.task.getTopActivity() == r;
10599        }
10600    }
10601
10602    public final void enterSafeMode() {
10603        synchronized(this) {
10604            // It only makes sense to do this before the system is ready
10605            // and started launching other packages.
10606            if (!mSystemReady) {
10607                try {
10608                    AppGlobals.getPackageManager().enterSafeMode();
10609                } catch (RemoteException e) {
10610                }
10611            }
10612
10613            mSafeMode = true;
10614        }
10615    }
10616
10617    public final void showSafeModeOverlay() {
10618        View v = LayoutInflater.from(mContext).inflate(
10619                com.android.internal.R.layout.safe_mode, null);
10620        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10621        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10622        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10623        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10624        lp.gravity = Gravity.BOTTOM | Gravity.START;
10625        lp.format = v.getBackground().getOpacity();
10626        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10627                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10628        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10629        ((WindowManager)mContext.getSystemService(
10630                Context.WINDOW_SERVICE)).addView(v, lp);
10631    }
10632
10633    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
10634        if (!(sender instanceof PendingIntentRecord)) {
10635            return;
10636        }
10637        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10638        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10639        synchronized (stats) {
10640            if (mBatteryStatsService.isOnBattery()) {
10641                mBatteryStatsService.enforceCallingPermission();
10642                int MY_UID = Binder.getCallingUid();
10643                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10644                BatteryStatsImpl.Uid.Pkg pkg =
10645                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10646                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10647                pkg.noteWakeupAlarmLocked(tag);
10648            }
10649        }
10650    }
10651
10652    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
10653        if (!(sender instanceof PendingIntentRecord)) {
10654            return;
10655        }
10656        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10657        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10658        synchronized (stats) {
10659            mBatteryStatsService.enforceCallingPermission();
10660            int MY_UID = Binder.getCallingUid();
10661            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10662            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
10663        }
10664    }
10665
10666    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
10667        if (!(sender instanceof PendingIntentRecord)) {
10668            return;
10669        }
10670        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10671        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10672        synchronized (stats) {
10673            mBatteryStatsService.enforceCallingPermission();
10674            int MY_UID = Binder.getCallingUid();
10675            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10676            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
10677        }
10678    }
10679
10680    public boolean killPids(int[] pids, String pReason, boolean secure) {
10681        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10682            throw new SecurityException("killPids only available to the system");
10683        }
10684        String reason = (pReason == null) ? "Unknown" : pReason;
10685        // XXX Note: don't acquire main activity lock here, because the window
10686        // manager calls in with its locks held.
10687
10688        boolean killed = false;
10689        synchronized (mPidsSelfLocked) {
10690            int[] types = new int[pids.length];
10691            int worstType = 0;
10692            for (int i=0; i<pids.length; i++) {
10693                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10694                if (proc != null) {
10695                    int type = proc.setAdj;
10696                    types[i] = type;
10697                    if (type > worstType) {
10698                        worstType = type;
10699                    }
10700                }
10701            }
10702
10703            // If the worst oom_adj is somewhere in the cached proc LRU range,
10704            // then constrain it so we will kill all cached procs.
10705            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10706                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10707                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10708            }
10709
10710            // If this is not a secure call, don't let it kill processes that
10711            // are important.
10712            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10713                worstType = ProcessList.SERVICE_ADJ;
10714            }
10715
10716            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10717            for (int i=0; i<pids.length; i++) {
10718                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10719                if (proc == null) {
10720                    continue;
10721                }
10722                int adj = proc.setAdj;
10723                if (adj >= worstType && !proc.killedByAm) {
10724                    proc.kill(reason, true);
10725                    killed = true;
10726                }
10727            }
10728        }
10729        return killed;
10730    }
10731
10732    @Override
10733    public void killUid(int uid, String reason) {
10734        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10735            throw new SecurityException("killUid only available to the system");
10736        }
10737        synchronized (this) {
10738            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10739                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10740                    reason != null ? reason : "kill uid");
10741        }
10742    }
10743
10744    @Override
10745    public boolean killProcessesBelowForeground(String reason) {
10746        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10747            throw new SecurityException("killProcessesBelowForeground() only available to system");
10748        }
10749
10750        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10751    }
10752
10753    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10754        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10755            throw new SecurityException("killProcessesBelowAdj() only available to system");
10756        }
10757
10758        boolean killed = false;
10759        synchronized (mPidsSelfLocked) {
10760            final int size = mPidsSelfLocked.size();
10761            for (int i = 0; i < size; i++) {
10762                final int pid = mPidsSelfLocked.keyAt(i);
10763                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10764                if (proc == null) continue;
10765
10766                final int adj = proc.setAdj;
10767                if (adj > belowAdj && !proc.killedByAm) {
10768                    proc.kill(reason, true);
10769                    killed = true;
10770                }
10771            }
10772        }
10773        return killed;
10774    }
10775
10776    @Override
10777    public void hang(final IBinder who, boolean allowRestart) {
10778        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10779                != PackageManager.PERMISSION_GRANTED) {
10780            throw new SecurityException("Requires permission "
10781                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10782        }
10783
10784        final IBinder.DeathRecipient death = new DeathRecipient() {
10785            @Override
10786            public void binderDied() {
10787                synchronized (this) {
10788                    notifyAll();
10789                }
10790            }
10791        };
10792
10793        try {
10794            who.linkToDeath(death, 0);
10795        } catch (RemoteException e) {
10796            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10797            return;
10798        }
10799
10800        synchronized (this) {
10801            Watchdog.getInstance().setAllowRestart(allowRestart);
10802            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10803            synchronized (death) {
10804                while (who.isBinderAlive()) {
10805                    try {
10806                        death.wait();
10807                    } catch (InterruptedException e) {
10808                    }
10809                }
10810            }
10811            Watchdog.getInstance().setAllowRestart(true);
10812        }
10813    }
10814
10815    @Override
10816    public void restart() {
10817        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10818                != PackageManager.PERMISSION_GRANTED) {
10819            throw new SecurityException("Requires permission "
10820                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10821        }
10822
10823        Log.i(TAG, "Sending shutdown broadcast...");
10824
10825        BroadcastReceiver br = new BroadcastReceiver() {
10826            @Override public void onReceive(Context context, Intent intent) {
10827                // Now the broadcast is done, finish up the low-level shutdown.
10828                Log.i(TAG, "Shutting down activity manager...");
10829                shutdown(10000);
10830                Log.i(TAG, "Shutdown complete, restarting!");
10831                Process.killProcess(Process.myPid());
10832                System.exit(10);
10833            }
10834        };
10835
10836        // First send the high-level shut down broadcast.
10837        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10838        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10839        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10840        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10841        mContext.sendOrderedBroadcastAsUser(intent,
10842                UserHandle.ALL, null, br, mHandler, 0, null, null);
10843        */
10844        br.onReceive(mContext, intent);
10845    }
10846
10847    private long getLowRamTimeSinceIdle(long now) {
10848        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10849    }
10850
10851    @Override
10852    public void performIdleMaintenance() {
10853        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10854                != PackageManager.PERMISSION_GRANTED) {
10855            throw new SecurityException("Requires permission "
10856                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10857        }
10858
10859        synchronized (this) {
10860            final long now = SystemClock.uptimeMillis();
10861            final long timeSinceLastIdle = now - mLastIdleTime;
10862            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10863            mLastIdleTime = now;
10864            mLowRamTimeSinceLastIdle = 0;
10865            if (mLowRamStartTime != 0) {
10866                mLowRamStartTime = now;
10867            }
10868
10869            StringBuilder sb = new StringBuilder(128);
10870            sb.append("Idle maintenance over ");
10871            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10872            sb.append(" low RAM for ");
10873            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10874            Slog.i(TAG, sb.toString());
10875
10876            // If at least 1/3 of our time since the last idle period has been spent
10877            // with RAM low, then we want to kill processes.
10878            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10879
10880            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10881                ProcessRecord proc = mLruProcesses.get(i);
10882                if (proc.notCachedSinceIdle) {
10883                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
10884                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
10885                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10886                        if (doKilling && proc.initialIdlePss != 0
10887                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10888                            sb = new StringBuilder(128);
10889                            sb.append("Kill");
10890                            sb.append(proc.processName);
10891                            sb.append(" in idle maint: pss=");
10892                            sb.append(proc.lastPss);
10893                            sb.append(", initialPss=");
10894                            sb.append(proc.initialIdlePss);
10895                            sb.append(", period=");
10896                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10897                            sb.append(", lowRamPeriod=");
10898                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10899                            Slog.wtfQuiet(TAG, sb.toString());
10900                            proc.kill("idle maint (pss " + proc.lastPss
10901                                    + " from " + proc.initialIdlePss + ")", true);
10902                        }
10903                    }
10904                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10905                    proc.notCachedSinceIdle = true;
10906                    proc.initialIdlePss = 0;
10907                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10908                            mTestPssMode, isSleeping(), now);
10909                }
10910            }
10911
10912            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10913            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10914        }
10915    }
10916
10917    private void retrieveSettings() {
10918        final ContentResolver resolver = mContext.getContentResolver();
10919        String debugApp = Settings.Global.getString(
10920            resolver, Settings.Global.DEBUG_APP);
10921        boolean waitForDebugger = Settings.Global.getInt(
10922            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10923        boolean alwaysFinishActivities = Settings.Global.getInt(
10924            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10925        boolean forceRtl = Settings.Global.getInt(
10926                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10927        // Transfer any global setting for forcing RTL layout, into a System Property
10928        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10929
10930        Configuration configuration = new Configuration();
10931        Settings.System.getConfiguration(resolver, configuration);
10932        if (forceRtl) {
10933            // This will take care of setting the correct layout direction flags
10934            configuration.setLayoutDirection(configuration.locale);
10935        }
10936
10937        synchronized (this) {
10938            mDebugApp = mOrigDebugApp = debugApp;
10939            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10940            mAlwaysFinishActivities = alwaysFinishActivities;
10941            // This happens before any activities are started, so we can
10942            // change mConfiguration in-place.
10943            updateConfigurationLocked(configuration, null, false, true);
10944            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
10945                    "Initial config: " + mConfiguration);
10946        }
10947    }
10948
10949    /** Loads resources after the current configuration has been set. */
10950    private void loadResourcesOnSystemReady() {
10951        final Resources res = mContext.getResources();
10952        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10953        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10954        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10955    }
10956
10957    public boolean testIsSystemReady() {
10958        // no need to synchronize(this) just to read & return the value
10959        return mSystemReady;
10960    }
10961
10962    private static File getCalledPreBootReceiversFile() {
10963        File dataDir = Environment.getDataDirectory();
10964        File systemDir = new File(dataDir, "system");
10965        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10966        return fname;
10967    }
10968
10969    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10970        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10971        File file = getCalledPreBootReceiversFile();
10972        FileInputStream fis = null;
10973        try {
10974            fis = new FileInputStream(file);
10975            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10976            int fvers = dis.readInt();
10977            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10978                String vers = dis.readUTF();
10979                String codename = dis.readUTF();
10980                String build = dis.readUTF();
10981                if (android.os.Build.VERSION.RELEASE.equals(vers)
10982                        && android.os.Build.VERSION.CODENAME.equals(codename)
10983                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10984                    int num = dis.readInt();
10985                    while (num > 0) {
10986                        num--;
10987                        String pkg = dis.readUTF();
10988                        String cls = dis.readUTF();
10989                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10990                    }
10991                }
10992            }
10993        } catch (FileNotFoundException e) {
10994        } catch (IOException e) {
10995            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10996        } finally {
10997            if (fis != null) {
10998                try {
10999                    fis.close();
11000                } catch (IOException e) {
11001                }
11002            }
11003        }
11004        return lastDoneReceivers;
11005    }
11006
11007    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11008        File file = getCalledPreBootReceiversFile();
11009        FileOutputStream fos = null;
11010        DataOutputStream dos = null;
11011        try {
11012            fos = new FileOutputStream(file);
11013            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11014            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11015            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11016            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11017            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11018            dos.writeInt(list.size());
11019            for (int i=0; i<list.size(); i++) {
11020                dos.writeUTF(list.get(i).getPackageName());
11021                dos.writeUTF(list.get(i).getClassName());
11022            }
11023        } catch (IOException e) {
11024            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11025            file.delete();
11026        } finally {
11027            FileUtils.sync(fos);
11028            if (dos != null) {
11029                try {
11030                    dos.close();
11031                } catch (IOException e) {
11032                    // TODO Auto-generated catch block
11033                    e.printStackTrace();
11034                }
11035            }
11036        }
11037    }
11038
11039    final class PreBootContinuation extends IIntentReceiver.Stub {
11040        final Intent intent;
11041        final Runnable onFinishCallback;
11042        final ArrayList<ComponentName> doneReceivers;
11043        final List<ResolveInfo> ris;
11044        final int[] users;
11045        int lastRi = -1;
11046        int curRi = 0;
11047        int curUser = 0;
11048
11049        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11050                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11051            intent = _intent;
11052            onFinishCallback = _onFinishCallback;
11053            doneReceivers = _doneReceivers;
11054            ris = _ris;
11055            users = _users;
11056        }
11057
11058        void go() {
11059            if (lastRi != curRi) {
11060                ActivityInfo ai = ris.get(curRi).activityInfo;
11061                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11062                intent.setComponent(comp);
11063                doneReceivers.add(comp);
11064                lastRi = curRi;
11065                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11066                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11067            }
11068            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11069                    + " for user " + users[curUser]);
11070            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11071            broadcastIntentLocked(null, null, intent, null, this,
11072                    0, null, null, null, AppOpsManager.OP_NONE,
11073                    true, false, MY_PID, Process.SYSTEM_UID,
11074                    users[curUser]);
11075        }
11076
11077        public void performReceive(Intent intent, int resultCode,
11078                String data, Bundle extras, boolean ordered,
11079                boolean sticky, int sendingUser) {
11080            curUser++;
11081            if (curUser >= users.length) {
11082                curUser = 0;
11083                curRi++;
11084                if (curRi >= ris.size()) {
11085                    // All done sending broadcasts!
11086                    if (onFinishCallback != null) {
11087                        // The raw IIntentReceiver interface is called
11088                        // with the AM lock held, so redispatch to
11089                        // execute our code without the lock.
11090                        mHandler.post(onFinishCallback);
11091                    }
11092                    return;
11093                }
11094            }
11095            go();
11096        }
11097    }
11098
11099    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11100            ArrayList<ComponentName> doneReceivers, int userId) {
11101        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11102        List<ResolveInfo> ris = null;
11103        try {
11104            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11105                    intent, null, 0, userId);
11106        } catch (RemoteException e) {
11107        }
11108        if (ris == null) {
11109            return false;
11110        }
11111        for (int i=ris.size()-1; i>=0; i--) {
11112            if ((ris.get(i).activityInfo.applicationInfo.flags
11113                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11114                ris.remove(i);
11115            }
11116        }
11117        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11118
11119        // For User 0, load the version number. When delivering to a new user, deliver
11120        // to all receivers.
11121        if (userId == UserHandle.USER_OWNER) {
11122            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11123            for (int i=0; i<ris.size(); i++) {
11124                ActivityInfo ai = ris.get(i).activityInfo;
11125                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11126                if (false && lastDoneReceivers.contains(comp)) {
11127                    // We already did the pre boot receiver for this app with the current
11128                    // platform version, so don't do it again...
11129                    ris.remove(i);
11130                    i--;
11131                    // ...however, do keep it as one that has been done, so we don't
11132                    // forget about it when rewriting the file of last done receivers.
11133                    doneReceivers.add(comp);
11134                }
11135            }
11136        }
11137
11138        if (ris.size() <= 0) {
11139            return false;
11140        }
11141
11142        // If primary user, send broadcast to all available users, else just to userId
11143        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11144                : new int[] { userId };
11145        if (users.length <= 0) {
11146            return false;
11147        }
11148
11149        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11150                ris, users);
11151        cont.go();
11152        return true;
11153    }
11154
11155    public void systemReady(final Runnable goingCallback) {
11156        synchronized(this) {
11157            if (mSystemReady) {
11158                // If we're done calling all the receivers, run the next "boot phase" passed in
11159                // by the SystemServer
11160                if (goingCallback != null) {
11161                    goingCallback.run();
11162                }
11163                return;
11164            }
11165
11166            // Make sure we have the current profile info, since it is needed for
11167            // security checks.
11168            updateCurrentProfileIdsLocked();
11169
11170            mRecentTasks.clear();
11171            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11172            mTaskPersister.restoreTasksFromOtherDeviceLocked();
11173            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11174            mTaskPersister.startPersisting();
11175
11176            // Check to see if there are any update receivers to run.
11177            if (!mDidUpdate) {
11178                if (mWaitingUpdate) {
11179                    return;
11180                }
11181                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11182                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11183                    public void run() {
11184                        synchronized (ActivityManagerService.this) {
11185                            mDidUpdate = true;
11186                        }
11187                        showBootMessage(mContext.getText(
11188                                R.string.android_upgrading_complete),
11189                                false);
11190                        writeLastDonePreBootReceivers(doneReceivers);
11191                        systemReady(goingCallback);
11192                    }
11193                }, doneReceivers, UserHandle.USER_OWNER);
11194
11195                if (mWaitingUpdate) {
11196                    return;
11197                }
11198                mDidUpdate = true;
11199            }
11200
11201            mAppOpsService.systemReady();
11202            mSystemReady = true;
11203        }
11204
11205        ArrayList<ProcessRecord> procsToKill = null;
11206        synchronized(mPidsSelfLocked) {
11207            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11208                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11209                if (!isAllowedWhileBooting(proc.info)){
11210                    if (procsToKill == null) {
11211                        procsToKill = new ArrayList<ProcessRecord>();
11212                    }
11213                    procsToKill.add(proc);
11214                }
11215            }
11216        }
11217
11218        synchronized(this) {
11219            if (procsToKill != null) {
11220                for (int i=procsToKill.size()-1; i>=0; i--) {
11221                    ProcessRecord proc = procsToKill.get(i);
11222                    Slog.i(TAG, "Removing system update proc: " + proc);
11223                    removeProcessLocked(proc, true, false, "system update done");
11224                }
11225            }
11226
11227            // Now that we have cleaned up any update processes, we
11228            // are ready to start launching real processes and know that
11229            // we won't trample on them any more.
11230            mProcessesReady = true;
11231        }
11232
11233        Slog.i(TAG, "System now ready");
11234        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11235            SystemClock.uptimeMillis());
11236
11237        synchronized(this) {
11238            // Make sure we have no pre-ready processes sitting around.
11239
11240            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11241                ResolveInfo ri = mContext.getPackageManager()
11242                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11243                                STOCK_PM_FLAGS);
11244                CharSequence errorMsg = null;
11245                if (ri != null) {
11246                    ActivityInfo ai = ri.activityInfo;
11247                    ApplicationInfo app = ai.applicationInfo;
11248                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11249                        mTopAction = Intent.ACTION_FACTORY_TEST;
11250                        mTopData = null;
11251                        mTopComponent = new ComponentName(app.packageName,
11252                                ai.name);
11253                    } else {
11254                        errorMsg = mContext.getResources().getText(
11255                                com.android.internal.R.string.factorytest_not_system);
11256                    }
11257                } else {
11258                    errorMsg = mContext.getResources().getText(
11259                            com.android.internal.R.string.factorytest_no_action);
11260                }
11261                if (errorMsg != null) {
11262                    mTopAction = null;
11263                    mTopData = null;
11264                    mTopComponent = null;
11265                    Message msg = Message.obtain();
11266                    msg.what = SHOW_FACTORY_ERROR_MSG;
11267                    msg.getData().putCharSequence("msg", errorMsg);
11268                    mUiHandler.sendMessage(msg);
11269                }
11270            }
11271        }
11272
11273        retrieveSettings();
11274        loadResourcesOnSystemReady();
11275
11276        synchronized (this) {
11277            readGrantedUriPermissionsLocked();
11278        }
11279
11280        if (goingCallback != null) goingCallback.run();
11281
11282        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11283                Integer.toString(mCurrentUserId), mCurrentUserId);
11284        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11285                Integer.toString(mCurrentUserId), mCurrentUserId);
11286        mSystemServiceManager.startUser(mCurrentUserId);
11287
11288        synchronized (this) {
11289            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11290                try {
11291                    List apps = AppGlobals.getPackageManager().
11292                        getPersistentApplications(STOCK_PM_FLAGS);
11293                    if (apps != null) {
11294                        int N = apps.size();
11295                        int i;
11296                        for (i=0; i<N; i++) {
11297                            ApplicationInfo info
11298                                = (ApplicationInfo)apps.get(i);
11299                            if (info != null &&
11300                                    !info.packageName.equals("android")) {
11301                                addAppLocked(info, false, null /* ABI override */);
11302                            }
11303                        }
11304                    }
11305                } catch (RemoteException ex) {
11306                    // pm is in same process, this will never happen.
11307                }
11308            }
11309
11310            // Start up initial activity.
11311            mBooting = true;
11312            startHomeActivityLocked(mCurrentUserId, "systemReady");
11313
11314            try {
11315                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11316                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11317                            + " data partition or your device will be unstable.");
11318                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11319                }
11320            } catch (RemoteException e) {
11321            }
11322
11323            if (!Build.isBuildConsistent()) {
11324                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11325                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11326            }
11327
11328            long ident = Binder.clearCallingIdentity();
11329            try {
11330                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11331                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11332                        | Intent.FLAG_RECEIVER_FOREGROUND);
11333                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11334                broadcastIntentLocked(null, null, intent,
11335                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11336                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11337                intent = new Intent(Intent.ACTION_USER_STARTING);
11338                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11339                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11340                broadcastIntentLocked(null, null, intent,
11341                        null, new IIntentReceiver.Stub() {
11342                            @Override
11343                            public void performReceive(Intent intent, int resultCode, String data,
11344                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11345                                    throws RemoteException {
11346                            }
11347                        }, 0, null, null,
11348                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11349                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11350            } catch (Throwable t) {
11351                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11352            } finally {
11353                Binder.restoreCallingIdentity(ident);
11354            }
11355            mStackSupervisor.resumeTopActivitiesLocked();
11356            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11357        }
11358    }
11359
11360    private boolean makeAppCrashingLocked(ProcessRecord app,
11361            String shortMsg, String longMsg, String stackTrace) {
11362        app.crashing = true;
11363        app.crashingReport = generateProcessError(app,
11364                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11365        startAppProblemLocked(app);
11366        app.stopFreezingAllLocked();
11367        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11368    }
11369
11370    private void makeAppNotRespondingLocked(ProcessRecord app,
11371            String activity, String shortMsg, String longMsg) {
11372        app.notResponding = true;
11373        app.notRespondingReport = generateProcessError(app,
11374                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11375                activity, shortMsg, longMsg, null);
11376        startAppProblemLocked(app);
11377        app.stopFreezingAllLocked();
11378    }
11379
11380    /**
11381     * Generate a process error record, suitable for attachment to a ProcessRecord.
11382     *
11383     * @param app The ProcessRecord in which the error occurred.
11384     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11385     *                      ActivityManager.AppErrorStateInfo
11386     * @param activity The activity associated with the crash, if known.
11387     * @param shortMsg Short message describing the crash.
11388     * @param longMsg Long message describing the crash.
11389     * @param stackTrace Full crash stack trace, may be null.
11390     *
11391     * @return Returns a fully-formed AppErrorStateInfo record.
11392     */
11393    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11394            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11395        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11396
11397        report.condition = condition;
11398        report.processName = app.processName;
11399        report.pid = app.pid;
11400        report.uid = app.info.uid;
11401        report.tag = activity;
11402        report.shortMsg = shortMsg;
11403        report.longMsg = longMsg;
11404        report.stackTrace = stackTrace;
11405
11406        return report;
11407    }
11408
11409    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11410        synchronized (this) {
11411            app.crashing = false;
11412            app.crashingReport = null;
11413            app.notResponding = false;
11414            app.notRespondingReport = null;
11415            if (app.anrDialog == fromDialog) {
11416                app.anrDialog = null;
11417            }
11418            if (app.waitDialog == fromDialog) {
11419                app.waitDialog = null;
11420            }
11421            if (app.pid > 0 && app.pid != MY_PID) {
11422                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11423                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11424                app.kill("user request after error", true);
11425            }
11426        }
11427    }
11428
11429    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11430            String shortMsg, String longMsg, String stackTrace) {
11431        long now = SystemClock.uptimeMillis();
11432
11433        Long crashTime;
11434        if (!app.isolated) {
11435            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11436        } else {
11437            crashTime = null;
11438        }
11439        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11440            // This process loses!
11441            Slog.w(TAG, "Process " + app.info.processName
11442                    + " has crashed too many times: killing!");
11443            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11444                    app.userId, app.info.processName, app.uid);
11445            mStackSupervisor.handleAppCrashLocked(app);
11446            if (!app.persistent) {
11447                // We don't want to start this process again until the user
11448                // explicitly does so...  but for persistent process, we really
11449                // need to keep it running.  If a persistent process is actually
11450                // repeatedly crashing, then badness for everyone.
11451                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11452                        app.info.processName);
11453                if (!app.isolated) {
11454                    // XXX We don't have a way to mark isolated processes
11455                    // as bad, since they don't have a peristent identity.
11456                    mBadProcesses.put(app.info.processName, app.uid,
11457                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11458                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11459                }
11460                app.bad = true;
11461                app.removed = true;
11462                // Don't let services in this process be restarted and potentially
11463                // annoy the user repeatedly.  Unless it is persistent, since those
11464                // processes run critical code.
11465                removeProcessLocked(app, false, false, "crash");
11466                mStackSupervisor.resumeTopActivitiesLocked();
11467                return false;
11468            }
11469            mStackSupervisor.resumeTopActivitiesLocked();
11470        } else {
11471            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11472        }
11473
11474        // Bump up the crash count of any services currently running in the proc.
11475        for (int i=app.services.size()-1; i>=0; i--) {
11476            // Any services running in the application need to be placed
11477            // back in the pending list.
11478            ServiceRecord sr = app.services.valueAt(i);
11479            sr.crashCount++;
11480        }
11481
11482        // If the crashing process is what we consider to be the "home process" and it has been
11483        // replaced by a third-party app, clear the package preferred activities from packages
11484        // with a home activity running in the process to prevent a repeatedly crashing app
11485        // from blocking the user to manually clear the list.
11486        final ArrayList<ActivityRecord> activities = app.activities;
11487        if (app == mHomeProcess && activities.size() > 0
11488                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11489            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11490                final ActivityRecord r = activities.get(activityNdx);
11491                if (r.isHomeActivity()) {
11492                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11493                    try {
11494                        ActivityThread.getPackageManager()
11495                                .clearPackagePreferredActivities(r.packageName);
11496                    } catch (RemoteException c) {
11497                        // pm is in same process, this will never happen.
11498                    }
11499                }
11500            }
11501        }
11502
11503        if (!app.isolated) {
11504            // XXX Can't keep track of crash times for isolated processes,
11505            // because they don't have a perisistent identity.
11506            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11507        }
11508
11509        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11510        return true;
11511    }
11512
11513    void startAppProblemLocked(ProcessRecord app) {
11514        // If this app is not running under the current user, then we
11515        // can't give it a report button because that would require
11516        // launching the report UI under a different user.
11517        app.errorReportReceiver = null;
11518
11519        for (int userId : mCurrentProfileIds) {
11520            if (app.userId == userId) {
11521                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11522                        mContext, app.info.packageName, app.info.flags);
11523            }
11524        }
11525        skipCurrentReceiverLocked(app);
11526    }
11527
11528    void skipCurrentReceiverLocked(ProcessRecord app) {
11529        for (BroadcastQueue queue : mBroadcastQueues) {
11530            queue.skipCurrentReceiverLocked(app);
11531        }
11532    }
11533
11534    /**
11535     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11536     * The application process will exit immediately after this call returns.
11537     * @param app object of the crashing app, null for the system server
11538     * @param crashInfo describing the exception
11539     */
11540    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11541        ProcessRecord r = findAppProcess(app, "Crash");
11542        final String processName = app == null ? "system_server"
11543                : (r == null ? "unknown" : r.processName);
11544
11545        handleApplicationCrashInner("crash", r, processName, crashInfo);
11546    }
11547
11548    /* Native crash reporting uses this inner version because it needs to be somewhat
11549     * decoupled from the AM-managed cleanup lifecycle
11550     */
11551    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11552            ApplicationErrorReport.CrashInfo crashInfo) {
11553        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11554                UserHandle.getUserId(Binder.getCallingUid()), processName,
11555                r == null ? -1 : r.info.flags,
11556                crashInfo.exceptionClassName,
11557                crashInfo.exceptionMessage,
11558                crashInfo.throwFileName,
11559                crashInfo.throwLineNumber);
11560
11561        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11562
11563        crashApplication(r, crashInfo);
11564    }
11565
11566    public void handleApplicationStrictModeViolation(
11567            IBinder app,
11568            int violationMask,
11569            StrictMode.ViolationInfo info) {
11570        ProcessRecord r = findAppProcess(app, "StrictMode");
11571        if (r == null) {
11572            return;
11573        }
11574
11575        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11576            Integer stackFingerprint = info.hashCode();
11577            boolean logIt = true;
11578            synchronized (mAlreadyLoggedViolatedStacks) {
11579                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11580                    logIt = false;
11581                    // TODO: sub-sample into EventLog for these, with
11582                    // the info.durationMillis?  Then we'd get
11583                    // the relative pain numbers, without logging all
11584                    // the stack traces repeatedly.  We'd want to do
11585                    // likewise in the client code, which also does
11586                    // dup suppression, before the Binder call.
11587                } else {
11588                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11589                        mAlreadyLoggedViolatedStacks.clear();
11590                    }
11591                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11592                }
11593            }
11594            if (logIt) {
11595                logStrictModeViolationToDropBox(r, info);
11596            }
11597        }
11598
11599        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11600            AppErrorResult result = new AppErrorResult();
11601            synchronized (this) {
11602                final long origId = Binder.clearCallingIdentity();
11603
11604                Message msg = Message.obtain();
11605                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11606                HashMap<String, Object> data = new HashMap<String, Object>();
11607                data.put("result", result);
11608                data.put("app", r);
11609                data.put("violationMask", violationMask);
11610                data.put("info", info);
11611                msg.obj = data;
11612                mUiHandler.sendMessage(msg);
11613
11614                Binder.restoreCallingIdentity(origId);
11615            }
11616            int res = result.get();
11617            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11618        }
11619    }
11620
11621    // Depending on the policy in effect, there could be a bunch of
11622    // these in quick succession so we try to batch these together to
11623    // minimize disk writes, number of dropbox entries, and maximize
11624    // compression, by having more fewer, larger records.
11625    private void logStrictModeViolationToDropBox(
11626            ProcessRecord process,
11627            StrictMode.ViolationInfo info) {
11628        if (info == null) {
11629            return;
11630        }
11631        final boolean isSystemApp = process == null ||
11632                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11633                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11634        final String processName = process == null ? "unknown" : process.processName;
11635        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11636        final DropBoxManager dbox = (DropBoxManager)
11637                mContext.getSystemService(Context.DROPBOX_SERVICE);
11638
11639        // Exit early if the dropbox isn't configured to accept this report type.
11640        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11641
11642        boolean bufferWasEmpty;
11643        boolean needsFlush;
11644        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11645        synchronized (sb) {
11646            bufferWasEmpty = sb.length() == 0;
11647            appendDropBoxProcessHeaders(process, processName, sb);
11648            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11649            sb.append("System-App: ").append(isSystemApp).append("\n");
11650            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11651            if (info.violationNumThisLoop != 0) {
11652                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11653            }
11654            if (info.numAnimationsRunning != 0) {
11655                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11656            }
11657            if (info.broadcastIntentAction != null) {
11658                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11659            }
11660            if (info.durationMillis != -1) {
11661                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11662            }
11663            if (info.numInstances != -1) {
11664                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11665            }
11666            if (info.tags != null) {
11667                for (String tag : info.tags) {
11668                    sb.append("Span-Tag: ").append(tag).append("\n");
11669                }
11670            }
11671            sb.append("\n");
11672            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11673                sb.append(info.crashInfo.stackTrace);
11674                sb.append("\n");
11675            }
11676            if (info.message != null) {
11677                sb.append(info.message);
11678                sb.append("\n");
11679            }
11680
11681            // Only buffer up to ~64k.  Various logging bits truncate
11682            // things at 128k.
11683            needsFlush = (sb.length() > 64 * 1024);
11684        }
11685
11686        // Flush immediately if the buffer's grown too large, or this
11687        // is a non-system app.  Non-system apps are isolated with a
11688        // different tag & policy and not batched.
11689        //
11690        // Batching is useful during internal testing with
11691        // StrictMode settings turned up high.  Without batching,
11692        // thousands of separate files could be created on boot.
11693        if (!isSystemApp || needsFlush) {
11694            new Thread("Error dump: " + dropboxTag) {
11695                @Override
11696                public void run() {
11697                    String report;
11698                    synchronized (sb) {
11699                        report = sb.toString();
11700                        sb.delete(0, sb.length());
11701                        sb.trimToSize();
11702                    }
11703                    if (report.length() != 0) {
11704                        dbox.addText(dropboxTag, report);
11705                    }
11706                }
11707            }.start();
11708            return;
11709        }
11710
11711        // System app batching:
11712        if (!bufferWasEmpty) {
11713            // An existing dropbox-writing thread is outstanding, so
11714            // we don't need to start it up.  The existing thread will
11715            // catch the buffer appends we just did.
11716            return;
11717        }
11718
11719        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11720        // (After this point, we shouldn't access AMS internal data structures.)
11721        new Thread("Error dump: " + dropboxTag) {
11722            @Override
11723            public void run() {
11724                // 5 second sleep to let stacks arrive and be batched together
11725                try {
11726                    Thread.sleep(5000);  // 5 seconds
11727                } catch (InterruptedException e) {}
11728
11729                String errorReport;
11730                synchronized (mStrictModeBuffer) {
11731                    errorReport = mStrictModeBuffer.toString();
11732                    if (errorReport.length() == 0) {
11733                        return;
11734                    }
11735                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11736                    mStrictModeBuffer.trimToSize();
11737                }
11738                dbox.addText(dropboxTag, errorReport);
11739            }
11740        }.start();
11741    }
11742
11743    /**
11744     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11745     * @param app object of the crashing app, null for the system server
11746     * @param tag reported by the caller
11747     * @param system whether this wtf is coming from the system
11748     * @param crashInfo describing the context of the error
11749     * @return true if the process should exit immediately (WTF is fatal)
11750     */
11751    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11752            final ApplicationErrorReport.CrashInfo crashInfo) {
11753        final int callingUid = Binder.getCallingUid();
11754        final int callingPid = Binder.getCallingPid();
11755
11756        if (system) {
11757            // If this is coming from the system, we could very well have low-level
11758            // system locks held, so we want to do this all asynchronously.  And we
11759            // never want this to become fatal, so there is that too.
11760            mHandler.post(new Runnable() {
11761                @Override public void run() {
11762                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11763                }
11764            });
11765            return false;
11766        }
11767
11768        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11769                crashInfo);
11770
11771        if (r != null && r.pid != Process.myPid() &&
11772                Settings.Global.getInt(mContext.getContentResolver(),
11773                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11774            crashApplication(r, crashInfo);
11775            return true;
11776        } else {
11777            return false;
11778        }
11779    }
11780
11781    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11782            final ApplicationErrorReport.CrashInfo crashInfo) {
11783        final ProcessRecord r = findAppProcess(app, "WTF");
11784        final String processName = app == null ? "system_server"
11785                : (r == null ? "unknown" : r.processName);
11786
11787        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11788                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11789
11790        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11791
11792        return r;
11793    }
11794
11795    /**
11796     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11797     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11798     */
11799    private ProcessRecord findAppProcess(IBinder app, String reason) {
11800        if (app == null) {
11801            return null;
11802        }
11803
11804        synchronized (this) {
11805            final int NP = mProcessNames.getMap().size();
11806            for (int ip=0; ip<NP; ip++) {
11807                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11808                final int NA = apps.size();
11809                for (int ia=0; ia<NA; ia++) {
11810                    ProcessRecord p = apps.valueAt(ia);
11811                    if (p.thread != null && p.thread.asBinder() == app) {
11812                        return p;
11813                    }
11814                }
11815            }
11816
11817            Slog.w(TAG, "Can't find mystery application for " + reason
11818                    + " from pid=" + Binder.getCallingPid()
11819                    + " uid=" + Binder.getCallingUid() + ": " + app);
11820            return null;
11821        }
11822    }
11823
11824    /**
11825     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11826     * to append various headers to the dropbox log text.
11827     */
11828    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11829            StringBuilder sb) {
11830        // Watchdog thread ends up invoking this function (with
11831        // a null ProcessRecord) to add the stack file to dropbox.
11832        // Do not acquire a lock on this (am) in such cases, as it
11833        // could cause a potential deadlock, if and when watchdog
11834        // is invoked due to unavailability of lock on am and it
11835        // would prevent watchdog from killing system_server.
11836        if (process == null) {
11837            sb.append("Process: ").append(processName).append("\n");
11838            return;
11839        }
11840        // Note: ProcessRecord 'process' is guarded by the service
11841        // instance.  (notably process.pkgList, which could otherwise change
11842        // concurrently during execution of this method)
11843        synchronized (this) {
11844            sb.append("Process: ").append(processName).append("\n");
11845            int flags = process.info.flags;
11846            IPackageManager pm = AppGlobals.getPackageManager();
11847            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11848            for (int ip=0; ip<process.pkgList.size(); ip++) {
11849                String pkg = process.pkgList.keyAt(ip);
11850                sb.append("Package: ").append(pkg);
11851                try {
11852                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11853                    if (pi != null) {
11854                        sb.append(" v").append(pi.versionCode);
11855                        if (pi.versionName != null) {
11856                            sb.append(" (").append(pi.versionName).append(")");
11857                        }
11858                    }
11859                } catch (RemoteException e) {
11860                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11861                }
11862                sb.append("\n");
11863            }
11864        }
11865    }
11866
11867    private static String processClass(ProcessRecord process) {
11868        if (process == null || process.pid == MY_PID) {
11869            return "system_server";
11870        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11871            return "system_app";
11872        } else {
11873            return "data_app";
11874        }
11875    }
11876
11877    /**
11878     * Write a description of an error (crash, WTF, ANR) to the drop box.
11879     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11880     * @param process which caused the error, null means the system server
11881     * @param activity which triggered the error, null if unknown
11882     * @param parent activity related to the error, null if unknown
11883     * @param subject line related to the error, null if absent
11884     * @param report in long form describing the error, null if absent
11885     * @param logFile to include in the report, null if none
11886     * @param crashInfo giving an application stack trace, null if absent
11887     */
11888    public void addErrorToDropBox(String eventType,
11889            ProcessRecord process, String processName, ActivityRecord activity,
11890            ActivityRecord parent, String subject,
11891            final String report, final File logFile,
11892            final ApplicationErrorReport.CrashInfo crashInfo) {
11893        // NOTE -- this must never acquire the ActivityManagerService lock,
11894        // otherwise the watchdog may be prevented from resetting the system.
11895
11896        final String dropboxTag = processClass(process) + "_" + eventType;
11897        final DropBoxManager dbox = (DropBoxManager)
11898                mContext.getSystemService(Context.DROPBOX_SERVICE);
11899
11900        // Exit early if the dropbox isn't configured to accept this report type.
11901        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11902
11903        final StringBuilder sb = new StringBuilder(1024);
11904        appendDropBoxProcessHeaders(process, processName, sb);
11905        if (activity != null) {
11906            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11907        }
11908        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11909            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11910        }
11911        if (parent != null && parent != activity) {
11912            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11913        }
11914        if (subject != null) {
11915            sb.append("Subject: ").append(subject).append("\n");
11916        }
11917        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11918        if (Debug.isDebuggerConnected()) {
11919            sb.append("Debugger: Connected\n");
11920        }
11921        sb.append("\n");
11922
11923        // Do the rest in a worker thread to avoid blocking the caller on I/O
11924        // (After this point, we shouldn't access AMS internal data structures.)
11925        Thread worker = new Thread("Error dump: " + dropboxTag) {
11926            @Override
11927            public void run() {
11928                if (report != null) {
11929                    sb.append(report);
11930                }
11931                if (logFile != null) {
11932                    try {
11933                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11934                                    "\n\n[[TRUNCATED]]"));
11935                    } catch (IOException e) {
11936                        Slog.e(TAG, "Error reading " + logFile, e);
11937                    }
11938                }
11939                if (crashInfo != null && crashInfo.stackTrace != null) {
11940                    sb.append(crashInfo.stackTrace);
11941                }
11942
11943                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11944                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11945                if (lines > 0) {
11946                    sb.append("\n");
11947
11948                    // Merge several logcat streams, and take the last N lines
11949                    InputStreamReader input = null;
11950                    try {
11951                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11952                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11953                                "-b", "crash",
11954                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11955
11956                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11957                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11958                        input = new InputStreamReader(logcat.getInputStream());
11959
11960                        int num;
11961                        char[] buf = new char[8192];
11962                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11963                    } catch (IOException e) {
11964                        Slog.e(TAG, "Error running logcat", e);
11965                    } finally {
11966                        if (input != null) try { input.close(); } catch (IOException e) {}
11967                    }
11968                }
11969
11970                dbox.addText(dropboxTag, sb.toString());
11971            }
11972        };
11973
11974        if (process == null) {
11975            // If process is null, we are being called from some internal code
11976            // and may be about to die -- run this synchronously.
11977            worker.run();
11978        } else {
11979            worker.start();
11980        }
11981    }
11982
11983    /**
11984     * Bring up the "unexpected error" dialog box for a crashing app.
11985     * Deal with edge cases (intercepts from instrumented applications,
11986     * ActivityController, error intent receivers, that sort of thing).
11987     * @param r the application crashing
11988     * @param crashInfo describing the failure
11989     */
11990    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11991        long timeMillis = System.currentTimeMillis();
11992        String shortMsg = crashInfo.exceptionClassName;
11993        String longMsg = crashInfo.exceptionMessage;
11994        String stackTrace = crashInfo.stackTrace;
11995        if (shortMsg != null && longMsg != null) {
11996            longMsg = shortMsg + ": " + longMsg;
11997        } else if (shortMsg != null) {
11998            longMsg = shortMsg;
11999        }
12000
12001        AppErrorResult result = new AppErrorResult();
12002        synchronized (this) {
12003            if (mController != null) {
12004                try {
12005                    String name = r != null ? r.processName : null;
12006                    int pid = r != null ? r.pid : Binder.getCallingPid();
12007                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12008                    if (!mController.appCrashed(name, pid,
12009                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12010                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12011                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12012                            Slog.w(TAG, "Skip killing native crashed app " + name
12013                                    + "(" + pid + ") during testing");
12014                        } else {
12015                            Slog.w(TAG, "Force-killing crashed app " + name
12016                                    + " at watcher's request");
12017                            if (r != null) {
12018                                r.kill("crash", true);
12019                            } else {
12020                                // Huh.
12021                                Process.killProcess(pid);
12022                                Process.killProcessGroup(uid, pid);
12023                            }
12024                        }
12025                        return;
12026                    }
12027                } catch (RemoteException e) {
12028                    mController = null;
12029                    Watchdog.getInstance().setActivityController(null);
12030                }
12031            }
12032
12033            final long origId = Binder.clearCallingIdentity();
12034
12035            // If this process is running instrumentation, finish it.
12036            if (r != null && r.instrumentationClass != null) {
12037                Slog.w(TAG, "Error in app " + r.processName
12038                      + " running instrumentation " + r.instrumentationClass + ":");
12039                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12040                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12041                Bundle info = new Bundle();
12042                info.putString("shortMsg", shortMsg);
12043                info.putString("longMsg", longMsg);
12044                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12045                Binder.restoreCallingIdentity(origId);
12046                return;
12047            }
12048
12049            // Log crash in battery stats.
12050            if (r != null) {
12051                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12052            }
12053
12054            // If we can't identify the process or it's already exceeded its crash quota,
12055            // quit right away without showing a crash dialog.
12056            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12057                Binder.restoreCallingIdentity(origId);
12058                return;
12059            }
12060
12061            Message msg = Message.obtain();
12062            msg.what = SHOW_ERROR_MSG;
12063            HashMap data = new HashMap();
12064            data.put("result", result);
12065            data.put("app", r);
12066            msg.obj = data;
12067            mUiHandler.sendMessage(msg);
12068
12069            Binder.restoreCallingIdentity(origId);
12070        }
12071
12072        int res = result.get();
12073
12074        Intent appErrorIntent = null;
12075        synchronized (this) {
12076            if (r != null && !r.isolated) {
12077                // XXX Can't keep track of crash time for isolated processes,
12078                // since they don't have a persistent identity.
12079                mProcessCrashTimes.put(r.info.processName, r.uid,
12080                        SystemClock.uptimeMillis());
12081            }
12082            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12083                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12084            }
12085        }
12086
12087        if (appErrorIntent != null) {
12088            try {
12089                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12090            } catch (ActivityNotFoundException e) {
12091                Slog.w(TAG, "bug report receiver dissappeared", e);
12092            }
12093        }
12094    }
12095
12096    Intent createAppErrorIntentLocked(ProcessRecord r,
12097            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12098        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12099        if (report == null) {
12100            return null;
12101        }
12102        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12103        result.setComponent(r.errorReportReceiver);
12104        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12105        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12106        return result;
12107    }
12108
12109    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12110            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12111        if (r.errorReportReceiver == null) {
12112            return null;
12113        }
12114
12115        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12116            return null;
12117        }
12118
12119        ApplicationErrorReport report = new ApplicationErrorReport();
12120        report.packageName = r.info.packageName;
12121        report.installerPackageName = r.errorReportReceiver.getPackageName();
12122        report.processName = r.processName;
12123        report.time = timeMillis;
12124        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12125
12126        if (r.crashing || r.forceCrashReport) {
12127            report.type = ApplicationErrorReport.TYPE_CRASH;
12128            report.crashInfo = crashInfo;
12129        } else if (r.notResponding) {
12130            report.type = ApplicationErrorReport.TYPE_ANR;
12131            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12132
12133            report.anrInfo.activity = r.notRespondingReport.tag;
12134            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12135            report.anrInfo.info = r.notRespondingReport.longMsg;
12136        }
12137
12138        return report;
12139    }
12140
12141    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12142        enforceNotIsolatedCaller("getProcessesInErrorState");
12143        // assume our apps are happy - lazy create the list
12144        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12145
12146        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12147                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12148        int userId = UserHandle.getUserId(Binder.getCallingUid());
12149
12150        synchronized (this) {
12151
12152            // iterate across all processes
12153            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12154                ProcessRecord app = mLruProcesses.get(i);
12155                if (!allUsers && app.userId != userId) {
12156                    continue;
12157                }
12158                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12159                    // This one's in trouble, so we'll generate a report for it
12160                    // crashes are higher priority (in case there's a crash *and* an anr)
12161                    ActivityManager.ProcessErrorStateInfo report = null;
12162                    if (app.crashing) {
12163                        report = app.crashingReport;
12164                    } else if (app.notResponding) {
12165                        report = app.notRespondingReport;
12166                    }
12167
12168                    if (report != null) {
12169                        if (errList == null) {
12170                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12171                        }
12172                        errList.add(report);
12173                    } else {
12174                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12175                                " crashing = " + app.crashing +
12176                                " notResponding = " + app.notResponding);
12177                    }
12178                }
12179            }
12180        }
12181
12182        return errList;
12183    }
12184
12185    static int procStateToImportance(int procState, int memAdj,
12186            ActivityManager.RunningAppProcessInfo currApp) {
12187        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12188        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12189            currApp.lru = memAdj;
12190        } else {
12191            currApp.lru = 0;
12192        }
12193        return imp;
12194    }
12195
12196    private void fillInProcMemInfo(ProcessRecord app,
12197            ActivityManager.RunningAppProcessInfo outInfo) {
12198        outInfo.pid = app.pid;
12199        outInfo.uid = app.info.uid;
12200        if (mHeavyWeightProcess == app) {
12201            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12202        }
12203        if (app.persistent) {
12204            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12205        }
12206        if (app.activities.size() > 0) {
12207            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12208        }
12209        outInfo.lastTrimLevel = app.trimMemoryLevel;
12210        int adj = app.curAdj;
12211        int procState = app.curProcState;
12212        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12213        outInfo.importanceReasonCode = app.adjTypeCode;
12214        outInfo.processState = app.curProcState;
12215    }
12216
12217    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12218        enforceNotIsolatedCaller("getRunningAppProcesses");
12219
12220        final int callingUid = Binder.getCallingUid();
12221
12222        // Lazy instantiation of list
12223        List<ActivityManager.RunningAppProcessInfo> runList = null;
12224        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12225                callingUid) == PackageManager.PERMISSION_GRANTED;
12226        final int userId = UserHandle.getUserId(callingUid);
12227        final boolean allUids = isGetTasksAllowed(
12228                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12229
12230        synchronized (this) {
12231            // Iterate across all processes
12232            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12233                ProcessRecord app = mLruProcesses.get(i);
12234                if ((!allUsers && app.userId != userId)
12235                        || (!allUids && app.uid != callingUid)) {
12236                    continue;
12237                }
12238                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12239                    // Generate process state info for running application
12240                    ActivityManager.RunningAppProcessInfo currApp =
12241                        new ActivityManager.RunningAppProcessInfo(app.processName,
12242                                app.pid, app.getPackageList());
12243                    fillInProcMemInfo(app, currApp);
12244                    if (app.adjSource instanceof ProcessRecord) {
12245                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12246                        currApp.importanceReasonImportance =
12247                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12248                                        app.adjSourceProcState);
12249                    } else if (app.adjSource instanceof ActivityRecord) {
12250                        ActivityRecord r = (ActivityRecord)app.adjSource;
12251                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12252                    }
12253                    if (app.adjTarget instanceof ComponentName) {
12254                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12255                    }
12256                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12257                    //        + " lru=" + currApp.lru);
12258                    if (runList == null) {
12259                        runList = new ArrayList<>();
12260                    }
12261                    runList.add(currApp);
12262                }
12263            }
12264        }
12265        return runList;
12266    }
12267
12268    public List<ApplicationInfo> getRunningExternalApplications() {
12269        enforceNotIsolatedCaller("getRunningExternalApplications");
12270        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12271        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12272        if (runningApps != null && runningApps.size() > 0) {
12273            Set<String> extList = new HashSet<String>();
12274            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12275                if (app.pkgList != null) {
12276                    for (String pkg : app.pkgList) {
12277                        extList.add(pkg);
12278                    }
12279                }
12280            }
12281            IPackageManager pm = AppGlobals.getPackageManager();
12282            for (String pkg : extList) {
12283                try {
12284                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12285                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12286                        retList.add(info);
12287                    }
12288                } catch (RemoteException e) {
12289                }
12290            }
12291        }
12292        return retList;
12293    }
12294
12295    @Override
12296    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12297        enforceNotIsolatedCaller("getMyMemoryState");
12298        synchronized (this) {
12299            ProcessRecord proc;
12300            synchronized (mPidsSelfLocked) {
12301                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12302            }
12303            fillInProcMemInfo(proc, outInfo);
12304        }
12305    }
12306
12307    @Override
12308    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12309        if (checkCallingPermission(android.Manifest.permission.DUMP)
12310                != PackageManager.PERMISSION_GRANTED) {
12311            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12312                    + Binder.getCallingPid()
12313                    + ", uid=" + Binder.getCallingUid()
12314                    + " without permission "
12315                    + android.Manifest.permission.DUMP);
12316            return;
12317        }
12318
12319        boolean dumpAll = false;
12320        boolean dumpClient = false;
12321        String dumpPackage = null;
12322
12323        int opti = 0;
12324        while (opti < args.length) {
12325            String opt = args[opti];
12326            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12327                break;
12328            }
12329            opti++;
12330            if ("-a".equals(opt)) {
12331                dumpAll = true;
12332            } else if ("-c".equals(opt)) {
12333                dumpClient = true;
12334            } else if ("-p".equals(opt)) {
12335                if (opti < args.length) {
12336                    dumpPackage = args[opti];
12337                    opti++;
12338                } else {
12339                    pw.println("Error: -p option requires package argument");
12340                    return;
12341                }
12342                dumpClient = true;
12343            } else if ("-h".equals(opt)) {
12344                pw.println("Activity manager dump options:");
12345                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12346                pw.println("  cmd may be one of:");
12347                pw.println("    a[ctivities]: activity stack state");
12348                pw.println("    r[recents]: recent activities state");
12349                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12350                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12351                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12352                pw.println("    o[om]: out of memory management");
12353                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12354                pw.println("    provider [COMP_SPEC]: provider client-side state");
12355                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12356                pw.println("    as[sociations]: tracked app associations");
12357                pw.println("    service [COMP_SPEC]: service client-side state");
12358                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12359                pw.println("    all: dump all activities");
12360                pw.println("    top: dump the top activity");
12361                pw.println("    write: write all pending state to storage");
12362                pw.println("    track-associations: enable association tracking");
12363                pw.println("    untrack-associations: disable and clear association tracking");
12364                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12365                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12366                pw.println("    a partial substring in a component name, a");
12367                pw.println("    hex object identifier.");
12368                pw.println("  -a: include all available server state.");
12369                pw.println("  -c: include client state.");
12370                pw.println("  -p: limit output to given package.");
12371                return;
12372            } else {
12373                pw.println("Unknown argument: " + opt + "; use -h for help");
12374            }
12375        }
12376
12377        long origId = Binder.clearCallingIdentity();
12378        boolean more = false;
12379        // Is the caller requesting to dump a particular piece of data?
12380        if (opti < args.length) {
12381            String cmd = args[opti];
12382            opti++;
12383            if ("activities".equals(cmd) || "a".equals(cmd)) {
12384                synchronized (this) {
12385                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12386                }
12387            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12388                synchronized (this) {
12389                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12390                }
12391            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12392                String[] newArgs;
12393                String name;
12394                if (opti >= args.length) {
12395                    name = null;
12396                    newArgs = EMPTY_STRING_ARRAY;
12397                } else {
12398                    dumpPackage = args[opti];
12399                    opti++;
12400                    newArgs = new String[args.length - opti];
12401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12402                            args.length - opti);
12403                }
12404                synchronized (this) {
12405                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12406                }
12407            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12408                String[] newArgs;
12409                String name;
12410                if (opti >= args.length) {
12411                    name = null;
12412                    newArgs = EMPTY_STRING_ARRAY;
12413                } else {
12414                    dumpPackage = args[opti];
12415                    opti++;
12416                    newArgs = new String[args.length - opti];
12417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12418                            args.length - opti);
12419                }
12420                synchronized (this) {
12421                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12422                }
12423            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12424                String[] newArgs;
12425                String name;
12426                if (opti >= args.length) {
12427                    name = null;
12428                    newArgs = EMPTY_STRING_ARRAY;
12429                } else {
12430                    dumpPackage = args[opti];
12431                    opti++;
12432                    newArgs = new String[args.length - opti];
12433                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12434                            args.length - opti);
12435                }
12436                synchronized (this) {
12437                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12438                }
12439            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12440                synchronized (this) {
12441                    dumpOomLocked(fd, pw, args, opti, true);
12442                }
12443            } else if ("provider".equals(cmd)) {
12444                String[] newArgs;
12445                String name;
12446                if (opti >= args.length) {
12447                    name = null;
12448                    newArgs = EMPTY_STRING_ARRAY;
12449                } else {
12450                    name = args[opti];
12451                    opti++;
12452                    newArgs = new String[args.length - opti];
12453                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12454                }
12455                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12456                    pw.println("No providers match: " + name);
12457                    pw.println("Use -h for help.");
12458                }
12459            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12460                synchronized (this) {
12461                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12462                }
12463            } else if ("service".equals(cmd)) {
12464                String[] newArgs;
12465                String name;
12466                if (opti >= args.length) {
12467                    name = null;
12468                    newArgs = EMPTY_STRING_ARRAY;
12469                } else {
12470                    name = args[opti];
12471                    opti++;
12472                    newArgs = new String[args.length - opti];
12473                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12474                            args.length - opti);
12475                }
12476                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12477                    pw.println("No services match: " + name);
12478                    pw.println("Use -h for help.");
12479                }
12480            } else if ("package".equals(cmd)) {
12481                String[] newArgs;
12482                if (opti >= args.length) {
12483                    pw.println("package: no package name specified");
12484                    pw.println("Use -h for help.");
12485                } else {
12486                    dumpPackage = args[opti];
12487                    opti++;
12488                    newArgs = new String[args.length - opti];
12489                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12490                            args.length - opti);
12491                    args = newArgs;
12492                    opti = 0;
12493                    more = true;
12494                }
12495            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12496                synchronized (this) {
12497                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12498                }
12499            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12500                synchronized (this) {
12501                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12502                }
12503            } else if ("write".equals(cmd)) {
12504                mTaskPersister.flush();
12505                pw.println("All tasks persisted.");
12506                return;
12507            } else if ("track-associations".equals(cmd)) {
12508                synchronized (this) {
12509                    if (!mTrackingAssociations) {
12510                        mTrackingAssociations = true;
12511                        pw.println("Association tracking started.");
12512                    } else {
12513                        pw.println("Association tracking already enabled.");
12514                    }
12515                }
12516                return;
12517            } else if ("untrack-associations".equals(cmd)) {
12518                synchronized (this) {
12519                    if (mTrackingAssociations) {
12520                        mTrackingAssociations = false;
12521                        mAssociations.clear();
12522                        pw.println("Association tracking stopped.");
12523                    } else {
12524                        pw.println("Association tracking not running.");
12525                    }
12526                }
12527                return;
12528            } else {
12529                // Dumping a single activity?
12530                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12531                    pw.println("Bad activity command, or no activities match: " + cmd);
12532                    pw.println("Use -h for help.");
12533                }
12534            }
12535            if (!more) {
12536                Binder.restoreCallingIdentity(origId);
12537                return;
12538            }
12539        }
12540
12541        // No piece of data specified, dump everything.
12542        synchronized (this) {
12543            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12544            pw.println();
12545            if (dumpAll) {
12546                pw.println("-------------------------------------------------------------------------------");
12547            }
12548            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12549            pw.println();
12550            if (dumpAll) {
12551                pw.println("-------------------------------------------------------------------------------");
12552            }
12553            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12554            pw.println();
12555            if (dumpAll) {
12556                pw.println("-------------------------------------------------------------------------------");
12557            }
12558            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12559            pw.println();
12560            if (dumpAll) {
12561                pw.println("-------------------------------------------------------------------------------");
12562            }
12563            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12564            pw.println();
12565            if (dumpAll) {
12566                pw.println("-------------------------------------------------------------------------------");
12567            }
12568            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12569            if (mAssociations.size() > 0) {
12570                pw.println();
12571                if (dumpAll) {
12572                    pw.println("-------------------------------------------------------------------------------");
12573                }
12574                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12575            }
12576            pw.println();
12577            if (dumpAll) {
12578                pw.println("-------------------------------------------------------------------------------");
12579            }
12580            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12581        }
12582        Binder.restoreCallingIdentity(origId);
12583    }
12584
12585    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12586            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12587        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12588
12589        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12590                dumpPackage);
12591        boolean needSep = printedAnything;
12592
12593        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12594                dumpPackage, needSep, "  mFocusedActivity: ");
12595        if (printed) {
12596            printedAnything = true;
12597            needSep = false;
12598        }
12599
12600        if (dumpPackage == null) {
12601            if (needSep) {
12602                pw.println();
12603            }
12604            needSep = true;
12605            printedAnything = true;
12606            mStackSupervisor.dump(pw, "  ");
12607        }
12608
12609        if (!printedAnything) {
12610            pw.println("  (nothing)");
12611        }
12612    }
12613
12614    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12615            int opti, boolean dumpAll, String dumpPackage) {
12616        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12617
12618        boolean printedAnything = false;
12619
12620        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12621            boolean printedHeader = false;
12622
12623            final int N = mRecentTasks.size();
12624            for (int i=0; i<N; i++) {
12625                TaskRecord tr = mRecentTasks.get(i);
12626                if (dumpPackage != null) {
12627                    if (tr.realActivity == null ||
12628                            !dumpPackage.equals(tr.realActivity)) {
12629                        continue;
12630                    }
12631                }
12632                if (!printedHeader) {
12633                    pw.println("  Recent tasks:");
12634                    printedHeader = true;
12635                    printedAnything = true;
12636                }
12637                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12638                        pw.println(tr);
12639                if (dumpAll) {
12640                    mRecentTasks.get(i).dump(pw, "    ");
12641                }
12642            }
12643        }
12644
12645        if (!printedAnything) {
12646            pw.println("  (nothing)");
12647        }
12648    }
12649
12650    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12651            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12652        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12653
12654        int dumpUid = 0;
12655        if (dumpPackage != null) {
12656            IPackageManager pm = AppGlobals.getPackageManager();
12657            try {
12658                dumpUid = pm.getPackageUid(dumpPackage, 0);
12659            } catch (RemoteException e) {
12660            }
12661        }
12662
12663        boolean printedAnything = false;
12664
12665        final long now = SystemClock.uptimeMillis();
12666
12667        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12668            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12669                    = mAssociations.valueAt(i1);
12670            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12671                SparseArray<ArrayMap<String, Association>> sourceUids
12672                        = targetComponents.valueAt(i2);
12673                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12674                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12675                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12676                        Association ass = sourceProcesses.valueAt(i4);
12677                        if (dumpPackage != null) {
12678                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12679                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12680                                continue;
12681                            }
12682                        }
12683                        printedAnything = true;
12684                        pw.print("  ");
12685                        pw.print(ass.mTargetProcess);
12686                        pw.print("/");
12687                        UserHandle.formatUid(pw, ass.mTargetUid);
12688                        pw.print(" <- ");
12689                        pw.print(ass.mSourceProcess);
12690                        pw.print("/");
12691                        UserHandle.formatUid(pw, ass.mSourceUid);
12692                        pw.println();
12693                        pw.print("    via ");
12694                        pw.print(ass.mTargetComponent.flattenToShortString());
12695                        pw.println();
12696                        pw.print("    ");
12697                        long dur = ass.mTime;
12698                        if (ass.mNesting > 0) {
12699                            dur += now - ass.mStartTime;
12700                        }
12701                        TimeUtils.formatDuration(dur, pw);
12702                        pw.print(" (");
12703                        pw.print(ass.mCount);
12704                        pw.println(" times)");
12705                        if (ass.mNesting > 0) {
12706                            pw.print("    ");
12707                            pw.print(" Currently active: ");
12708                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12709                            pw.println();
12710                        }
12711                    }
12712                }
12713            }
12714
12715        }
12716
12717        if (!printedAnything) {
12718            pw.println("  (nothing)");
12719        }
12720    }
12721
12722    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12723            int opti, boolean dumpAll, String dumpPackage) {
12724        boolean needSep = false;
12725        boolean printedAnything = false;
12726        int numPers = 0;
12727
12728        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12729
12730        if (dumpAll) {
12731            final int NP = mProcessNames.getMap().size();
12732            for (int ip=0; ip<NP; ip++) {
12733                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12734                final int NA = procs.size();
12735                for (int ia=0; ia<NA; ia++) {
12736                    ProcessRecord r = procs.valueAt(ia);
12737                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12738                        continue;
12739                    }
12740                    if (!needSep) {
12741                        pw.println("  All known processes:");
12742                        needSep = true;
12743                        printedAnything = true;
12744                    }
12745                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12746                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12747                        pw.print(" "); pw.println(r);
12748                    r.dump(pw, "    ");
12749                    if (r.persistent) {
12750                        numPers++;
12751                    }
12752                }
12753            }
12754        }
12755
12756        if (mIsolatedProcesses.size() > 0) {
12757            boolean printed = false;
12758            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12759                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12760                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12761                    continue;
12762                }
12763                if (!printed) {
12764                    if (needSep) {
12765                        pw.println();
12766                    }
12767                    pw.println("  Isolated process list (sorted by uid):");
12768                    printedAnything = true;
12769                    printed = true;
12770                    needSep = true;
12771                }
12772                pw.println(String.format("%sIsolated #%2d: %s",
12773                        "    ", i, r.toString()));
12774            }
12775        }
12776
12777        if (mLruProcesses.size() > 0) {
12778            if (needSep) {
12779                pw.println();
12780            }
12781            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12782                    pw.print(" total, non-act at ");
12783                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12784                    pw.print(", non-svc at ");
12785                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12786                    pw.println("):");
12787            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12788            needSep = true;
12789            printedAnything = true;
12790        }
12791
12792        if (dumpAll || dumpPackage != null) {
12793            synchronized (mPidsSelfLocked) {
12794                boolean printed = false;
12795                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12796                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12797                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12798                        continue;
12799                    }
12800                    if (!printed) {
12801                        if (needSep) pw.println();
12802                        needSep = true;
12803                        pw.println("  PID mappings:");
12804                        printed = true;
12805                        printedAnything = true;
12806                    }
12807                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12808                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12809                }
12810            }
12811        }
12812
12813        if (mForegroundProcesses.size() > 0) {
12814            synchronized (mPidsSelfLocked) {
12815                boolean printed = false;
12816                for (int i=0; i<mForegroundProcesses.size(); i++) {
12817                    ProcessRecord r = mPidsSelfLocked.get(
12818                            mForegroundProcesses.valueAt(i).pid);
12819                    if (dumpPackage != null && (r == null
12820                            || !r.pkgList.containsKey(dumpPackage))) {
12821                        continue;
12822                    }
12823                    if (!printed) {
12824                        if (needSep) pw.println();
12825                        needSep = true;
12826                        pw.println("  Foreground Processes:");
12827                        printed = true;
12828                        printedAnything = true;
12829                    }
12830                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12831                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12832                }
12833            }
12834        }
12835
12836        if (mPersistentStartingProcesses.size() > 0) {
12837            if (needSep) pw.println();
12838            needSep = true;
12839            printedAnything = true;
12840            pw.println("  Persisent processes that are starting:");
12841            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12842                    "Starting Norm", "Restarting PERS", dumpPackage);
12843        }
12844
12845        if (mRemovedProcesses.size() > 0) {
12846            if (needSep) pw.println();
12847            needSep = true;
12848            printedAnything = true;
12849            pw.println("  Processes that are being removed:");
12850            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12851                    "Removed Norm", "Removed PERS", dumpPackage);
12852        }
12853
12854        if (mProcessesOnHold.size() > 0) {
12855            if (needSep) pw.println();
12856            needSep = true;
12857            printedAnything = true;
12858            pw.println("  Processes that are on old until the system is ready:");
12859            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12860                    "OnHold Norm", "OnHold PERS", dumpPackage);
12861        }
12862
12863        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12864
12865        if (mProcessCrashTimes.getMap().size() > 0) {
12866            boolean printed = false;
12867            long now = SystemClock.uptimeMillis();
12868            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12869            final int NP = pmap.size();
12870            for (int ip=0; ip<NP; ip++) {
12871                String pname = pmap.keyAt(ip);
12872                SparseArray<Long> uids = pmap.valueAt(ip);
12873                final int N = uids.size();
12874                for (int i=0; i<N; i++) {
12875                    int puid = uids.keyAt(i);
12876                    ProcessRecord r = mProcessNames.get(pname, puid);
12877                    if (dumpPackage != null && (r == null
12878                            || !r.pkgList.containsKey(dumpPackage))) {
12879                        continue;
12880                    }
12881                    if (!printed) {
12882                        if (needSep) pw.println();
12883                        needSep = true;
12884                        pw.println("  Time since processes crashed:");
12885                        printed = true;
12886                        printedAnything = true;
12887                    }
12888                    pw.print("    Process "); pw.print(pname);
12889                            pw.print(" uid "); pw.print(puid);
12890                            pw.print(": last crashed ");
12891                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12892                            pw.println(" ago");
12893                }
12894            }
12895        }
12896
12897        if (mBadProcesses.getMap().size() > 0) {
12898            boolean printed = false;
12899            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12900            final int NP = pmap.size();
12901            for (int ip=0; ip<NP; ip++) {
12902                String pname = pmap.keyAt(ip);
12903                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12904                final int N = uids.size();
12905                for (int i=0; i<N; i++) {
12906                    int puid = uids.keyAt(i);
12907                    ProcessRecord r = mProcessNames.get(pname, puid);
12908                    if (dumpPackage != null && (r == null
12909                            || !r.pkgList.containsKey(dumpPackage))) {
12910                        continue;
12911                    }
12912                    if (!printed) {
12913                        if (needSep) pw.println();
12914                        needSep = true;
12915                        pw.println("  Bad processes:");
12916                        printedAnything = true;
12917                    }
12918                    BadProcessInfo info = uids.valueAt(i);
12919                    pw.print("    Bad process "); pw.print(pname);
12920                            pw.print(" uid "); pw.print(puid);
12921                            pw.print(": crashed at time "); pw.println(info.time);
12922                    if (info.shortMsg != null) {
12923                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12924                    }
12925                    if (info.longMsg != null) {
12926                        pw.print("      Long msg: "); pw.println(info.longMsg);
12927                    }
12928                    if (info.stack != null) {
12929                        pw.println("      Stack:");
12930                        int lastPos = 0;
12931                        for (int pos=0; pos<info.stack.length(); pos++) {
12932                            if (info.stack.charAt(pos) == '\n') {
12933                                pw.print("        ");
12934                                pw.write(info.stack, lastPos, pos-lastPos);
12935                                pw.println();
12936                                lastPos = pos+1;
12937                            }
12938                        }
12939                        if (lastPos < info.stack.length()) {
12940                            pw.print("        ");
12941                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12942                            pw.println();
12943                        }
12944                    }
12945                }
12946            }
12947        }
12948
12949        if (dumpPackage == null) {
12950            pw.println();
12951            needSep = false;
12952            pw.println("  mStartedUsers:");
12953            for (int i=0; i<mStartedUsers.size(); i++) {
12954                UserStartedState uss = mStartedUsers.valueAt(i);
12955                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12956                        pw.print(": "); uss.dump("", pw);
12957            }
12958            pw.print("  mStartedUserArray: [");
12959            for (int i=0; i<mStartedUserArray.length; i++) {
12960                if (i > 0) pw.print(", ");
12961                pw.print(mStartedUserArray[i]);
12962            }
12963            pw.println("]");
12964            pw.print("  mUserLru: [");
12965            for (int i=0; i<mUserLru.size(); i++) {
12966                if (i > 0) pw.print(", ");
12967                pw.print(mUserLru.get(i));
12968            }
12969            pw.println("]");
12970            if (dumpAll) {
12971                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12972            }
12973            synchronized (mUserProfileGroupIdsSelfLocked) {
12974                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12975                    pw.println("  mUserProfileGroupIds:");
12976                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12977                        pw.print("    User #");
12978                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12979                        pw.print(" -> profile #");
12980                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12981                    }
12982                }
12983            }
12984        }
12985        if (mHomeProcess != null && (dumpPackage == null
12986                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12987            if (needSep) {
12988                pw.println();
12989                needSep = false;
12990            }
12991            pw.println("  mHomeProcess: " + mHomeProcess);
12992        }
12993        if (mPreviousProcess != null && (dumpPackage == null
12994                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12995            if (needSep) {
12996                pw.println();
12997                needSep = false;
12998            }
12999            pw.println("  mPreviousProcess: " + mPreviousProcess);
13000        }
13001        if (dumpAll) {
13002            StringBuilder sb = new StringBuilder(128);
13003            sb.append("  mPreviousProcessVisibleTime: ");
13004            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13005            pw.println(sb);
13006        }
13007        if (mHeavyWeightProcess != null && (dumpPackage == null
13008                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13009            if (needSep) {
13010                pw.println();
13011                needSep = false;
13012            }
13013            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13014        }
13015        if (dumpPackage == null) {
13016            pw.println("  mConfiguration: " + mConfiguration);
13017        }
13018        if (dumpAll) {
13019            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13020            if (mCompatModePackages.getPackages().size() > 0) {
13021                boolean printed = false;
13022                for (Map.Entry<String, Integer> entry
13023                        : mCompatModePackages.getPackages().entrySet()) {
13024                    String pkg = entry.getKey();
13025                    int mode = entry.getValue();
13026                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13027                        continue;
13028                    }
13029                    if (!printed) {
13030                        pw.println("  mScreenCompatPackages:");
13031                        printed = true;
13032                    }
13033                    pw.print("    "); pw.print(pkg); pw.print(": ");
13034                            pw.print(mode); pw.println();
13035                }
13036            }
13037        }
13038        if (dumpPackage == null) {
13039            pw.println("  mWakefulness="
13040                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13041            pw.println("  mSleepTokens=" + mSleepTokens);
13042            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13043                    + lockScreenShownToString());
13044            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13045            if (mRunningVoice != null) {
13046                pw.println("  mRunningVoice=" + mRunningVoice);
13047                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13048            }
13049        }
13050        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13051                || mOrigWaitForDebugger) {
13052            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13053                    || dumpPackage.equals(mOrigDebugApp)) {
13054                if (needSep) {
13055                    pw.println();
13056                    needSep = false;
13057                }
13058                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13059                        + " mDebugTransient=" + mDebugTransient
13060                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13061            }
13062        }
13063        if (mMemWatchProcesses.getMap().size() > 0) {
13064            pw.println("  Mem watch processes:");
13065            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13066                    = mMemWatchProcesses.getMap();
13067            for (int i=0; i<procs.size(); i++) {
13068                final String proc = procs.keyAt(i);
13069                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13070                for (int j=0; j<uids.size(); j++) {
13071                    if (needSep) {
13072                        pw.println();
13073                        needSep = false;
13074                    }
13075                    StringBuilder sb = new StringBuilder();
13076                    sb.append("    ").append(proc).append('/');
13077                    UserHandle.formatUid(sb, uids.keyAt(j));
13078                    Pair<Long, String> val = uids.valueAt(j);
13079                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13080                    if (val.second != null) {
13081                        sb.append(", report to ").append(val.second);
13082                    }
13083                    pw.println(sb.toString());
13084                }
13085            }
13086            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13087            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13088            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13089                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13090        }
13091        if (mOpenGlTraceApp != null) {
13092            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13093                if (needSep) {
13094                    pw.println();
13095                    needSep = false;
13096                }
13097                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13098            }
13099        }
13100        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13101                || mProfileFd != null) {
13102            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13103                if (needSep) {
13104                    pw.println();
13105                    needSep = false;
13106                }
13107                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13108                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13109                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13110                        + mAutoStopProfiler);
13111                pw.println("  mProfileType=" + mProfileType);
13112            }
13113        }
13114        if (dumpPackage == null) {
13115            if (mAlwaysFinishActivities || mController != null) {
13116                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13117                        + " mController=" + mController);
13118            }
13119            if (dumpAll) {
13120                pw.println("  Total persistent processes: " + numPers);
13121                pw.println("  mProcessesReady=" + mProcessesReady
13122                        + " mSystemReady=" + mSystemReady
13123                        + " mBooted=" + mBooted
13124                        + " mFactoryTest=" + mFactoryTest);
13125                pw.println("  mBooting=" + mBooting
13126                        + " mCallFinishBooting=" + mCallFinishBooting
13127                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13128                pw.print("  mLastPowerCheckRealtime=");
13129                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13130                        pw.println("");
13131                pw.print("  mLastPowerCheckUptime=");
13132                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13133                        pw.println("");
13134                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13135                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13136                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13137                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13138                        + " (" + mLruProcesses.size() + " total)"
13139                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13140                        + " mNumServiceProcs=" + mNumServiceProcs
13141                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13142                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13143                        + " mLastMemoryLevel" + mLastMemoryLevel
13144                        + " mLastNumProcesses" + mLastNumProcesses);
13145                long now = SystemClock.uptimeMillis();
13146                pw.print("  mLastIdleTime=");
13147                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13148                        pw.print(" mLowRamSinceLastIdle=");
13149                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13150                        pw.println();
13151            }
13152        }
13153
13154        if (!printedAnything) {
13155            pw.println("  (nothing)");
13156        }
13157    }
13158
13159    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13160            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13161        if (mProcessesToGc.size() > 0) {
13162            boolean printed = false;
13163            long now = SystemClock.uptimeMillis();
13164            for (int i=0; i<mProcessesToGc.size(); i++) {
13165                ProcessRecord proc = mProcessesToGc.get(i);
13166                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13167                    continue;
13168                }
13169                if (!printed) {
13170                    if (needSep) pw.println();
13171                    needSep = true;
13172                    pw.println("  Processes that are waiting to GC:");
13173                    printed = true;
13174                }
13175                pw.print("    Process "); pw.println(proc);
13176                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13177                        pw.print(", last gced=");
13178                        pw.print(now-proc.lastRequestedGc);
13179                        pw.print(" ms ago, last lowMem=");
13180                        pw.print(now-proc.lastLowMemory);
13181                        pw.println(" ms ago");
13182
13183            }
13184        }
13185        return needSep;
13186    }
13187
13188    void printOomLevel(PrintWriter pw, String name, int adj) {
13189        pw.print("    ");
13190        if (adj >= 0) {
13191            pw.print(' ');
13192            if (adj < 10) pw.print(' ');
13193        } else {
13194            if (adj > -10) pw.print(' ');
13195        }
13196        pw.print(adj);
13197        pw.print(": ");
13198        pw.print(name);
13199        pw.print(" (");
13200        pw.print(mProcessList.getMemLevel(adj)/1024);
13201        pw.println(" kB)");
13202    }
13203
13204    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13205            int opti, boolean dumpAll) {
13206        boolean needSep = false;
13207
13208        if (mLruProcesses.size() > 0) {
13209            if (needSep) pw.println();
13210            needSep = true;
13211            pw.println("  OOM levels:");
13212            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13213            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13214            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13215            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13216            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13217            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13218            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13219            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13220            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13221            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13222            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13223            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13224            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13225            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13226
13227            if (needSep) pw.println();
13228            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13229                    pw.print(" total, non-act at ");
13230                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13231                    pw.print(", non-svc at ");
13232                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13233                    pw.println("):");
13234            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13235            needSep = true;
13236        }
13237
13238        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13239
13240        pw.println();
13241        pw.println("  mHomeProcess: " + mHomeProcess);
13242        pw.println("  mPreviousProcess: " + mPreviousProcess);
13243        if (mHeavyWeightProcess != null) {
13244            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13245        }
13246
13247        return true;
13248    }
13249
13250    /**
13251     * There are three ways to call this:
13252     *  - no provider specified: dump all the providers
13253     *  - a flattened component name that matched an existing provider was specified as the
13254     *    first arg: dump that one provider
13255     *  - the first arg isn't the flattened component name of an existing provider:
13256     *    dump all providers whose component contains the first arg as a substring
13257     */
13258    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13259            int opti, boolean dumpAll) {
13260        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13261    }
13262
13263    static class ItemMatcher {
13264        ArrayList<ComponentName> components;
13265        ArrayList<String> strings;
13266        ArrayList<Integer> objects;
13267        boolean all;
13268
13269        ItemMatcher() {
13270            all = true;
13271        }
13272
13273        void build(String name) {
13274            ComponentName componentName = ComponentName.unflattenFromString(name);
13275            if (componentName != null) {
13276                if (components == null) {
13277                    components = new ArrayList<ComponentName>();
13278                }
13279                components.add(componentName);
13280                all = false;
13281            } else {
13282                int objectId = 0;
13283                // Not a '/' separated full component name; maybe an object ID?
13284                try {
13285                    objectId = Integer.parseInt(name, 16);
13286                    if (objects == null) {
13287                        objects = new ArrayList<Integer>();
13288                    }
13289                    objects.add(objectId);
13290                    all = false;
13291                } catch (RuntimeException e) {
13292                    // Not an integer; just do string match.
13293                    if (strings == null) {
13294                        strings = new ArrayList<String>();
13295                    }
13296                    strings.add(name);
13297                    all = false;
13298                }
13299            }
13300        }
13301
13302        int build(String[] args, int opti) {
13303            for (; opti<args.length; opti++) {
13304                String name = args[opti];
13305                if ("--".equals(name)) {
13306                    return opti+1;
13307                }
13308                build(name);
13309            }
13310            return opti;
13311        }
13312
13313        boolean match(Object object, ComponentName comp) {
13314            if (all) {
13315                return true;
13316            }
13317            if (components != null) {
13318                for (int i=0; i<components.size(); i++) {
13319                    if (components.get(i).equals(comp)) {
13320                        return true;
13321                    }
13322                }
13323            }
13324            if (objects != null) {
13325                for (int i=0; i<objects.size(); i++) {
13326                    if (System.identityHashCode(object) == objects.get(i)) {
13327                        return true;
13328                    }
13329                }
13330            }
13331            if (strings != null) {
13332                String flat = comp.flattenToString();
13333                for (int i=0; i<strings.size(); i++) {
13334                    if (flat.contains(strings.get(i))) {
13335                        return true;
13336                    }
13337                }
13338            }
13339            return false;
13340        }
13341    }
13342
13343    /**
13344     * There are three things that cmd can be:
13345     *  - a flattened component name that matches an existing activity
13346     *  - the cmd arg isn't the flattened component name of an existing activity:
13347     *    dump all activity whose component contains the cmd as a substring
13348     *  - A hex number of the ActivityRecord object instance.
13349     */
13350    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13351            int opti, boolean dumpAll) {
13352        ArrayList<ActivityRecord> activities;
13353
13354        synchronized (this) {
13355            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13356        }
13357
13358        if (activities.size() <= 0) {
13359            return false;
13360        }
13361
13362        String[] newArgs = new String[args.length - opti];
13363        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13364
13365        TaskRecord lastTask = null;
13366        boolean needSep = false;
13367        for (int i=activities.size()-1; i>=0; i--) {
13368            ActivityRecord r = activities.get(i);
13369            if (needSep) {
13370                pw.println();
13371            }
13372            needSep = true;
13373            synchronized (this) {
13374                if (lastTask != r.task) {
13375                    lastTask = r.task;
13376                    pw.print("TASK "); pw.print(lastTask.affinity);
13377                            pw.print(" id="); pw.println(lastTask.taskId);
13378                    if (dumpAll) {
13379                        lastTask.dump(pw, "  ");
13380                    }
13381                }
13382            }
13383            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13384        }
13385        return true;
13386    }
13387
13388    /**
13389     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13390     * there is a thread associated with the activity.
13391     */
13392    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13393            final ActivityRecord r, String[] args, boolean dumpAll) {
13394        String innerPrefix = prefix + "  ";
13395        synchronized (this) {
13396            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13397                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13398                    pw.print(" pid=");
13399                    if (r.app != null) pw.println(r.app.pid);
13400                    else pw.println("(not running)");
13401            if (dumpAll) {
13402                r.dump(pw, innerPrefix);
13403            }
13404        }
13405        if (r.app != null && r.app.thread != null) {
13406            // flush anything that is already in the PrintWriter since the thread is going
13407            // to write to the file descriptor directly
13408            pw.flush();
13409            try {
13410                TransferPipe tp = new TransferPipe();
13411                try {
13412                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13413                            r.appToken, innerPrefix, args);
13414                    tp.go(fd);
13415                } finally {
13416                    tp.kill();
13417                }
13418            } catch (IOException e) {
13419                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13420            } catch (RemoteException e) {
13421                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13422            }
13423        }
13424    }
13425
13426    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13427            int opti, boolean dumpAll, String dumpPackage) {
13428        boolean needSep = false;
13429        boolean onlyHistory = false;
13430        boolean printedAnything = false;
13431
13432        if ("history".equals(dumpPackage)) {
13433            if (opti < args.length && "-s".equals(args[opti])) {
13434                dumpAll = false;
13435            }
13436            onlyHistory = true;
13437            dumpPackage = null;
13438        }
13439
13440        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13441        if (!onlyHistory && dumpAll) {
13442            if (mRegisteredReceivers.size() > 0) {
13443                boolean printed = false;
13444                Iterator it = mRegisteredReceivers.values().iterator();
13445                while (it.hasNext()) {
13446                    ReceiverList r = (ReceiverList)it.next();
13447                    if (dumpPackage != null && (r.app == null ||
13448                            !dumpPackage.equals(r.app.info.packageName))) {
13449                        continue;
13450                    }
13451                    if (!printed) {
13452                        pw.println("  Registered Receivers:");
13453                        needSep = true;
13454                        printed = true;
13455                        printedAnything = true;
13456                    }
13457                    pw.print("  * "); pw.println(r);
13458                    r.dump(pw, "    ");
13459                }
13460            }
13461
13462            if (mReceiverResolver.dump(pw, needSep ?
13463                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13464                    "    ", dumpPackage, false, false)) {
13465                needSep = true;
13466                printedAnything = true;
13467            }
13468        }
13469
13470        for (BroadcastQueue q : mBroadcastQueues) {
13471            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13472            printedAnything |= needSep;
13473        }
13474
13475        needSep = true;
13476
13477        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13478            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13479                if (needSep) {
13480                    pw.println();
13481                }
13482                needSep = true;
13483                printedAnything = true;
13484                pw.print("  Sticky broadcasts for user ");
13485                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13486                StringBuilder sb = new StringBuilder(128);
13487                for (Map.Entry<String, ArrayList<Intent>> ent
13488                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13489                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13490                    if (dumpAll) {
13491                        pw.println(":");
13492                        ArrayList<Intent> intents = ent.getValue();
13493                        final int N = intents.size();
13494                        for (int i=0; i<N; i++) {
13495                            sb.setLength(0);
13496                            sb.append("    Intent: ");
13497                            intents.get(i).toShortString(sb, false, true, false, false);
13498                            pw.println(sb.toString());
13499                            Bundle bundle = intents.get(i).getExtras();
13500                            if (bundle != null) {
13501                                pw.print("      ");
13502                                pw.println(bundle.toString());
13503                            }
13504                        }
13505                    } else {
13506                        pw.println("");
13507                    }
13508                }
13509            }
13510        }
13511
13512        if (!onlyHistory && dumpAll) {
13513            pw.println();
13514            for (BroadcastQueue queue : mBroadcastQueues) {
13515                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13516                        + queue.mBroadcastsScheduled);
13517            }
13518            pw.println("  mHandler:");
13519            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13520            needSep = true;
13521            printedAnything = true;
13522        }
13523
13524        if (!printedAnything) {
13525            pw.println("  (nothing)");
13526        }
13527    }
13528
13529    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13530            int opti, boolean dumpAll, String dumpPackage) {
13531        boolean needSep;
13532        boolean printedAnything = false;
13533
13534        ItemMatcher matcher = new ItemMatcher();
13535        matcher.build(args, opti);
13536
13537        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13538
13539        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13540        printedAnything |= needSep;
13541
13542        if (mLaunchingProviders.size() > 0) {
13543            boolean printed = false;
13544            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13545                ContentProviderRecord r = mLaunchingProviders.get(i);
13546                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13547                    continue;
13548                }
13549                if (!printed) {
13550                    if (needSep) pw.println();
13551                    needSep = true;
13552                    pw.println("  Launching content providers:");
13553                    printed = true;
13554                    printedAnything = true;
13555                }
13556                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13557                        pw.println(r);
13558            }
13559        }
13560
13561        if (mGrantedUriPermissions.size() > 0) {
13562            boolean printed = false;
13563            int dumpUid = -2;
13564            if (dumpPackage != null) {
13565                try {
13566                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13567                } catch (NameNotFoundException e) {
13568                    dumpUid = -1;
13569                }
13570            }
13571            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13572                int uid = mGrantedUriPermissions.keyAt(i);
13573                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13574                    continue;
13575                }
13576                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13577                if (!printed) {
13578                    if (needSep) pw.println();
13579                    needSep = true;
13580                    pw.println("  Granted Uri Permissions:");
13581                    printed = true;
13582                    printedAnything = true;
13583                }
13584                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13585                for (UriPermission perm : perms.values()) {
13586                    pw.print("    "); pw.println(perm);
13587                    if (dumpAll) {
13588                        perm.dump(pw, "      ");
13589                    }
13590                }
13591            }
13592        }
13593
13594        if (!printedAnything) {
13595            pw.println("  (nothing)");
13596        }
13597    }
13598
13599    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13600            int opti, boolean dumpAll, String dumpPackage) {
13601        boolean printed = false;
13602
13603        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13604
13605        if (mIntentSenderRecords.size() > 0) {
13606            Iterator<WeakReference<PendingIntentRecord>> it
13607                    = mIntentSenderRecords.values().iterator();
13608            while (it.hasNext()) {
13609                WeakReference<PendingIntentRecord> ref = it.next();
13610                PendingIntentRecord rec = ref != null ? ref.get(): null;
13611                if (dumpPackage != null && (rec == null
13612                        || !dumpPackage.equals(rec.key.packageName))) {
13613                    continue;
13614                }
13615                printed = true;
13616                if (rec != null) {
13617                    pw.print("  * "); pw.println(rec);
13618                    if (dumpAll) {
13619                        rec.dump(pw, "    ");
13620                    }
13621                } else {
13622                    pw.print("  * "); pw.println(ref);
13623                }
13624            }
13625        }
13626
13627        if (!printed) {
13628            pw.println("  (nothing)");
13629        }
13630    }
13631
13632    private static final int dumpProcessList(PrintWriter pw,
13633            ActivityManagerService service, List list,
13634            String prefix, String normalLabel, String persistentLabel,
13635            String dumpPackage) {
13636        int numPers = 0;
13637        final int N = list.size()-1;
13638        for (int i=N; i>=0; i--) {
13639            ProcessRecord r = (ProcessRecord)list.get(i);
13640            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13641                continue;
13642            }
13643            pw.println(String.format("%s%s #%2d: %s",
13644                    prefix, (r.persistent ? persistentLabel : normalLabel),
13645                    i, r.toString()));
13646            if (r.persistent) {
13647                numPers++;
13648            }
13649        }
13650        return numPers;
13651    }
13652
13653    private static final boolean dumpProcessOomList(PrintWriter pw,
13654            ActivityManagerService service, List<ProcessRecord> origList,
13655            String prefix, String normalLabel, String persistentLabel,
13656            boolean inclDetails, String dumpPackage) {
13657
13658        ArrayList<Pair<ProcessRecord, Integer>> list
13659                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13660        for (int i=0; i<origList.size(); i++) {
13661            ProcessRecord r = origList.get(i);
13662            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13663                continue;
13664            }
13665            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13666        }
13667
13668        if (list.size() <= 0) {
13669            return false;
13670        }
13671
13672        Comparator<Pair<ProcessRecord, Integer>> comparator
13673                = new Comparator<Pair<ProcessRecord, Integer>>() {
13674            @Override
13675            public int compare(Pair<ProcessRecord, Integer> object1,
13676                    Pair<ProcessRecord, Integer> object2) {
13677                if (object1.first.setAdj != object2.first.setAdj) {
13678                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13679                }
13680                if (object1.second.intValue() != object2.second.intValue()) {
13681                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13682                }
13683                return 0;
13684            }
13685        };
13686
13687        Collections.sort(list, comparator);
13688
13689        final long curRealtime = SystemClock.elapsedRealtime();
13690        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13691        final long curUptime = SystemClock.uptimeMillis();
13692        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13693
13694        for (int i=list.size()-1; i>=0; i--) {
13695            ProcessRecord r = list.get(i).first;
13696            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13697            char schedGroup;
13698            switch (r.setSchedGroup) {
13699                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13700                    schedGroup = 'B';
13701                    break;
13702                case Process.THREAD_GROUP_DEFAULT:
13703                    schedGroup = 'F';
13704                    break;
13705                default:
13706                    schedGroup = '?';
13707                    break;
13708            }
13709            char foreground;
13710            if (r.foregroundActivities) {
13711                foreground = 'A';
13712            } else if (r.foregroundServices) {
13713                foreground = 'S';
13714            } else {
13715                foreground = ' ';
13716            }
13717            String procState = ProcessList.makeProcStateString(r.curProcState);
13718            pw.print(prefix);
13719            pw.print(r.persistent ? persistentLabel : normalLabel);
13720            pw.print(" #");
13721            int num = (origList.size()-1)-list.get(i).second;
13722            if (num < 10) pw.print(' ');
13723            pw.print(num);
13724            pw.print(": ");
13725            pw.print(oomAdj);
13726            pw.print(' ');
13727            pw.print(schedGroup);
13728            pw.print('/');
13729            pw.print(foreground);
13730            pw.print('/');
13731            pw.print(procState);
13732            pw.print(" trm:");
13733            if (r.trimMemoryLevel < 10) pw.print(' ');
13734            pw.print(r.trimMemoryLevel);
13735            pw.print(' ');
13736            pw.print(r.toShortString());
13737            pw.print(" (");
13738            pw.print(r.adjType);
13739            pw.println(')');
13740            if (r.adjSource != null || r.adjTarget != null) {
13741                pw.print(prefix);
13742                pw.print("    ");
13743                if (r.adjTarget instanceof ComponentName) {
13744                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13745                } else if (r.adjTarget != null) {
13746                    pw.print(r.adjTarget.toString());
13747                } else {
13748                    pw.print("{null}");
13749                }
13750                pw.print("<=");
13751                if (r.adjSource instanceof ProcessRecord) {
13752                    pw.print("Proc{");
13753                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13754                    pw.println("}");
13755                } else if (r.adjSource != null) {
13756                    pw.println(r.adjSource.toString());
13757                } else {
13758                    pw.println("{null}");
13759                }
13760            }
13761            if (inclDetails) {
13762                pw.print(prefix);
13763                pw.print("    ");
13764                pw.print("oom: max="); pw.print(r.maxAdj);
13765                pw.print(" curRaw="); pw.print(r.curRawAdj);
13766                pw.print(" setRaw="); pw.print(r.setRawAdj);
13767                pw.print(" cur="); pw.print(r.curAdj);
13768                pw.print(" set="); pw.println(r.setAdj);
13769                pw.print(prefix);
13770                pw.print("    ");
13771                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13772                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13773                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
13774                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
13775                pw.println();
13776                pw.print(prefix);
13777                pw.print("    ");
13778                pw.print("cached="); pw.print(r.cached);
13779                pw.print(" empty="); pw.print(r.empty);
13780                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13781
13782                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13783                    if (r.lastWakeTime != 0) {
13784                        long wtime;
13785                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13786                        synchronized (stats) {
13787                            wtime = stats.getProcessWakeTime(r.info.uid,
13788                                    r.pid, curRealtime);
13789                        }
13790                        long timeUsed = wtime - r.lastWakeTime;
13791                        pw.print(prefix);
13792                        pw.print("    ");
13793                        pw.print("keep awake over ");
13794                        TimeUtils.formatDuration(realtimeSince, pw);
13795                        pw.print(" used ");
13796                        TimeUtils.formatDuration(timeUsed, pw);
13797                        pw.print(" (");
13798                        pw.print((timeUsed*100)/realtimeSince);
13799                        pw.println("%)");
13800                    }
13801                    if (r.lastCpuTime != 0) {
13802                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13803                        pw.print(prefix);
13804                        pw.print("    ");
13805                        pw.print("run cpu over ");
13806                        TimeUtils.formatDuration(uptimeSince, pw);
13807                        pw.print(" used ");
13808                        TimeUtils.formatDuration(timeUsed, pw);
13809                        pw.print(" (");
13810                        pw.print((timeUsed*100)/uptimeSince);
13811                        pw.println("%)");
13812                    }
13813                }
13814            }
13815        }
13816        return true;
13817    }
13818
13819    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13820            String[] args) {
13821        ArrayList<ProcessRecord> procs;
13822        synchronized (this) {
13823            if (args != null && args.length > start
13824                    && args[start].charAt(0) != '-') {
13825                procs = new ArrayList<ProcessRecord>();
13826                int pid = -1;
13827                try {
13828                    pid = Integer.parseInt(args[start]);
13829                } catch (NumberFormatException e) {
13830                }
13831                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13832                    ProcessRecord proc = mLruProcesses.get(i);
13833                    if (proc.pid == pid) {
13834                        procs.add(proc);
13835                    } else if (allPkgs && proc.pkgList != null
13836                            && proc.pkgList.containsKey(args[start])) {
13837                        procs.add(proc);
13838                    } else if (proc.processName.equals(args[start])) {
13839                        procs.add(proc);
13840                    }
13841                }
13842                if (procs.size() <= 0) {
13843                    return null;
13844                }
13845            } else {
13846                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13847            }
13848        }
13849        return procs;
13850    }
13851
13852    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13853            PrintWriter pw, String[] args) {
13854        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13855        if (procs == null) {
13856            pw.println("No process found for: " + args[0]);
13857            return;
13858        }
13859
13860        long uptime = SystemClock.uptimeMillis();
13861        long realtime = SystemClock.elapsedRealtime();
13862        pw.println("Applications Graphics Acceleration Info:");
13863        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13864
13865        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13866            ProcessRecord r = procs.get(i);
13867            if (r.thread != null) {
13868                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13869                pw.flush();
13870                try {
13871                    TransferPipe tp = new TransferPipe();
13872                    try {
13873                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13874                        tp.go(fd);
13875                    } finally {
13876                        tp.kill();
13877                    }
13878                } catch (IOException e) {
13879                    pw.println("Failure while dumping the app: " + r);
13880                    pw.flush();
13881                } catch (RemoteException e) {
13882                    pw.println("Got a RemoteException while dumping the app " + r);
13883                    pw.flush();
13884                }
13885            }
13886        }
13887    }
13888
13889    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13890        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13891        if (procs == null) {
13892            pw.println("No process found for: " + args[0]);
13893            return;
13894        }
13895
13896        pw.println("Applications Database Info:");
13897
13898        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13899            ProcessRecord r = procs.get(i);
13900            if (r.thread != null) {
13901                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13902                pw.flush();
13903                try {
13904                    TransferPipe tp = new TransferPipe();
13905                    try {
13906                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13907                        tp.go(fd);
13908                    } finally {
13909                        tp.kill();
13910                    }
13911                } catch (IOException e) {
13912                    pw.println("Failure while dumping the app: " + r);
13913                    pw.flush();
13914                } catch (RemoteException e) {
13915                    pw.println("Got a RemoteException while dumping the app " + r);
13916                    pw.flush();
13917                }
13918            }
13919        }
13920    }
13921
13922    final static class MemItem {
13923        final boolean isProc;
13924        final String label;
13925        final String shortLabel;
13926        final long pss;
13927        final int id;
13928        final boolean hasActivities;
13929        ArrayList<MemItem> subitems;
13930
13931        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13932                boolean _hasActivities) {
13933            isProc = true;
13934            label = _label;
13935            shortLabel = _shortLabel;
13936            pss = _pss;
13937            id = _id;
13938            hasActivities = _hasActivities;
13939        }
13940
13941        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13942            isProc = false;
13943            label = _label;
13944            shortLabel = _shortLabel;
13945            pss = _pss;
13946            id = _id;
13947            hasActivities = false;
13948        }
13949    }
13950
13951    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13952            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13953        if (sort && !isCompact) {
13954            Collections.sort(items, new Comparator<MemItem>() {
13955                @Override
13956                public int compare(MemItem lhs, MemItem rhs) {
13957                    if (lhs.pss < rhs.pss) {
13958                        return 1;
13959                    } else if (lhs.pss > rhs.pss) {
13960                        return -1;
13961                    }
13962                    return 0;
13963                }
13964            });
13965        }
13966
13967        for (int i=0; i<items.size(); i++) {
13968            MemItem mi = items.get(i);
13969            if (!isCompact) {
13970                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13971            } else if (mi.isProc) {
13972                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13973                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13974                pw.println(mi.hasActivities ? ",a" : ",e");
13975            } else {
13976                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13977                pw.println(mi.pss);
13978            }
13979            if (mi.subitems != null) {
13980                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13981                        true, isCompact);
13982            }
13983        }
13984    }
13985
13986    // These are in KB.
13987    static final long[] DUMP_MEM_BUCKETS = new long[] {
13988        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13989        120*1024, 160*1024, 200*1024,
13990        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13991        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13992    };
13993
13994    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13995            boolean stackLike) {
13996        int start = label.lastIndexOf('.');
13997        if (start >= 0) start++;
13998        else start = 0;
13999        int end = label.length();
14000        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14001            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14002                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14003                out.append(bucket);
14004                out.append(stackLike ? "MB." : "MB ");
14005                out.append(label, start, end);
14006                return;
14007            }
14008        }
14009        out.append(memKB/1024);
14010        out.append(stackLike ? "MB." : "MB ");
14011        out.append(label, start, end);
14012    }
14013
14014    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14015            ProcessList.NATIVE_ADJ,
14016            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14017            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14018            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14019            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14020            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14021            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14022    };
14023    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14024            "Native",
14025            "System", "Persistent", "Persistent Service", "Foreground",
14026            "Visible", "Perceptible",
14027            "Heavy Weight", "Backup",
14028            "A Services", "Home",
14029            "Previous", "B Services", "Cached"
14030    };
14031    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14032            "native",
14033            "sys", "pers", "persvc", "fore",
14034            "vis", "percept",
14035            "heavy", "backup",
14036            "servicea", "home",
14037            "prev", "serviceb", "cached"
14038    };
14039
14040    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14041            long realtime, boolean isCheckinRequest, boolean isCompact) {
14042        if (isCheckinRequest || isCompact) {
14043            // short checkin version
14044            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14045        } else {
14046            pw.println("Applications Memory Usage (kB):");
14047            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14048        }
14049    }
14050
14051    private static final int KSM_SHARED = 0;
14052    private static final int KSM_SHARING = 1;
14053    private static final int KSM_UNSHARED = 2;
14054    private static final int KSM_VOLATILE = 3;
14055
14056    private final long[] getKsmInfo() {
14057        long[] longOut = new long[4];
14058        final int[] SINGLE_LONG_FORMAT = new int[] {
14059            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14060        };
14061        long[] longTmp = new long[1];
14062        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14063                SINGLE_LONG_FORMAT, null, longTmp, null);
14064        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14065        longTmp[0] = 0;
14066        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14067                SINGLE_LONG_FORMAT, null, longTmp, null);
14068        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14069        longTmp[0] = 0;
14070        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14071                SINGLE_LONG_FORMAT, null, longTmp, null);
14072        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14073        longTmp[0] = 0;
14074        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14075                SINGLE_LONG_FORMAT, null, longTmp, null);
14076        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14077        return longOut;
14078    }
14079
14080    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14081            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14082        boolean dumpDetails = false;
14083        boolean dumpFullDetails = false;
14084        boolean dumpDalvik = false;
14085        boolean oomOnly = false;
14086        boolean isCompact = false;
14087        boolean localOnly = false;
14088        boolean packages = false;
14089
14090        int opti = 0;
14091        while (opti < args.length) {
14092            String opt = args[opti];
14093            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14094                break;
14095            }
14096            opti++;
14097            if ("-a".equals(opt)) {
14098                dumpDetails = true;
14099                dumpFullDetails = true;
14100                dumpDalvik = true;
14101            } else if ("-d".equals(opt)) {
14102                dumpDalvik = true;
14103            } else if ("-c".equals(opt)) {
14104                isCompact = true;
14105            } else if ("--oom".equals(opt)) {
14106                oomOnly = true;
14107            } else if ("--local".equals(opt)) {
14108                localOnly = true;
14109            } else if ("--package".equals(opt)) {
14110                packages = true;
14111            } else if ("-h".equals(opt)) {
14112                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14113                pw.println("  -a: include all available information for each process.");
14114                pw.println("  -d: include dalvik details.");
14115                pw.println("  -c: dump in a compact machine-parseable representation.");
14116                pw.println("  --oom: only show processes organized by oom adj.");
14117                pw.println("  --local: only collect details locally, don't call process.");
14118                pw.println("  --package: interpret process arg as package, dumping all");
14119                pw.println("             processes that have loaded that package.");
14120                pw.println("If [process] is specified it can be the name or ");
14121                pw.println("pid of a specific process to dump.");
14122                return;
14123            } else {
14124                pw.println("Unknown argument: " + opt + "; use -h for help");
14125            }
14126        }
14127
14128        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14129        long uptime = SystemClock.uptimeMillis();
14130        long realtime = SystemClock.elapsedRealtime();
14131        final long[] tmpLong = new long[1];
14132
14133        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14134        if (procs == null) {
14135            // No Java processes.  Maybe they want to print a native process.
14136            if (args != null && args.length > opti
14137                    && args[opti].charAt(0) != '-') {
14138                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14139                        = new ArrayList<ProcessCpuTracker.Stats>();
14140                updateCpuStatsNow();
14141                int findPid = -1;
14142                try {
14143                    findPid = Integer.parseInt(args[opti]);
14144                } catch (NumberFormatException e) {
14145                }
14146                synchronized (mProcessCpuTracker) {
14147                    final int N = mProcessCpuTracker.countStats();
14148                    for (int i=0; i<N; i++) {
14149                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14150                        if (st.pid == findPid || (st.baseName != null
14151                                && st.baseName.equals(args[opti]))) {
14152                            nativeProcs.add(st);
14153                        }
14154                    }
14155                }
14156                if (nativeProcs.size() > 0) {
14157                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14158                            isCompact);
14159                    Debug.MemoryInfo mi = null;
14160                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14161                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14162                        final int pid = r.pid;
14163                        if (!isCheckinRequest && dumpDetails) {
14164                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14165                        }
14166                        if (mi == null) {
14167                            mi = new Debug.MemoryInfo();
14168                        }
14169                        if (dumpDetails || (!brief && !oomOnly)) {
14170                            Debug.getMemoryInfo(pid, mi);
14171                        } else {
14172                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14173                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14174                        }
14175                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14176                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14177                        if (isCheckinRequest) {
14178                            pw.println();
14179                        }
14180                    }
14181                    return;
14182                }
14183            }
14184            pw.println("No process found for: " + args[opti]);
14185            return;
14186        }
14187
14188        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14189            dumpDetails = true;
14190        }
14191
14192        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14193
14194        String[] innerArgs = new String[args.length-opti];
14195        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14196
14197        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14198        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14199        long nativePss = 0;
14200        long dalvikPss = 0;
14201        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14202                EmptyArray.LONG;
14203        long otherPss = 0;
14204        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14205
14206        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14207        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14208                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14209
14210        long totalPss = 0;
14211        long cachedPss = 0;
14212
14213        Debug.MemoryInfo mi = null;
14214        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14215            final ProcessRecord r = procs.get(i);
14216            final IApplicationThread thread;
14217            final int pid;
14218            final int oomAdj;
14219            final boolean hasActivities;
14220            synchronized (this) {
14221                thread = r.thread;
14222                pid = r.pid;
14223                oomAdj = r.getSetAdjWithServices();
14224                hasActivities = r.activities.size() > 0;
14225            }
14226            if (thread != null) {
14227                if (!isCheckinRequest && dumpDetails) {
14228                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14229                }
14230                if (mi == null) {
14231                    mi = new Debug.MemoryInfo();
14232                }
14233                if (dumpDetails || (!brief && !oomOnly)) {
14234                    Debug.getMemoryInfo(pid, mi);
14235                } else {
14236                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14237                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14238                }
14239                if (dumpDetails) {
14240                    if (localOnly) {
14241                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14242                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14243                        if (isCheckinRequest) {
14244                            pw.println();
14245                        }
14246                    } else {
14247                        try {
14248                            pw.flush();
14249                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14250                                    dumpDalvik, innerArgs);
14251                        } catch (RemoteException e) {
14252                            if (!isCheckinRequest) {
14253                                pw.println("Got RemoteException!");
14254                                pw.flush();
14255                            }
14256                        }
14257                    }
14258                }
14259
14260                final long myTotalPss = mi.getTotalPss();
14261                final long myTotalUss = mi.getTotalUss();
14262
14263                synchronized (this) {
14264                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14265                        // Record this for posterity if the process has been stable.
14266                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14267                    }
14268                }
14269
14270                if (!isCheckinRequest && mi != null) {
14271                    totalPss += myTotalPss;
14272                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14273                            (hasActivities ? " / activities)" : ")"),
14274                            r.processName, myTotalPss, pid, hasActivities);
14275                    procMems.add(pssItem);
14276                    procMemsMap.put(pid, pssItem);
14277
14278                    nativePss += mi.nativePss;
14279                    dalvikPss += mi.dalvikPss;
14280                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14281                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14282                    }
14283                    otherPss += mi.otherPss;
14284                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14285                        long mem = mi.getOtherPss(j);
14286                        miscPss[j] += mem;
14287                        otherPss -= mem;
14288                    }
14289
14290                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14291                        cachedPss += myTotalPss;
14292                    }
14293
14294                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14295                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14296                                || oomIndex == (oomPss.length-1)) {
14297                            oomPss[oomIndex] += myTotalPss;
14298                            if (oomProcs[oomIndex] == null) {
14299                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14300                            }
14301                            oomProcs[oomIndex].add(pssItem);
14302                            break;
14303                        }
14304                    }
14305                }
14306            }
14307        }
14308
14309        long nativeProcTotalPss = 0;
14310
14311        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14312            // If we are showing aggregations, also look for native processes to
14313            // include so that our aggregations are more accurate.
14314            updateCpuStatsNow();
14315            mi = null;
14316            synchronized (mProcessCpuTracker) {
14317                final int N = mProcessCpuTracker.countStats();
14318                for (int i=0; i<N; i++) {
14319                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14320                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14321                        if (mi == null) {
14322                            mi = new Debug.MemoryInfo();
14323                        }
14324                        if (!brief && !oomOnly) {
14325                            Debug.getMemoryInfo(st.pid, mi);
14326                        } else {
14327                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14328                            mi.nativePrivateDirty = (int)tmpLong[0];
14329                        }
14330
14331                        final long myTotalPss = mi.getTotalPss();
14332                        totalPss += myTotalPss;
14333                        nativeProcTotalPss += myTotalPss;
14334
14335                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14336                                st.name, myTotalPss, st.pid, false);
14337                        procMems.add(pssItem);
14338
14339                        nativePss += mi.nativePss;
14340                        dalvikPss += mi.dalvikPss;
14341                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14342                            dalvikSubitemPss[j] += mi.getOtherPss(
14343                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14344                        }
14345                        otherPss += mi.otherPss;
14346                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14347                            long mem = mi.getOtherPss(j);
14348                            miscPss[j] += mem;
14349                            otherPss -= mem;
14350                        }
14351                        oomPss[0] += myTotalPss;
14352                        if (oomProcs[0] == null) {
14353                            oomProcs[0] = new ArrayList<MemItem>();
14354                        }
14355                        oomProcs[0].add(pssItem);
14356                    }
14357                }
14358            }
14359
14360            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14361
14362            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14363            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14364            if (dalvikSubitemPss.length > 0) {
14365                dalvikItem.subitems = new ArrayList<MemItem>();
14366                for (int j=0; j<dalvikSubitemPss.length; j++) {
14367                    final String name = Debug.MemoryInfo.getOtherLabel(
14368                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14369                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14370                }
14371            }
14372            catMems.add(dalvikItem);
14373            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14374            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14375                String label = Debug.MemoryInfo.getOtherLabel(j);
14376                catMems.add(new MemItem(label, label, miscPss[j], j));
14377            }
14378
14379            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14380            for (int j=0; j<oomPss.length; j++) {
14381                if (oomPss[j] != 0) {
14382                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14383                            : DUMP_MEM_OOM_LABEL[j];
14384                    MemItem item = new MemItem(label, label, oomPss[j],
14385                            DUMP_MEM_OOM_ADJ[j]);
14386                    item.subitems = oomProcs[j];
14387                    oomMems.add(item);
14388                }
14389            }
14390
14391            if (!brief && !oomOnly && !isCompact) {
14392                pw.println();
14393                pw.println("Total PSS by process:");
14394                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14395                pw.println();
14396            }
14397            if (!isCompact) {
14398                pw.println("Total PSS by OOM adjustment:");
14399            }
14400            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14401            if (!brief && !oomOnly) {
14402                PrintWriter out = categoryPw != null ? categoryPw : pw;
14403                if (!isCompact) {
14404                    out.println();
14405                    out.println("Total PSS by category:");
14406                }
14407                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14408            }
14409            if (!isCompact) {
14410                pw.println();
14411            }
14412            MemInfoReader memInfo = new MemInfoReader();
14413            memInfo.readMemInfo();
14414            if (nativeProcTotalPss > 0) {
14415                synchronized (this) {
14416                    final long cachedKb = memInfo.getCachedSizeKb();
14417                    final long freeKb = memInfo.getFreeSizeKb();
14418                    final long zramKb = memInfo.getZramTotalSizeKb();
14419                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14420                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14421                            kernelKb*1024, nativeProcTotalPss*1024);
14422                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14423                            nativeProcTotalPss);
14424                }
14425            }
14426            if (!brief) {
14427                if (!isCompact) {
14428                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14429                    pw.print(" kB (status ");
14430                    switch (mLastMemoryLevel) {
14431                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14432                            pw.println("normal)");
14433                            break;
14434                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14435                            pw.println("moderate)");
14436                            break;
14437                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14438                            pw.println("low)");
14439                            break;
14440                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14441                            pw.println("critical)");
14442                            break;
14443                        default:
14444                            pw.print(mLastMemoryLevel);
14445                            pw.println(")");
14446                            break;
14447                    }
14448                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14449                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14450                            pw.print(cachedPss); pw.print(" cached pss + ");
14451                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14452                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14453                } else {
14454                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14455                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14456                            + memInfo.getFreeSizeKb()); pw.print(",");
14457                    pw.println(totalPss - cachedPss);
14458                }
14459            }
14460            if (!isCompact) {
14461                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14462                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14463                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14464                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14465                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14466                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14467                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14468            }
14469            if (!brief) {
14470                if (memInfo.getZramTotalSizeKb() != 0) {
14471                    if (!isCompact) {
14472                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14473                                pw.print(" kB physical used for ");
14474                                pw.print(memInfo.getSwapTotalSizeKb()
14475                                        - memInfo.getSwapFreeSizeKb());
14476                                pw.print(" kB in swap (");
14477                                pw.print(memInfo.getSwapTotalSizeKb());
14478                                pw.println(" kB total swap)");
14479                    } else {
14480                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14481                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14482                                pw.println(memInfo.getSwapFreeSizeKb());
14483                    }
14484                }
14485                final long[] ksm = getKsmInfo();
14486                if (!isCompact) {
14487                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14488                            || ksm[KSM_VOLATILE] != 0) {
14489                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14490                                pw.print(" kB saved from shared ");
14491                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14492                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14493                                pw.print(" kB unshared; ");
14494                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14495                    }
14496                    pw.print("   Tuning: ");
14497                    pw.print(ActivityManager.staticGetMemoryClass());
14498                    pw.print(" (large ");
14499                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14500                    pw.print("), oom ");
14501                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14502                    pw.print(" kB");
14503                    pw.print(", restore limit ");
14504                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14505                    pw.print(" kB");
14506                    if (ActivityManager.isLowRamDeviceStatic()) {
14507                        pw.print(" (low-ram)");
14508                    }
14509                    if (ActivityManager.isHighEndGfx()) {
14510                        pw.print(" (high-end-gfx)");
14511                    }
14512                    pw.println();
14513                } else {
14514                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14515                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14516                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14517                    pw.print("tuning,");
14518                    pw.print(ActivityManager.staticGetMemoryClass());
14519                    pw.print(',');
14520                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14521                    pw.print(',');
14522                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14523                    if (ActivityManager.isLowRamDeviceStatic()) {
14524                        pw.print(",low-ram");
14525                    }
14526                    if (ActivityManager.isHighEndGfx()) {
14527                        pw.print(",high-end-gfx");
14528                    }
14529                    pw.println();
14530                }
14531            }
14532        }
14533    }
14534
14535    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14536            long memtrack, String name) {
14537        sb.append("  ");
14538        sb.append(ProcessList.makeOomAdjString(oomAdj));
14539        sb.append(' ');
14540        sb.append(ProcessList.makeProcStateString(procState));
14541        sb.append(' ');
14542        ProcessList.appendRamKb(sb, pss);
14543        sb.append(" kB: ");
14544        sb.append(name);
14545        if (memtrack > 0) {
14546            sb.append(" (");
14547            sb.append(memtrack);
14548            sb.append(" kB memtrack)");
14549        }
14550    }
14551
14552    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14553        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14554        sb.append(" (pid ");
14555        sb.append(mi.pid);
14556        sb.append(") ");
14557        sb.append(mi.adjType);
14558        sb.append('\n');
14559        if (mi.adjReason != null) {
14560            sb.append("                      ");
14561            sb.append(mi.adjReason);
14562            sb.append('\n');
14563        }
14564    }
14565
14566    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14567        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14568        for (int i=0, N=memInfos.size(); i<N; i++) {
14569            ProcessMemInfo mi = memInfos.get(i);
14570            infoMap.put(mi.pid, mi);
14571        }
14572        updateCpuStatsNow();
14573        long[] memtrackTmp = new long[1];
14574        synchronized (mProcessCpuTracker) {
14575            final int N = mProcessCpuTracker.countStats();
14576            for (int i=0; i<N; i++) {
14577                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14578                if (st.vsize > 0) {
14579                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14580                    if (pss > 0) {
14581                        if (infoMap.indexOfKey(st.pid) < 0) {
14582                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14583                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14584                            mi.pss = pss;
14585                            mi.memtrack = memtrackTmp[0];
14586                            memInfos.add(mi);
14587                        }
14588                    }
14589                }
14590            }
14591        }
14592
14593        long totalPss = 0;
14594        long totalMemtrack = 0;
14595        for (int i=0, N=memInfos.size(); i<N; i++) {
14596            ProcessMemInfo mi = memInfos.get(i);
14597            if (mi.pss == 0) {
14598                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14599                mi.memtrack = memtrackTmp[0];
14600            }
14601            totalPss += mi.pss;
14602            totalMemtrack += mi.memtrack;
14603        }
14604        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14605            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14606                if (lhs.oomAdj != rhs.oomAdj) {
14607                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14608                }
14609                if (lhs.pss != rhs.pss) {
14610                    return lhs.pss < rhs.pss ? 1 : -1;
14611                }
14612                return 0;
14613            }
14614        });
14615
14616        StringBuilder tag = new StringBuilder(128);
14617        StringBuilder stack = new StringBuilder(128);
14618        tag.append("Low on memory -- ");
14619        appendMemBucket(tag, totalPss, "total", false);
14620        appendMemBucket(stack, totalPss, "total", true);
14621
14622        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14623        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14624        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14625
14626        boolean firstLine = true;
14627        int lastOomAdj = Integer.MIN_VALUE;
14628        long extraNativeRam = 0;
14629        long extraNativeMemtrack = 0;
14630        long cachedPss = 0;
14631        for (int i=0, N=memInfos.size(); i<N; i++) {
14632            ProcessMemInfo mi = memInfos.get(i);
14633
14634            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14635                cachedPss += mi.pss;
14636            }
14637
14638            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14639                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14640                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14641                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14642                if (lastOomAdj != mi.oomAdj) {
14643                    lastOomAdj = mi.oomAdj;
14644                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14645                        tag.append(" / ");
14646                    }
14647                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14648                        if (firstLine) {
14649                            stack.append(":");
14650                            firstLine = false;
14651                        }
14652                        stack.append("\n\t at ");
14653                    } else {
14654                        stack.append("$");
14655                    }
14656                } else {
14657                    tag.append(" ");
14658                    stack.append("$");
14659                }
14660                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14661                    appendMemBucket(tag, mi.pss, mi.name, false);
14662                }
14663                appendMemBucket(stack, mi.pss, mi.name, true);
14664                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14665                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14666                    stack.append("(");
14667                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14668                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14669                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14670                            stack.append(":");
14671                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14672                        }
14673                    }
14674                    stack.append(")");
14675                }
14676            }
14677
14678            appendMemInfo(fullNativeBuilder, mi);
14679            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14680                // The short form only has native processes that are >= 512K.
14681                if (mi.pss >= 512) {
14682                    appendMemInfo(shortNativeBuilder, mi);
14683                } else {
14684                    extraNativeRam += mi.pss;
14685                    extraNativeMemtrack += mi.memtrack;
14686                }
14687            } else {
14688                // Short form has all other details, but if we have collected RAM
14689                // from smaller native processes let's dump a summary of that.
14690                if (extraNativeRam > 0) {
14691                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14692                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14693                    shortNativeBuilder.append('\n');
14694                    extraNativeRam = 0;
14695                }
14696                appendMemInfo(fullJavaBuilder, mi);
14697            }
14698        }
14699
14700        fullJavaBuilder.append("           ");
14701        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14702        fullJavaBuilder.append(" kB: TOTAL");
14703        if (totalMemtrack > 0) {
14704            fullJavaBuilder.append(" (");
14705            fullJavaBuilder.append(totalMemtrack);
14706            fullJavaBuilder.append(" kB memtrack)");
14707        } else {
14708        }
14709        fullJavaBuilder.append("\n");
14710
14711        MemInfoReader memInfo = new MemInfoReader();
14712        memInfo.readMemInfo();
14713        final long[] infos = memInfo.getRawInfo();
14714
14715        StringBuilder memInfoBuilder = new StringBuilder(1024);
14716        Debug.getMemInfo(infos);
14717        memInfoBuilder.append("  MemInfo: ");
14718        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14719        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14720        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14721        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14722        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14723        memInfoBuilder.append("           ");
14724        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14725        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14726        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14727        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14728        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14729            memInfoBuilder.append("  ZRAM: ");
14730            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14731            memInfoBuilder.append(" kB RAM, ");
14732            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14733            memInfoBuilder.append(" kB swap total, ");
14734            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14735            memInfoBuilder.append(" kB swap free\n");
14736        }
14737        final long[] ksm = getKsmInfo();
14738        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14739                || ksm[KSM_VOLATILE] != 0) {
14740            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14741            memInfoBuilder.append(" kB saved from shared ");
14742            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14743            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14744            memInfoBuilder.append(" kB unshared; ");
14745            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14746        }
14747        memInfoBuilder.append("  Free RAM: ");
14748        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14749                + memInfo.getFreeSizeKb());
14750        memInfoBuilder.append(" kB\n");
14751        memInfoBuilder.append("  Used RAM: ");
14752        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14753        memInfoBuilder.append(" kB\n");
14754        memInfoBuilder.append("  Lost RAM: ");
14755        memInfoBuilder.append(memInfo.getTotalSizeKb()
14756                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14757                - memInfo.getKernelUsedSizeKb());
14758        memInfoBuilder.append(" kB\n");
14759        Slog.i(TAG, "Low on memory:");
14760        Slog.i(TAG, shortNativeBuilder.toString());
14761        Slog.i(TAG, fullJavaBuilder.toString());
14762        Slog.i(TAG, memInfoBuilder.toString());
14763
14764        StringBuilder dropBuilder = new StringBuilder(1024);
14765        /*
14766        StringWriter oomSw = new StringWriter();
14767        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14768        StringWriter catSw = new StringWriter();
14769        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14770        String[] emptyArgs = new String[] { };
14771        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14772        oomPw.flush();
14773        String oomString = oomSw.toString();
14774        */
14775        dropBuilder.append("Low on memory:");
14776        dropBuilder.append(stack);
14777        dropBuilder.append('\n');
14778        dropBuilder.append(fullNativeBuilder);
14779        dropBuilder.append(fullJavaBuilder);
14780        dropBuilder.append('\n');
14781        dropBuilder.append(memInfoBuilder);
14782        dropBuilder.append('\n');
14783        /*
14784        dropBuilder.append(oomString);
14785        dropBuilder.append('\n');
14786        */
14787        StringWriter catSw = new StringWriter();
14788        synchronized (ActivityManagerService.this) {
14789            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14790            String[] emptyArgs = new String[] { };
14791            catPw.println();
14792            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14793            catPw.println();
14794            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14795                    false, false, null);
14796            catPw.println();
14797            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14798            catPw.flush();
14799        }
14800        dropBuilder.append(catSw.toString());
14801        addErrorToDropBox("lowmem", null, "system_server", null,
14802                null, tag.toString(), dropBuilder.toString(), null, null);
14803        //Slog.i(TAG, "Sent to dropbox:");
14804        //Slog.i(TAG, dropBuilder.toString());
14805        synchronized (ActivityManagerService.this) {
14806            long now = SystemClock.uptimeMillis();
14807            if (mLastMemUsageReportTime < now) {
14808                mLastMemUsageReportTime = now;
14809            }
14810        }
14811    }
14812
14813    /**
14814     * Searches array of arguments for the specified string
14815     * @param args array of argument strings
14816     * @param value value to search for
14817     * @return true if the value is contained in the array
14818     */
14819    private static boolean scanArgs(String[] args, String value) {
14820        if (args != null) {
14821            for (String arg : args) {
14822                if (value.equals(arg)) {
14823                    return true;
14824                }
14825            }
14826        }
14827        return false;
14828    }
14829
14830    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14831            ContentProviderRecord cpr, boolean always) {
14832        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14833
14834        if (!inLaunching || always) {
14835            synchronized (cpr) {
14836                cpr.launchingApp = null;
14837                cpr.notifyAll();
14838            }
14839            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14840            String names[] = cpr.info.authority.split(";");
14841            for (int j = 0; j < names.length; j++) {
14842                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14843            }
14844        }
14845
14846        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
14847            ContentProviderConnection conn = cpr.connections.get(i);
14848            if (conn.waiting) {
14849                // If this connection is waiting for the provider, then we don't
14850                // need to mess with its process unless we are always removing
14851                // or for some reason the provider is not currently launching.
14852                if (inLaunching && !always) {
14853                    continue;
14854                }
14855            }
14856            ProcessRecord capp = conn.client;
14857            conn.dead = true;
14858            if (conn.stableCount > 0) {
14859                if (!capp.persistent && capp.thread != null
14860                        && capp.pid != 0
14861                        && capp.pid != MY_PID) {
14862                    capp.kill("depends on provider "
14863                            + cpr.name.flattenToShortString()
14864                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14865                }
14866            } else if (capp.thread != null && conn.provider.provider != null) {
14867                try {
14868                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14869                } catch (RemoteException e) {
14870                }
14871                // In the protocol here, we don't expect the client to correctly
14872                // clean up this connection, we'll just remove it.
14873                cpr.connections.remove(i);
14874                if (conn.client.conProviders.remove(conn)) {
14875                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14876                }
14877            }
14878        }
14879
14880        if (inLaunching && always) {
14881            mLaunchingProviders.remove(cpr);
14882        }
14883        return inLaunching;
14884    }
14885
14886    /**
14887     * Main code for cleaning up a process when it has gone away.  This is
14888     * called both as a result of the process dying, or directly when stopping
14889     * a process when running in single process mode.
14890     *
14891     * @return Returns true if the given process has been restarted, so the
14892     * app that was passed in must remain on the process lists.
14893     */
14894    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14895            boolean restarting, boolean allowRestart, int index) {
14896        if (index >= 0) {
14897            removeLruProcessLocked(app);
14898            ProcessList.remove(app.pid);
14899        }
14900
14901        mProcessesToGc.remove(app);
14902        mPendingPssProcesses.remove(app);
14903
14904        // Dismiss any open dialogs.
14905        if (app.crashDialog != null && !app.forceCrashReport) {
14906            app.crashDialog.dismiss();
14907            app.crashDialog = null;
14908        }
14909        if (app.anrDialog != null) {
14910            app.anrDialog.dismiss();
14911            app.anrDialog = null;
14912        }
14913        if (app.waitDialog != null) {
14914            app.waitDialog.dismiss();
14915            app.waitDialog = null;
14916        }
14917
14918        app.crashing = false;
14919        app.notResponding = false;
14920
14921        app.resetPackageList(mProcessStats);
14922        app.unlinkDeathRecipient();
14923        app.makeInactive(mProcessStats);
14924        app.waitingToKill = null;
14925        app.forcingToForeground = null;
14926        updateProcessForegroundLocked(app, false, false);
14927        app.foregroundActivities = false;
14928        app.hasShownUi = false;
14929        app.treatLikeActivity = false;
14930        app.hasAboveClient = false;
14931        app.hasClientActivities = false;
14932
14933        mServices.killServicesLocked(app, allowRestart);
14934
14935        boolean restart = false;
14936
14937        // Remove published content providers.
14938        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
14939            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14940            final boolean always = app.bad || !allowRestart;
14941            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
14942            if ((inLaunching || always) && !cpr.connections.isEmpty()) {
14943                // We left the provider in the launching list, need to
14944                // restart it.
14945                restart = true;
14946            }
14947
14948            cpr.provider = null;
14949            cpr.proc = null;
14950        }
14951        app.pubProviders.clear();
14952
14953        // Take care of any launching providers waiting for this process.
14954        if (checkAppInLaunchingProvidersLocked(app, false)) {
14955            restart = true;
14956        }
14957
14958        // Unregister from connected content providers.
14959        if (!app.conProviders.isEmpty()) {
14960            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
14961                ContentProviderConnection conn = app.conProviders.get(i);
14962                conn.provider.connections.remove(conn);
14963                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14964                        conn.provider.name);
14965            }
14966            app.conProviders.clear();
14967        }
14968
14969        // At this point there may be remaining entries in mLaunchingProviders
14970        // where we were the only one waiting, so they are no longer of use.
14971        // Look for these and clean up if found.
14972        // XXX Commented out for now.  Trying to figure out a way to reproduce
14973        // the actual situation to identify what is actually going on.
14974        if (false) {
14975            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
14976                ContentProviderRecord cpr = mLaunchingProviders.get(i);
14977                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14978                    synchronized (cpr) {
14979                        cpr.launchingApp = null;
14980                        cpr.notifyAll();
14981                    }
14982                }
14983            }
14984        }
14985
14986        skipCurrentReceiverLocked(app);
14987
14988        // Unregister any receivers.
14989        for (int i = app.receivers.size() - 1; i >= 0; i--) {
14990            removeReceiverLocked(app.receivers.valueAt(i));
14991        }
14992        app.receivers.clear();
14993
14994        // If the app is undergoing backup, tell the backup manager about it
14995        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14996            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
14997                    + mBackupTarget.appInfo + " died during backup");
14998            try {
14999                IBackupManager bm = IBackupManager.Stub.asInterface(
15000                        ServiceManager.getService(Context.BACKUP_SERVICE));
15001                bm.agentDisconnected(app.info.packageName);
15002            } catch (RemoteException e) {
15003                // can't happen; backup manager is local
15004            }
15005        }
15006
15007        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15008            ProcessChangeItem item = mPendingProcessChanges.get(i);
15009            if (item.pid == app.pid) {
15010                mPendingProcessChanges.remove(i);
15011                mAvailProcessChanges.add(item);
15012            }
15013        }
15014        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15015
15016        // If the caller is restarting this app, then leave it in its
15017        // current lists and let the caller take care of it.
15018        if (restarting) {
15019            return false;
15020        }
15021
15022        if (!app.persistent || app.isolated) {
15023            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15024                    "Removing non-persistent process during cleanup: " + app);
15025            mProcessNames.remove(app.processName, app.uid);
15026            mIsolatedProcesses.remove(app.uid);
15027            if (mHeavyWeightProcess == app) {
15028                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15029                        mHeavyWeightProcess.userId, 0));
15030                mHeavyWeightProcess = null;
15031            }
15032        } else if (!app.removed) {
15033            // This app is persistent, so we need to keep its record around.
15034            // If it is not already on the pending app list, add it there
15035            // and start a new process for it.
15036            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15037                mPersistentStartingProcesses.add(app);
15038                restart = true;
15039            }
15040        }
15041        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15042                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15043        mProcessesOnHold.remove(app);
15044
15045        if (app == mHomeProcess) {
15046            mHomeProcess = null;
15047        }
15048        if (app == mPreviousProcess) {
15049            mPreviousProcess = null;
15050        }
15051
15052        if (restart && !app.isolated) {
15053            // We have components that still need to be running in the
15054            // process, so re-launch it.
15055            if (index < 0) {
15056                ProcessList.remove(app.pid);
15057            }
15058            mProcessNames.put(app.processName, app.uid, app);
15059            startProcessLocked(app, "restart", app.processName);
15060            return true;
15061        } else if (app.pid > 0 && app.pid != MY_PID) {
15062            // Goodbye!
15063            boolean removed;
15064            synchronized (mPidsSelfLocked) {
15065                mPidsSelfLocked.remove(app.pid);
15066                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15067            }
15068            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15069            if (app.isolated) {
15070                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15071            }
15072            app.setPid(0);
15073        }
15074        return false;
15075    }
15076
15077    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15078        // Look through the content providers we are waiting to have launched,
15079        // and if any run in this process then either schedule a restart of
15080        // the process or kill the client waiting for it if this process has
15081        // gone bad.
15082        boolean restart = false;
15083        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15084            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15085            if (cpr.launchingApp == app) {
15086                if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
15087                    restart = true;
15088                } else {
15089                    removeDyingProviderLocked(app, cpr, true);
15090                }
15091            }
15092        }
15093        return restart;
15094    }
15095
15096    // =========================================================
15097    // SERVICES
15098    // =========================================================
15099
15100    @Override
15101    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15102            int flags) {
15103        enforceNotIsolatedCaller("getServices");
15104        synchronized (this) {
15105            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15106        }
15107    }
15108
15109    @Override
15110    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15111        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15112        synchronized (this) {
15113            return mServices.getRunningServiceControlPanelLocked(name);
15114        }
15115    }
15116
15117    @Override
15118    public ComponentName startService(IApplicationThread caller, Intent service,
15119            String resolvedType, int userId) throws TransactionTooLargeException {
15120        enforceNotIsolatedCaller("startService");
15121        // Refuse possible leaked file descriptors
15122        if (service != null && service.hasFileDescriptors() == true) {
15123            throw new IllegalArgumentException("File descriptors passed in Intent");
15124        }
15125
15126        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15127                "startService: " + service + " type=" + resolvedType);
15128        synchronized(this) {
15129            final int callingPid = Binder.getCallingPid();
15130            final int callingUid = Binder.getCallingUid();
15131            final long origId = Binder.clearCallingIdentity();
15132            ComponentName res = mServices.startServiceLocked(caller, service,
15133                    resolvedType, callingPid, callingUid, userId);
15134            Binder.restoreCallingIdentity(origId);
15135            return res;
15136        }
15137    }
15138
15139    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15140            throws TransactionTooLargeException {
15141        synchronized(this) {
15142            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15143                    "startServiceInPackage: " + service + " type=" + resolvedType);
15144            final long origId = Binder.clearCallingIdentity();
15145            ComponentName res = mServices.startServiceLocked(null, service,
15146                    resolvedType, -1, uid, userId);
15147            Binder.restoreCallingIdentity(origId);
15148            return res;
15149        }
15150    }
15151
15152    @Override
15153    public int stopService(IApplicationThread caller, Intent service,
15154            String resolvedType, int userId) {
15155        enforceNotIsolatedCaller("stopService");
15156        // Refuse possible leaked file descriptors
15157        if (service != null && service.hasFileDescriptors() == true) {
15158            throw new IllegalArgumentException("File descriptors passed in Intent");
15159        }
15160
15161        synchronized(this) {
15162            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15163        }
15164    }
15165
15166    @Override
15167    public IBinder peekService(Intent service, String resolvedType) {
15168        enforceNotIsolatedCaller("peekService");
15169        // Refuse possible leaked file descriptors
15170        if (service != null && service.hasFileDescriptors() == true) {
15171            throw new IllegalArgumentException("File descriptors passed in Intent");
15172        }
15173        synchronized(this) {
15174            return mServices.peekServiceLocked(service, resolvedType);
15175        }
15176    }
15177
15178    @Override
15179    public boolean stopServiceToken(ComponentName className, IBinder token,
15180            int startId) {
15181        synchronized(this) {
15182            return mServices.stopServiceTokenLocked(className, token, startId);
15183        }
15184    }
15185
15186    @Override
15187    public void setServiceForeground(ComponentName className, IBinder token,
15188            int id, Notification notification, boolean removeNotification) {
15189        synchronized(this) {
15190            mServices.setServiceForegroundLocked(className, token, id, notification,
15191                    removeNotification);
15192        }
15193    }
15194
15195    @Override
15196    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15197            boolean requireFull, String name, String callerPackage) {
15198        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15199                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15200    }
15201
15202    int unsafeConvertIncomingUser(int userId) {
15203        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15204                ? mCurrentUserId : userId;
15205    }
15206
15207    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15208            int allowMode, String name, String callerPackage) {
15209        final int callingUserId = UserHandle.getUserId(callingUid);
15210        if (callingUserId == userId) {
15211            return userId;
15212        }
15213
15214        // Note that we may be accessing mCurrentUserId outside of a lock...
15215        // shouldn't be a big deal, if this is being called outside
15216        // of a locked context there is intrinsically a race with
15217        // the value the caller will receive and someone else changing it.
15218        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15219        // we will switch to the calling user if access to the current user fails.
15220        int targetUserId = unsafeConvertIncomingUser(userId);
15221
15222        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15223            final boolean allow;
15224            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15225                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15226                // If the caller has this permission, they always pass go.  And collect $200.
15227                allow = true;
15228            } else if (allowMode == ALLOW_FULL_ONLY) {
15229                // We require full access, sucks to be you.
15230                allow = false;
15231            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15232                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15233                // If the caller does not have either permission, they are always doomed.
15234                allow = false;
15235            } else if (allowMode == ALLOW_NON_FULL) {
15236                // We are blanket allowing non-full access, you lucky caller!
15237                allow = true;
15238            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15239                // We may or may not allow this depending on whether the two users are
15240                // in the same profile.
15241                synchronized (mUserProfileGroupIdsSelfLocked) {
15242                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15243                            UserInfo.NO_PROFILE_GROUP_ID);
15244                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15245                            UserInfo.NO_PROFILE_GROUP_ID);
15246                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15247                            && callingProfile == targetProfile;
15248                }
15249            } else {
15250                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15251            }
15252            if (!allow) {
15253                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15254                    // In this case, they would like to just execute as their
15255                    // owner user instead of failing.
15256                    targetUserId = callingUserId;
15257                } else {
15258                    StringBuilder builder = new StringBuilder(128);
15259                    builder.append("Permission Denial: ");
15260                    builder.append(name);
15261                    if (callerPackage != null) {
15262                        builder.append(" from ");
15263                        builder.append(callerPackage);
15264                    }
15265                    builder.append(" asks to run as user ");
15266                    builder.append(userId);
15267                    builder.append(" but is calling from user ");
15268                    builder.append(UserHandle.getUserId(callingUid));
15269                    builder.append("; this requires ");
15270                    builder.append(INTERACT_ACROSS_USERS_FULL);
15271                    if (allowMode != ALLOW_FULL_ONLY) {
15272                        builder.append(" or ");
15273                        builder.append(INTERACT_ACROSS_USERS);
15274                    }
15275                    String msg = builder.toString();
15276                    Slog.w(TAG, msg);
15277                    throw new SecurityException(msg);
15278                }
15279            }
15280        }
15281        if (!allowAll && targetUserId < 0) {
15282            throw new IllegalArgumentException(
15283                    "Call does not support special user #" + targetUserId);
15284        }
15285        // Check shell permission
15286        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15287            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15288                    targetUserId)) {
15289                throw new SecurityException("Shell does not have permission to access user "
15290                        + targetUserId + "\n " + Debug.getCallers(3));
15291            }
15292        }
15293        return targetUserId;
15294    }
15295
15296    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15297            String className, int flags) {
15298        boolean result = false;
15299        // For apps that don't have pre-defined UIDs, check for permission
15300        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15301            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15302                if (ActivityManager.checkUidPermission(
15303                        INTERACT_ACROSS_USERS,
15304                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15305                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15306                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15307                            + " requests FLAG_SINGLE_USER, but app does not hold "
15308                            + INTERACT_ACROSS_USERS;
15309                    Slog.w(TAG, msg);
15310                    throw new SecurityException(msg);
15311                }
15312                // Permission passed
15313                result = true;
15314            }
15315        } else if ("system".equals(componentProcessName)) {
15316            result = true;
15317        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15318            // Phone app and persistent apps are allowed to export singleuser providers.
15319            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15320                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15321        }
15322        if (DEBUG_MU) Slog.v(TAG_MU,
15323                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15324                + Integer.toHexString(flags) + ") = " + result);
15325        return result;
15326    }
15327
15328    /**
15329     * Checks to see if the caller is in the same app as the singleton
15330     * component, or the component is in a special app. It allows special apps
15331     * to export singleton components but prevents exporting singleton
15332     * components for regular apps.
15333     */
15334    boolean isValidSingletonCall(int callingUid, int componentUid) {
15335        int componentAppId = UserHandle.getAppId(componentUid);
15336        return UserHandle.isSameApp(callingUid, componentUid)
15337                || componentAppId == Process.SYSTEM_UID
15338                || componentAppId == Process.PHONE_UID
15339                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15340                        == PackageManager.PERMISSION_GRANTED;
15341    }
15342
15343    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15344            String resolvedType, IServiceConnection connection, int flags, int userId)
15345            throws TransactionTooLargeException {
15346        enforceNotIsolatedCaller("bindService");
15347
15348        // Refuse possible leaked file descriptors
15349        if (service != null && service.hasFileDescriptors() == true) {
15350            throw new IllegalArgumentException("File descriptors passed in Intent");
15351        }
15352
15353        synchronized(this) {
15354            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15355                    connection, flags, userId);
15356        }
15357    }
15358
15359    public boolean unbindService(IServiceConnection connection) {
15360        synchronized (this) {
15361            return mServices.unbindServiceLocked(connection);
15362        }
15363    }
15364
15365    public void publishService(IBinder token, Intent intent, IBinder service) {
15366        // Refuse possible leaked file descriptors
15367        if (intent != null && intent.hasFileDescriptors() == true) {
15368            throw new IllegalArgumentException("File descriptors passed in Intent");
15369        }
15370
15371        synchronized(this) {
15372            if (!(token instanceof ServiceRecord)) {
15373                throw new IllegalArgumentException("Invalid service token");
15374            }
15375            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15376        }
15377    }
15378
15379    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15380        // Refuse possible leaked file descriptors
15381        if (intent != null && intent.hasFileDescriptors() == true) {
15382            throw new IllegalArgumentException("File descriptors passed in Intent");
15383        }
15384
15385        synchronized(this) {
15386            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15387        }
15388    }
15389
15390    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15391        synchronized(this) {
15392            if (!(token instanceof ServiceRecord)) {
15393                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15394                throw new IllegalArgumentException("Invalid service token");
15395            }
15396            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15397        }
15398    }
15399
15400    // =========================================================
15401    // BACKUP AND RESTORE
15402    // =========================================================
15403
15404    // Cause the target app to be launched if necessary and its backup agent
15405    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15406    // activity manager to announce its creation.
15407    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15408        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15409                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15410        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15411
15412        synchronized(this) {
15413            // !!! TODO: currently no check here that we're already bound
15414            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15415            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15416            synchronized (stats) {
15417                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15418            }
15419
15420            // Backup agent is now in use, its package can't be stopped.
15421            try {
15422                AppGlobals.getPackageManager().setPackageStoppedState(
15423                        app.packageName, false, UserHandle.getUserId(app.uid));
15424            } catch (RemoteException e) {
15425            } catch (IllegalArgumentException e) {
15426                Slog.w(TAG, "Failed trying to unstop package "
15427                        + app.packageName + ": " + e);
15428            }
15429
15430            BackupRecord r = new BackupRecord(ss, app, backupMode);
15431            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15432                    ? new ComponentName(app.packageName, app.backupAgentName)
15433                    : new ComponentName("android", "FullBackupAgent");
15434            // startProcessLocked() returns existing proc's record if it's already running
15435            ProcessRecord proc = startProcessLocked(app.processName, app,
15436                    false, 0, "backup", hostingName, false, false, false);
15437            if (proc == null) {
15438                Slog.e(TAG, "Unable to start backup agent process " + r);
15439                return false;
15440            }
15441
15442            r.app = proc;
15443            mBackupTarget = r;
15444            mBackupAppName = app.packageName;
15445
15446            // Try not to kill the process during backup
15447            updateOomAdjLocked(proc);
15448
15449            // If the process is already attached, schedule the creation of the backup agent now.
15450            // If it is not yet live, this will be done when it attaches to the framework.
15451            if (proc.thread != null) {
15452                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15453                try {
15454                    proc.thread.scheduleCreateBackupAgent(app,
15455                            compatibilityInfoForPackageLocked(app), backupMode);
15456                } catch (RemoteException e) {
15457                    // Will time out on the backup manager side
15458                }
15459            } else {
15460                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15461            }
15462            // Invariants: at this point, the target app process exists and the application
15463            // is either already running or in the process of coming up.  mBackupTarget and
15464            // mBackupAppName describe the app, so that when it binds back to the AM we
15465            // know that it's scheduled for a backup-agent operation.
15466        }
15467
15468        return true;
15469    }
15470
15471    @Override
15472    public void clearPendingBackup() {
15473        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15474        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15475
15476        synchronized (this) {
15477            mBackupTarget = null;
15478            mBackupAppName = null;
15479        }
15480    }
15481
15482    // A backup agent has just come up
15483    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15484        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15485                + " = " + agent);
15486
15487        synchronized(this) {
15488            if (!agentPackageName.equals(mBackupAppName)) {
15489                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15490                return;
15491            }
15492        }
15493
15494        long oldIdent = Binder.clearCallingIdentity();
15495        try {
15496            IBackupManager bm = IBackupManager.Stub.asInterface(
15497                    ServiceManager.getService(Context.BACKUP_SERVICE));
15498            bm.agentConnected(agentPackageName, agent);
15499        } catch (RemoteException e) {
15500            // can't happen; the backup manager service is local
15501        } catch (Exception e) {
15502            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15503            e.printStackTrace();
15504        } finally {
15505            Binder.restoreCallingIdentity(oldIdent);
15506        }
15507    }
15508
15509    // done with this agent
15510    public void unbindBackupAgent(ApplicationInfo appInfo) {
15511        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15512        if (appInfo == null) {
15513            Slog.w(TAG, "unbind backup agent for null app");
15514            return;
15515        }
15516
15517        synchronized(this) {
15518            try {
15519                if (mBackupAppName == null) {
15520                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15521                    return;
15522                }
15523
15524                if (!mBackupAppName.equals(appInfo.packageName)) {
15525                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15526                    return;
15527                }
15528
15529                // Not backing this app up any more; reset its OOM adjustment
15530                final ProcessRecord proc = mBackupTarget.app;
15531                updateOomAdjLocked(proc);
15532
15533                // If the app crashed during backup, 'thread' will be null here
15534                if (proc.thread != null) {
15535                    try {
15536                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15537                                compatibilityInfoForPackageLocked(appInfo));
15538                    } catch (Exception e) {
15539                        Slog.e(TAG, "Exception when unbinding backup agent:");
15540                        e.printStackTrace();
15541                    }
15542                }
15543            } finally {
15544                mBackupTarget = null;
15545                mBackupAppName = null;
15546            }
15547        }
15548    }
15549    // =========================================================
15550    // BROADCASTS
15551    // =========================================================
15552
15553    boolean isPendingBroadcastProcessLocked(int pid) {
15554        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15555                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15556    }
15557
15558    void skipPendingBroadcastLocked(int pid) {
15559            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15560            for (BroadcastQueue queue : mBroadcastQueues) {
15561                queue.skipPendingBroadcastLocked(pid);
15562            }
15563    }
15564
15565    // The app just attached; send any pending broadcasts that it should receive
15566    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15567        boolean didSomething = false;
15568        for (BroadcastQueue queue : mBroadcastQueues) {
15569            didSomething |= queue.sendPendingBroadcastsLocked(app);
15570        }
15571        return didSomething;
15572    }
15573
15574    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15575            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15576        enforceNotIsolatedCaller("registerReceiver");
15577        ArrayList<Intent> stickyIntents = null;
15578        ProcessRecord callerApp = null;
15579        int callingUid;
15580        int callingPid;
15581        synchronized(this) {
15582            if (caller != null) {
15583                callerApp = getRecordForAppLocked(caller);
15584                if (callerApp == null) {
15585                    throw new SecurityException(
15586                            "Unable to find app for caller " + caller
15587                            + " (pid=" + Binder.getCallingPid()
15588                            + ") when registering receiver " + receiver);
15589                }
15590                if (callerApp.info.uid != Process.SYSTEM_UID &&
15591                        !callerApp.pkgList.containsKey(callerPackage) &&
15592                        !"android".equals(callerPackage)) {
15593                    throw new SecurityException("Given caller package " + callerPackage
15594                            + " is not running in process " + callerApp);
15595                }
15596                callingUid = callerApp.info.uid;
15597                callingPid = callerApp.pid;
15598            } else {
15599                callerPackage = null;
15600                callingUid = Binder.getCallingUid();
15601                callingPid = Binder.getCallingPid();
15602            }
15603
15604            userId = handleIncomingUser(callingPid, callingUid, userId,
15605                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15606
15607            Iterator<String> actions = filter.actionsIterator();
15608            if (actions == null) {
15609                ArrayList<String> noAction = new ArrayList<String>(1);
15610                noAction.add(null);
15611                actions = noAction.iterator();
15612            }
15613
15614            // Collect stickies of users
15615            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15616            while (actions.hasNext()) {
15617                String action = actions.next();
15618                for (int id : userIds) {
15619                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15620                    if (stickies != null) {
15621                        ArrayList<Intent> intents = stickies.get(action);
15622                        if (intents != null) {
15623                            if (stickyIntents == null) {
15624                                stickyIntents = new ArrayList<Intent>();
15625                            }
15626                            stickyIntents.addAll(intents);
15627                        }
15628                    }
15629                }
15630            }
15631        }
15632
15633        ArrayList<Intent> allSticky = null;
15634        if (stickyIntents != null) {
15635            final ContentResolver resolver = mContext.getContentResolver();
15636            // Look for any matching sticky broadcasts...
15637            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15638                Intent intent = stickyIntents.get(i);
15639                // If intent has scheme "content", it will need to acccess
15640                // provider that needs to lock mProviderMap in ActivityThread
15641                // and also it may need to wait application response, so we
15642                // cannot lock ActivityManagerService here.
15643                if (filter.match(resolver, intent, true, TAG) >= 0) {
15644                    if (allSticky == null) {
15645                        allSticky = new ArrayList<Intent>();
15646                    }
15647                    allSticky.add(intent);
15648                }
15649            }
15650        }
15651
15652        // The first sticky in the list is returned directly back to the client.
15653        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15654        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15655        if (receiver == null) {
15656            return sticky;
15657        }
15658
15659        synchronized (this) {
15660            if (callerApp != null && (callerApp.thread == null
15661                    || callerApp.thread.asBinder() != caller.asBinder())) {
15662                // Original caller already died
15663                return null;
15664            }
15665            ReceiverList rl
15666                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15667            if (rl == null) {
15668                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15669                        userId, receiver);
15670                if (rl.app != null) {
15671                    rl.app.receivers.add(rl);
15672                } else {
15673                    try {
15674                        receiver.asBinder().linkToDeath(rl, 0);
15675                    } catch (RemoteException e) {
15676                        return sticky;
15677                    }
15678                    rl.linkedToDeath = true;
15679                }
15680                mRegisteredReceivers.put(receiver.asBinder(), rl);
15681            } else if (rl.uid != callingUid) {
15682                throw new IllegalArgumentException(
15683                        "Receiver requested to register for uid " + callingUid
15684                        + " was previously registered for uid " + rl.uid);
15685            } else if (rl.pid != callingPid) {
15686                throw new IllegalArgumentException(
15687                        "Receiver requested to register for pid " + callingPid
15688                        + " was previously registered for pid " + rl.pid);
15689            } else if (rl.userId != userId) {
15690                throw new IllegalArgumentException(
15691                        "Receiver requested to register for user " + userId
15692                        + " was previously registered for user " + rl.userId);
15693            }
15694            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15695                    permission, callingUid, userId);
15696            rl.add(bf);
15697            if (!bf.debugCheck()) {
15698                Slog.w(TAG, "==> For Dynamic broadast");
15699            }
15700            mReceiverResolver.addFilter(bf);
15701
15702            // Enqueue broadcasts for all existing stickies that match
15703            // this filter.
15704            if (allSticky != null) {
15705                ArrayList receivers = new ArrayList();
15706                receivers.add(bf);
15707
15708                int N = allSticky.size();
15709                for (int i=0; i<N; i++) {
15710                    Intent intent = (Intent)allSticky.get(i);
15711                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15712                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15713                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15714                            null, null, false, true, true, -1);
15715                    queue.enqueueParallelBroadcastLocked(r);
15716                    queue.scheduleBroadcastsLocked();
15717                }
15718            }
15719
15720            return sticky;
15721        }
15722    }
15723
15724    public void unregisterReceiver(IIntentReceiver receiver) {
15725        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
15726
15727        final long origId = Binder.clearCallingIdentity();
15728        try {
15729            boolean doTrim = false;
15730
15731            synchronized(this) {
15732                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15733                if (rl != null) {
15734                    final BroadcastRecord r = rl.curBroadcast;
15735                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15736                        final boolean doNext = r.queue.finishReceiverLocked(
15737                                r, r.resultCode, r.resultData, r.resultExtras,
15738                                r.resultAbort, false);
15739                        if (doNext) {
15740                            doTrim = true;
15741                            r.queue.processNextBroadcast(false);
15742                        }
15743                    }
15744
15745                    if (rl.app != null) {
15746                        rl.app.receivers.remove(rl);
15747                    }
15748                    removeReceiverLocked(rl);
15749                    if (rl.linkedToDeath) {
15750                        rl.linkedToDeath = false;
15751                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15752                    }
15753                }
15754            }
15755
15756            // If we actually concluded any broadcasts, we might now be able
15757            // to trim the recipients' apps from our working set
15758            if (doTrim) {
15759                trimApplications();
15760                return;
15761            }
15762
15763        } finally {
15764            Binder.restoreCallingIdentity(origId);
15765        }
15766    }
15767
15768    void removeReceiverLocked(ReceiverList rl) {
15769        mRegisteredReceivers.remove(rl.receiver.asBinder());
15770        int N = rl.size();
15771        for (int i=0; i<N; i++) {
15772            mReceiverResolver.removeFilter(rl.get(i));
15773        }
15774    }
15775
15776    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15777        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15778            ProcessRecord r = mLruProcesses.get(i);
15779            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15780                try {
15781                    r.thread.dispatchPackageBroadcast(cmd, packages);
15782                } catch (RemoteException ex) {
15783                }
15784            }
15785        }
15786    }
15787
15788    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15789            int callingUid, int[] users) {
15790        List<ResolveInfo> receivers = null;
15791        try {
15792            HashSet<ComponentName> singleUserReceivers = null;
15793            boolean scannedFirstReceivers = false;
15794            for (int user : users) {
15795                // Skip users that have Shell restrictions
15796                if (callingUid == Process.SHELL_UID
15797                        && getUserManagerLocked().hasUserRestriction(
15798                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15799                    continue;
15800                }
15801                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15802                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15803                if (user != UserHandle.USER_OWNER && newReceivers != null) {
15804                    // If this is not the primary user, we need to check for
15805                    // any receivers that should be filtered out.
15806                    for (int i=0; i<newReceivers.size(); i++) {
15807                        ResolveInfo ri = newReceivers.get(i);
15808                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15809                            newReceivers.remove(i);
15810                            i--;
15811                        }
15812                    }
15813                }
15814                if (newReceivers != null && newReceivers.size() == 0) {
15815                    newReceivers = null;
15816                }
15817                if (receivers == null) {
15818                    receivers = newReceivers;
15819                } else if (newReceivers != null) {
15820                    // We need to concatenate the additional receivers
15821                    // found with what we have do far.  This would be easy,
15822                    // but we also need to de-dup any receivers that are
15823                    // singleUser.
15824                    if (!scannedFirstReceivers) {
15825                        // Collect any single user receivers we had already retrieved.
15826                        scannedFirstReceivers = true;
15827                        for (int i=0; i<receivers.size(); i++) {
15828                            ResolveInfo ri = receivers.get(i);
15829                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15830                                ComponentName cn = new ComponentName(
15831                                        ri.activityInfo.packageName, ri.activityInfo.name);
15832                                if (singleUserReceivers == null) {
15833                                    singleUserReceivers = new HashSet<ComponentName>();
15834                                }
15835                                singleUserReceivers.add(cn);
15836                            }
15837                        }
15838                    }
15839                    // Add the new results to the existing results, tracking
15840                    // and de-dupping single user receivers.
15841                    for (int i=0; i<newReceivers.size(); i++) {
15842                        ResolveInfo ri = newReceivers.get(i);
15843                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15844                            ComponentName cn = new ComponentName(
15845                                    ri.activityInfo.packageName, ri.activityInfo.name);
15846                            if (singleUserReceivers == null) {
15847                                singleUserReceivers = new HashSet<ComponentName>();
15848                            }
15849                            if (!singleUserReceivers.contains(cn)) {
15850                                singleUserReceivers.add(cn);
15851                                receivers.add(ri);
15852                            }
15853                        } else {
15854                            receivers.add(ri);
15855                        }
15856                    }
15857                }
15858            }
15859        } catch (RemoteException ex) {
15860            // pm is in same process, this will never happen.
15861        }
15862        return receivers;
15863    }
15864
15865    private final int broadcastIntentLocked(ProcessRecord callerApp,
15866            String callerPackage, Intent intent, String resolvedType,
15867            IIntentReceiver resultTo, int resultCode, String resultData,
15868            Bundle map, String requiredPermission, int appOp,
15869            boolean ordered, boolean sticky, int callingPid, int callingUid,
15870            int userId) {
15871        intent = new Intent(intent);
15872
15873        // By default broadcasts do not go to stopped apps.
15874        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15875
15876        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
15877                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15878                + " ordered=" + ordered + " userid=" + userId);
15879        if ((resultTo != null) && !ordered) {
15880            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15881        }
15882
15883        userId = handleIncomingUser(callingPid, callingUid, userId,
15884                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15885
15886        // Make sure that the user who is receiving this broadcast is running.
15887        // If not, we will just skip it. Make an exception for shutdown broadcasts
15888        // and upgrade steps.
15889
15890        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15891            if ((callingUid != Process.SYSTEM_UID
15892                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15893                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15894                Slog.w(TAG, "Skipping broadcast of " + intent
15895                        + ": user " + userId + " is stopped");
15896                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15897            }
15898        }
15899
15900        /*
15901         * Prevent non-system code (defined here to be non-persistent
15902         * processes) from sending protected broadcasts.
15903         */
15904        int callingAppId = UserHandle.getAppId(callingUid);
15905        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15906            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15907            || callingAppId == Process.NFC_UID || callingUid == 0) {
15908            // Always okay.
15909        } else if (callerApp == null || !callerApp.persistent) {
15910            try {
15911                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15912                        intent.getAction())) {
15913                    String msg = "Permission Denial: not allowed to send broadcast "
15914                            + intent.getAction() + " from pid="
15915                            + callingPid + ", uid=" + callingUid;
15916                    Slog.w(TAG, msg);
15917                    throw new SecurityException(msg);
15918                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15919                    // Special case for compatibility: we don't want apps to send this,
15920                    // but historically it has not been protected and apps may be using it
15921                    // to poke their own app widget.  So, instead of making it protected,
15922                    // just limit it to the caller.
15923                    if (callerApp == null) {
15924                        String msg = "Permission Denial: not allowed to send broadcast "
15925                                + intent.getAction() + " from unknown caller.";
15926                        Slog.w(TAG, msg);
15927                        throw new SecurityException(msg);
15928                    } else if (intent.getComponent() != null) {
15929                        // They are good enough to send to an explicit component...  verify
15930                        // it is being sent to the calling app.
15931                        if (!intent.getComponent().getPackageName().equals(
15932                                callerApp.info.packageName)) {
15933                            String msg = "Permission Denial: not allowed to send broadcast "
15934                                    + intent.getAction() + " to "
15935                                    + intent.getComponent().getPackageName() + " from "
15936                                    + callerApp.info.packageName;
15937                            Slog.w(TAG, msg);
15938                            throw new SecurityException(msg);
15939                        }
15940                    } else {
15941                        // Limit broadcast to their own package.
15942                        intent.setPackage(callerApp.info.packageName);
15943                    }
15944                }
15945            } catch (RemoteException e) {
15946                Slog.w(TAG, "Remote exception", e);
15947                return ActivityManager.BROADCAST_SUCCESS;
15948            }
15949        }
15950
15951        final String action = intent.getAction();
15952        if (action != null) {
15953            switch (action) {
15954                case Intent.ACTION_UID_REMOVED:
15955                case Intent.ACTION_PACKAGE_REMOVED:
15956                case Intent.ACTION_PACKAGE_CHANGED:
15957                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15958                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15959                    // Handle special intents: if this broadcast is from the package
15960                    // manager about a package being removed, we need to remove all of
15961                    // its activities from the history stack.
15962                    if (checkComponentPermission(
15963                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15964                            callingPid, callingUid, -1, true)
15965                            != PackageManager.PERMISSION_GRANTED) {
15966                        String msg = "Permission Denial: " + intent.getAction()
15967                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15968                                + ", uid=" + callingUid + ")"
15969                                + " requires "
15970                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15971                        Slog.w(TAG, msg);
15972                        throw new SecurityException(msg);
15973                    }
15974                    switch (action) {
15975                        case Intent.ACTION_UID_REMOVED:
15976                            final Bundle intentExtras = intent.getExtras();
15977                            final int uid = intentExtras != null
15978                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15979                            if (uid >= 0) {
15980                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15981                                synchronized (bs) {
15982                                    bs.removeUidStatsLocked(uid);
15983                                }
15984                                mAppOpsService.uidRemoved(uid);
15985                            }
15986                            break;
15987                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15988                            // If resources are unavailable just force stop all those packages
15989                            // and flush the attribute cache as well.
15990                            String list[] =
15991                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15992                            if (list != null && list.length > 0) {
15993                                for (int i = 0; i < list.length; i++) {
15994                                    forceStopPackageLocked(list[i], -1, false, true, true,
15995                                            false, false, userId, "storage unmount");
15996                                }
15997                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15998                                sendPackageBroadcastLocked(
15999                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16000                                        userId);
16001                            }
16002                            break;
16003                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16004                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16005                            break;
16006                        case Intent.ACTION_PACKAGE_REMOVED:
16007                        case Intent.ACTION_PACKAGE_CHANGED:
16008                            Uri data = intent.getData();
16009                            String ssp;
16010                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16011                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16012                                boolean fullUninstall = removed &&
16013                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16014                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16015                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16016                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16017                                            false, true, true, false, fullUninstall, userId,
16018                                            removed ? "pkg removed" : "pkg changed");
16019                                }
16020                                if (removed) {
16021                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16022                                            new String[] {ssp}, userId);
16023                                    if (fullUninstall) {
16024                                        mAppOpsService.packageRemoved(
16025                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16026
16027                                        // Remove all permissions granted from/to this package
16028                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16029
16030                                        removeTasksByPackageNameLocked(ssp, userId);
16031                                        if (userId == UserHandle.USER_OWNER) {
16032                                            mTaskPersister.removeFromPackageCache(ssp);
16033                                        }
16034                                        mBatteryStatsService.notePackageUninstalled(ssp);
16035                                    }
16036                                } else {
16037                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16038                                    if (userId == UserHandle.USER_OWNER) {
16039                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16040                                    }
16041                                }
16042                            }
16043                            break;
16044                    }
16045                    break;
16046                case Intent.ACTION_PACKAGE_ADDED:
16047                    // Special case for adding a package: by default turn on compatibility mode.
16048                    Uri data = intent.getData();
16049                    String ssp;
16050                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16051                        final boolean replacing =
16052                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16053                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16054
16055                        if (replacing) {
16056                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16057                        }
16058                        if (userId == UserHandle.USER_OWNER) {
16059                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16060                        }
16061                        try {
16062                            ApplicationInfo ai = AppGlobals.getPackageManager().
16063                                    getApplicationInfo(ssp, 0, 0);
16064                            mBatteryStatsService.notePackageInstalled(ssp,
16065                                    ai != null ? ai.versionCode : 0);
16066                        } catch (RemoteException e) {
16067                        }
16068                    }
16069                    break;
16070                case Intent.ACTION_TIMEZONE_CHANGED:
16071                    // If this is the time zone changed action, queue up a message that will reset
16072                    // the timezone of all currently running processes. This message will get
16073                    // queued up before the broadcast happens.
16074                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16075                    break;
16076                case Intent.ACTION_TIME_CHANGED:
16077                    // If the user set the time, let all running processes know.
16078                    final int is24Hour =
16079                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16080                                    : 0;
16081                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16082                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16083                    synchronized (stats) {
16084                        stats.noteCurrentTimeChangedLocked();
16085                    }
16086                    break;
16087                case Intent.ACTION_CLEAR_DNS_CACHE:
16088                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16089                    break;
16090                case Proxy.PROXY_CHANGE_ACTION:
16091                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16092                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16093                    break;
16094            }
16095        }
16096
16097        // Add to the sticky list if requested.
16098        if (sticky) {
16099            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16100                    callingPid, callingUid)
16101                    != PackageManager.PERMISSION_GRANTED) {
16102                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16103                        + callingPid + ", uid=" + callingUid
16104                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16105                Slog.w(TAG, msg);
16106                throw new SecurityException(msg);
16107            }
16108            if (requiredPermission != null) {
16109                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16110                        + " and enforce permission " + requiredPermission);
16111                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16112            }
16113            if (intent.getComponent() != null) {
16114                throw new SecurityException(
16115                        "Sticky broadcasts can't target a specific component");
16116            }
16117            // We use userId directly here, since the "all" target is maintained
16118            // as a separate set of sticky broadcasts.
16119            if (userId != UserHandle.USER_ALL) {
16120                // But first, if this is not a broadcast to all users, then
16121                // make sure it doesn't conflict with an existing broadcast to
16122                // all users.
16123                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16124                        UserHandle.USER_ALL);
16125                if (stickies != null) {
16126                    ArrayList<Intent> list = stickies.get(intent.getAction());
16127                    if (list != null) {
16128                        int N = list.size();
16129                        int i;
16130                        for (i=0; i<N; i++) {
16131                            if (intent.filterEquals(list.get(i))) {
16132                                throw new IllegalArgumentException(
16133                                        "Sticky broadcast " + intent + " for user "
16134                                        + userId + " conflicts with existing global broadcast");
16135                            }
16136                        }
16137                    }
16138                }
16139            }
16140            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16141            if (stickies == null) {
16142                stickies = new ArrayMap<String, ArrayList<Intent>>();
16143                mStickyBroadcasts.put(userId, stickies);
16144            }
16145            ArrayList<Intent> list = stickies.get(intent.getAction());
16146            if (list == null) {
16147                list = new ArrayList<Intent>();
16148                stickies.put(intent.getAction(), list);
16149            }
16150            int N = list.size();
16151            int i;
16152            for (i=0; i<N; i++) {
16153                if (intent.filterEquals(list.get(i))) {
16154                    // This sticky already exists, replace it.
16155                    list.set(i, new Intent(intent));
16156                    break;
16157                }
16158            }
16159            if (i >= N) {
16160                list.add(new Intent(intent));
16161            }
16162        }
16163
16164        int[] users;
16165        if (userId == UserHandle.USER_ALL) {
16166            // Caller wants broadcast to go to all started users.
16167            users = mStartedUserArray;
16168        } else {
16169            // Caller wants broadcast to go to one specific user.
16170            users = new int[] {userId};
16171        }
16172
16173        // Figure out who all will receive this broadcast.
16174        List receivers = null;
16175        List<BroadcastFilter> registeredReceivers = null;
16176        // Need to resolve the intent to interested receivers...
16177        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16178                 == 0) {
16179            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16180        }
16181        if (intent.getComponent() == null) {
16182            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16183                // Query one target user at a time, excluding shell-restricted users
16184                UserManagerService ums = getUserManagerLocked();
16185                for (int i = 0; i < users.length; i++) {
16186                    if (ums.hasUserRestriction(
16187                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16188                        continue;
16189                    }
16190                    List<BroadcastFilter> registeredReceiversForUser =
16191                            mReceiverResolver.queryIntent(intent,
16192                                    resolvedType, false, users[i]);
16193                    if (registeredReceivers == null) {
16194                        registeredReceivers = registeredReceiversForUser;
16195                    } else if (registeredReceiversForUser != null) {
16196                        registeredReceivers.addAll(registeredReceiversForUser);
16197                    }
16198                }
16199            } else {
16200                registeredReceivers = mReceiverResolver.queryIntent(intent,
16201                        resolvedType, false, userId);
16202            }
16203        }
16204
16205        final boolean replacePending =
16206                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16207
16208        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16209                + " replacePending=" + replacePending);
16210
16211        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16212        if (!ordered && NR > 0) {
16213            // If we are not serializing this broadcast, then send the
16214            // registered receivers separately so they don't wait for the
16215            // components to be launched.
16216            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16217            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16218                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16219                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16220                    ordered, sticky, false, userId);
16221            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16222            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16223            if (!replaced) {
16224                queue.enqueueParallelBroadcastLocked(r);
16225                queue.scheduleBroadcastsLocked();
16226            }
16227            registeredReceivers = null;
16228            NR = 0;
16229        }
16230
16231        // Merge into one list.
16232        int ir = 0;
16233        if (receivers != null) {
16234            // A special case for PACKAGE_ADDED: do not allow the package
16235            // being added to see this broadcast.  This prevents them from
16236            // using this as a back door to get run as soon as they are
16237            // installed.  Maybe in the future we want to have a special install
16238            // broadcast or such for apps, but we'd like to deliberately make
16239            // this decision.
16240            String skipPackages[] = null;
16241            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16242                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16243                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16244                Uri data = intent.getData();
16245                if (data != null) {
16246                    String pkgName = data.getSchemeSpecificPart();
16247                    if (pkgName != null) {
16248                        skipPackages = new String[] { pkgName };
16249                    }
16250                }
16251            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16252                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16253            }
16254            if (skipPackages != null && (skipPackages.length > 0)) {
16255                for (String skipPackage : skipPackages) {
16256                    if (skipPackage != null) {
16257                        int NT = receivers.size();
16258                        for (int it=0; it<NT; it++) {
16259                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16260                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16261                                receivers.remove(it);
16262                                it--;
16263                                NT--;
16264                            }
16265                        }
16266                    }
16267                }
16268            }
16269
16270            int NT = receivers != null ? receivers.size() : 0;
16271            int it = 0;
16272            ResolveInfo curt = null;
16273            BroadcastFilter curr = null;
16274            while (it < NT && ir < NR) {
16275                if (curt == null) {
16276                    curt = (ResolveInfo)receivers.get(it);
16277                }
16278                if (curr == null) {
16279                    curr = registeredReceivers.get(ir);
16280                }
16281                if (curr.getPriority() >= curt.priority) {
16282                    // Insert this broadcast record into the final list.
16283                    receivers.add(it, curr);
16284                    ir++;
16285                    curr = null;
16286                    it++;
16287                    NT++;
16288                } else {
16289                    // Skip to the next ResolveInfo in the final list.
16290                    it++;
16291                    curt = null;
16292                }
16293            }
16294        }
16295        while (ir < NR) {
16296            if (receivers == null) {
16297                receivers = new ArrayList();
16298            }
16299            receivers.add(registeredReceivers.get(ir));
16300            ir++;
16301        }
16302
16303        if ((receivers != null && receivers.size() > 0)
16304                || resultTo != null) {
16305            BroadcastQueue queue = broadcastQueueForIntent(intent);
16306            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16307                    callerPackage, callingPid, callingUid, resolvedType,
16308                    requiredPermission, appOp, receivers, resultTo, resultCode,
16309                    resultData, map, ordered, sticky, false, userId);
16310
16311            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16312                    + ": prev had " + queue.mOrderedBroadcasts.size());
16313            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16314                    "Enqueueing broadcast " + r.intent.getAction());
16315
16316            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16317            if (!replaced) {
16318                queue.enqueueOrderedBroadcastLocked(r);
16319                queue.scheduleBroadcastsLocked();
16320            }
16321        }
16322
16323        return ActivityManager.BROADCAST_SUCCESS;
16324    }
16325
16326    final Intent verifyBroadcastLocked(Intent intent) {
16327        // Refuse possible leaked file descriptors
16328        if (intent != null && intent.hasFileDescriptors() == true) {
16329            throw new IllegalArgumentException("File descriptors passed in Intent");
16330        }
16331
16332        int flags = intent.getFlags();
16333
16334        if (!mProcessesReady) {
16335            // if the caller really truly claims to know what they're doing, go
16336            // ahead and allow the broadcast without launching any receivers
16337            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16338                intent = new Intent(intent);
16339                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16340            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16341                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16342                        + " before boot completion");
16343                throw new IllegalStateException("Cannot broadcast before boot completed");
16344            }
16345        }
16346
16347        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16348            throw new IllegalArgumentException(
16349                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16350        }
16351
16352        return intent;
16353    }
16354
16355    public final int broadcastIntent(IApplicationThread caller,
16356            Intent intent, String resolvedType, IIntentReceiver resultTo,
16357            int resultCode, String resultData, Bundle map,
16358            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16359        enforceNotIsolatedCaller("broadcastIntent");
16360        synchronized(this) {
16361            intent = verifyBroadcastLocked(intent);
16362
16363            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16364            final int callingPid = Binder.getCallingPid();
16365            final int callingUid = Binder.getCallingUid();
16366            final long origId = Binder.clearCallingIdentity();
16367            int res = broadcastIntentLocked(callerApp,
16368                    callerApp != null ? callerApp.info.packageName : null,
16369                    intent, resolvedType, resultTo,
16370                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16371                    callingPid, callingUid, userId);
16372            Binder.restoreCallingIdentity(origId);
16373            return res;
16374        }
16375    }
16376
16377    int broadcastIntentInPackage(String packageName, int uid,
16378            Intent intent, String resolvedType, IIntentReceiver resultTo,
16379            int resultCode, String resultData, Bundle map,
16380            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16381        synchronized(this) {
16382            intent = verifyBroadcastLocked(intent);
16383
16384            final long origId = Binder.clearCallingIdentity();
16385            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16386                    resultTo, resultCode, resultData, map, requiredPermission,
16387                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16388            Binder.restoreCallingIdentity(origId);
16389            return res;
16390        }
16391    }
16392
16393    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16394        // Refuse possible leaked file descriptors
16395        if (intent != null && intent.hasFileDescriptors() == true) {
16396            throw new IllegalArgumentException("File descriptors passed in Intent");
16397        }
16398
16399        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16400                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16401
16402        synchronized(this) {
16403            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16404                    != PackageManager.PERMISSION_GRANTED) {
16405                String msg = "Permission Denial: unbroadcastIntent() from pid="
16406                        + Binder.getCallingPid()
16407                        + ", uid=" + Binder.getCallingUid()
16408                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16409                Slog.w(TAG, msg);
16410                throw new SecurityException(msg);
16411            }
16412            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16413            if (stickies != null) {
16414                ArrayList<Intent> list = stickies.get(intent.getAction());
16415                if (list != null) {
16416                    int N = list.size();
16417                    int i;
16418                    for (i=0; i<N; i++) {
16419                        if (intent.filterEquals(list.get(i))) {
16420                            list.remove(i);
16421                            break;
16422                        }
16423                    }
16424                    if (list.size() <= 0) {
16425                        stickies.remove(intent.getAction());
16426                    }
16427                }
16428                if (stickies.size() <= 0) {
16429                    mStickyBroadcasts.remove(userId);
16430                }
16431            }
16432        }
16433    }
16434
16435    void backgroundServicesFinishedLocked(int userId) {
16436        for (BroadcastQueue queue : mBroadcastQueues) {
16437            queue.backgroundServicesFinishedLocked(userId);
16438        }
16439    }
16440
16441    public void finishReceiver(IBinder who, int resultCode, String resultData,
16442            Bundle resultExtras, boolean resultAbort, int flags) {
16443        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16444
16445        // Refuse possible leaked file descriptors
16446        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16447            throw new IllegalArgumentException("File descriptors passed in Bundle");
16448        }
16449
16450        final long origId = Binder.clearCallingIdentity();
16451        try {
16452            boolean doNext = false;
16453            BroadcastRecord r;
16454
16455            synchronized(this) {
16456                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16457                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16458                r = queue.getMatchingOrderedReceiver(who);
16459                if (r != null) {
16460                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16461                        resultData, resultExtras, resultAbort, true);
16462                }
16463            }
16464
16465            if (doNext) {
16466                r.queue.processNextBroadcast(false);
16467            }
16468            trimApplications();
16469        } finally {
16470            Binder.restoreCallingIdentity(origId);
16471        }
16472    }
16473
16474    // =========================================================
16475    // INSTRUMENTATION
16476    // =========================================================
16477
16478    public boolean startInstrumentation(ComponentName className,
16479            String profileFile, int flags, Bundle arguments,
16480            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16481            int userId, String abiOverride) {
16482        enforceNotIsolatedCaller("startInstrumentation");
16483        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16484                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16485        // Refuse possible leaked file descriptors
16486        if (arguments != null && arguments.hasFileDescriptors()) {
16487            throw new IllegalArgumentException("File descriptors passed in Bundle");
16488        }
16489
16490        synchronized(this) {
16491            InstrumentationInfo ii = null;
16492            ApplicationInfo ai = null;
16493            try {
16494                ii = mContext.getPackageManager().getInstrumentationInfo(
16495                    className, STOCK_PM_FLAGS);
16496                ai = AppGlobals.getPackageManager().getApplicationInfo(
16497                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16498            } catch (PackageManager.NameNotFoundException e) {
16499            } catch (RemoteException e) {
16500            }
16501            if (ii == null) {
16502                reportStartInstrumentationFailure(watcher, className,
16503                        "Unable to find instrumentation info for: " + className);
16504                return false;
16505            }
16506            if (ai == null) {
16507                reportStartInstrumentationFailure(watcher, className,
16508                        "Unable to find instrumentation target package: " + ii.targetPackage);
16509                return false;
16510            }
16511
16512            int match = mContext.getPackageManager().checkSignatures(
16513                    ii.targetPackage, ii.packageName);
16514            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16515                String msg = "Permission Denial: starting instrumentation "
16516                        + className + " from pid="
16517                        + Binder.getCallingPid()
16518                        + ", uid=" + Binder.getCallingPid()
16519                        + " not allowed because package " + ii.packageName
16520                        + " does not have a signature matching the target "
16521                        + ii.targetPackage;
16522                reportStartInstrumentationFailure(watcher, className, msg);
16523                throw new SecurityException(msg);
16524            }
16525
16526            final long origId = Binder.clearCallingIdentity();
16527            // Instrumentation can kill and relaunch even persistent processes
16528            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16529                    "start instr");
16530            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16531            app.instrumentationClass = className;
16532            app.instrumentationInfo = ai;
16533            app.instrumentationProfileFile = profileFile;
16534            app.instrumentationArguments = arguments;
16535            app.instrumentationWatcher = watcher;
16536            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16537            app.instrumentationResultClass = className;
16538            Binder.restoreCallingIdentity(origId);
16539        }
16540
16541        return true;
16542    }
16543
16544    /**
16545     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16546     * error to the logs, but if somebody is watching, send the report there too.  This enables
16547     * the "am" command to report errors with more information.
16548     *
16549     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16550     * @param cn The component name of the instrumentation.
16551     * @param report The error report.
16552     */
16553    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16554            ComponentName cn, String report) {
16555        Slog.w(TAG, report);
16556        try {
16557            if (watcher != null) {
16558                Bundle results = new Bundle();
16559                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16560                results.putString("Error", report);
16561                watcher.instrumentationStatus(cn, -1, results);
16562            }
16563        } catch (RemoteException e) {
16564            Slog.w(TAG, e);
16565        }
16566    }
16567
16568    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16569        if (app.instrumentationWatcher != null) {
16570            try {
16571                // NOTE:  IInstrumentationWatcher *must* be oneway here
16572                app.instrumentationWatcher.instrumentationFinished(
16573                    app.instrumentationClass,
16574                    resultCode,
16575                    results);
16576            } catch (RemoteException e) {
16577            }
16578        }
16579        if (app.instrumentationUiAutomationConnection != null) {
16580            try {
16581                app.instrumentationUiAutomationConnection.shutdown();
16582            } catch (RemoteException re) {
16583                /* ignore */
16584            }
16585            // Only a UiAutomation can set this flag and now that
16586            // it is finished we make sure it is reset to its default.
16587            mUserIsMonkey = false;
16588        }
16589        app.instrumentationWatcher = null;
16590        app.instrumentationUiAutomationConnection = null;
16591        app.instrumentationClass = null;
16592        app.instrumentationInfo = null;
16593        app.instrumentationProfileFile = null;
16594        app.instrumentationArguments = null;
16595
16596        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16597                "finished inst");
16598    }
16599
16600    public void finishInstrumentation(IApplicationThread target,
16601            int resultCode, Bundle results) {
16602        int userId = UserHandle.getCallingUserId();
16603        // Refuse possible leaked file descriptors
16604        if (results != null && results.hasFileDescriptors()) {
16605            throw new IllegalArgumentException("File descriptors passed in Intent");
16606        }
16607
16608        synchronized(this) {
16609            ProcessRecord app = getRecordForAppLocked(target);
16610            if (app == null) {
16611                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16612                return;
16613            }
16614            final long origId = Binder.clearCallingIdentity();
16615            finishInstrumentationLocked(app, resultCode, results);
16616            Binder.restoreCallingIdentity(origId);
16617        }
16618    }
16619
16620    // =========================================================
16621    // CONFIGURATION
16622    // =========================================================
16623
16624    public ConfigurationInfo getDeviceConfigurationInfo() {
16625        ConfigurationInfo config = new ConfigurationInfo();
16626        synchronized (this) {
16627            config.reqTouchScreen = mConfiguration.touchscreen;
16628            config.reqKeyboardType = mConfiguration.keyboard;
16629            config.reqNavigation = mConfiguration.navigation;
16630            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16631                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16632                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16633            }
16634            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16635                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16636                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16637            }
16638            config.reqGlEsVersion = GL_ES_VERSION;
16639        }
16640        return config;
16641    }
16642
16643    ActivityStack getFocusedStack() {
16644        return mStackSupervisor.getFocusedStack();
16645    }
16646
16647    @Override
16648    public int getFocusedStackId() throws RemoteException {
16649        ActivityStack focusedStack = getFocusedStack();
16650        if (focusedStack != null) {
16651            return focusedStack.getStackId();
16652        }
16653        return -1;
16654    }
16655
16656    public Configuration getConfiguration() {
16657        Configuration ci;
16658        synchronized(this) {
16659            ci = new Configuration(mConfiguration);
16660            ci.userSetLocale = false;
16661        }
16662        return ci;
16663    }
16664
16665    public void updatePersistentConfiguration(Configuration values) {
16666        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16667                "updateConfiguration()");
16668        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16669                "updateConfiguration()");
16670        if (values == null) {
16671            throw new NullPointerException("Configuration must not be null");
16672        }
16673
16674        synchronized(this) {
16675            final long origId = Binder.clearCallingIdentity();
16676            updateConfigurationLocked(values, null, true, false);
16677            Binder.restoreCallingIdentity(origId);
16678        }
16679    }
16680
16681    public void updateConfiguration(Configuration values) {
16682        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16683                "updateConfiguration()");
16684
16685        synchronized(this) {
16686            if (values == null && mWindowManager != null) {
16687                // sentinel: fetch the current configuration from the window manager
16688                values = mWindowManager.computeNewConfiguration();
16689            }
16690
16691            if (mWindowManager != null) {
16692                mProcessList.applyDisplaySize(mWindowManager);
16693            }
16694
16695            final long origId = Binder.clearCallingIdentity();
16696            if (values != null) {
16697                Settings.System.clearConfiguration(values);
16698            }
16699            updateConfigurationLocked(values, null, false, false);
16700            Binder.restoreCallingIdentity(origId);
16701        }
16702    }
16703
16704    /**
16705     * Do either or both things: (1) change the current configuration, and (2)
16706     * make sure the given activity is running with the (now) current
16707     * configuration.  Returns true if the activity has been left running, or
16708     * false if <var>starting</var> is being destroyed to match the new
16709     * configuration.
16710     * @param persistent TODO
16711     */
16712    boolean updateConfigurationLocked(Configuration values,
16713            ActivityRecord starting, boolean persistent, boolean initLocale) {
16714        int changes = 0;
16715
16716        if (values != null) {
16717            Configuration newConfig = new Configuration(mConfiguration);
16718            changes = newConfig.updateFrom(values);
16719            if (changes != 0) {
16720                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
16721                        "Updating configuration to: " + values);
16722
16723                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16724
16725                if (!initLocale && values.locale != null && values.userSetLocale) {
16726                    final String languageTag = values.locale.toLanguageTag();
16727                    SystemProperties.set("persist.sys.locale", languageTag);
16728                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16729                            values.locale));
16730                }
16731
16732                mConfigurationSeq++;
16733                if (mConfigurationSeq <= 0) {
16734                    mConfigurationSeq = 1;
16735                }
16736                newConfig.seq = mConfigurationSeq;
16737                mConfiguration = newConfig;
16738                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16739                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16740                //mUsageStatsService.noteStartConfig(newConfig);
16741
16742                final Configuration configCopy = new Configuration(mConfiguration);
16743
16744                // TODO: If our config changes, should we auto dismiss any currently
16745                // showing dialogs?
16746                mShowDialogs = shouldShowDialogs(newConfig);
16747
16748                AttributeCache ac = AttributeCache.instance();
16749                if (ac != null) {
16750                    ac.updateConfiguration(configCopy);
16751                }
16752
16753                // Make sure all resources in our process are updated
16754                // right now, so that anyone who is going to retrieve
16755                // resource values after we return will be sure to get
16756                // the new ones.  This is especially important during
16757                // boot, where the first config change needs to guarantee
16758                // all resources have that config before following boot
16759                // code is executed.
16760                mSystemThread.applyConfigurationToResources(configCopy);
16761
16762                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16763                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16764                    msg.obj = new Configuration(configCopy);
16765                    mHandler.sendMessage(msg);
16766                }
16767
16768                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16769                    ProcessRecord app = mLruProcesses.get(i);
16770                    try {
16771                        if (app.thread != null) {
16772                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
16773                                    + app.processName + " new config " + mConfiguration);
16774                            app.thread.scheduleConfigurationChanged(configCopy);
16775                        }
16776                    } catch (Exception e) {
16777                    }
16778                }
16779                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16780                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16781                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16782                        | Intent.FLAG_RECEIVER_FOREGROUND);
16783                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16784                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16785                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16786                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16787                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16788                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16789                    broadcastIntentLocked(null, null, intent,
16790                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16791                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16792                }
16793            }
16794        }
16795
16796        boolean kept = true;
16797        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16798        // mainStack is null during startup.
16799        if (mainStack != null) {
16800            if (changes != 0 && starting == null) {
16801                // If the configuration changed, and the caller is not already
16802                // in the process of starting an activity, then find the top
16803                // activity to check if its configuration needs to change.
16804                starting = mainStack.topRunningActivityLocked(null);
16805            }
16806
16807            if (starting != null) {
16808                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16809                // And we need to make sure at this point that all other activities
16810                // are made visible with the correct configuration.
16811                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16812            }
16813        }
16814
16815        if (values != null && mWindowManager != null) {
16816            mWindowManager.setNewConfiguration(mConfiguration);
16817        }
16818
16819        return kept;
16820    }
16821
16822    /**
16823     * Decide based on the configuration whether we should shouw the ANR,
16824     * crash, etc dialogs.  The idea is that if there is no affordnace to
16825     * press the on-screen buttons, we shouldn't show the dialog.
16826     *
16827     * A thought: SystemUI might also want to get told about this, the Power
16828     * dialog / global actions also might want different behaviors.
16829     */
16830    private static final boolean shouldShowDialogs(Configuration config) {
16831        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16832                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
16833                && config.navigation == Configuration.NAVIGATION_NONAV);
16834    }
16835
16836    @Override
16837    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16838        synchronized (this) {
16839            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
16840            if (srec != null) {
16841                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16842            }
16843        }
16844        return false;
16845    }
16846
16847    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16848            Intent resultData) {
16849
16850        synchronized (this) {
16851            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
16852            if (r != null) {
16853                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
16854            }
16855            return false;
16856        }
16857    }
16858
16859    public int getLaunchedFromUid(IBinder activityToken) {
16860        ActivityRecord srec;
16861        synchronized (this) {
16862            srec = ActivityRecord.forTokenLocked(activityToken);
16863        }
16864        if (srec == null) {
16865            return -1;
16866        }
16867        return srec.launchedFromUid;
16868    }
16869
16870    public String getLaunchedFromPackage(IBinder activityToken) {
16871        ActivityRecord srec;
16872        synchronized (this) {
16873            srec = ActivityRecord.forTokenLocked(activityToken);
16874        }
16875        if (srec == null) {
16876            return null;
16877        }
16878        return srec.launchedFromPackage;
16879    }
16880
16881    // =========================================================
16882    // LIFETIME MANAGEMENT
16883    // =========================================================
16884
16885    // Returns which broadcast queue the app is the current [or imminent] receiver
16886    // on, or 'null' if the app is not an active broadcast recipient.
16887    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16888        BroadcastRecord r = app.curReceiver;
16889        if (r != null) {
16890            return r.queue;
16891        }
16892
16893        // It's not the current receiver, but it might be starting up to become one
16894        synchronized (this) {
16895            for (BroadcastQueue queue : mBroadcastQueues) {
16896                r = queue.mPendingBroadcast;
16897                if (r != null && r.curApp == app) {
16898                    // found it; report which queue it's in
16899                    return queue;
16900                }
16901            }
16902        }
16903
16904        return null;
16905    }
16906
16907    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16908            ComponentName targetComponent, String targetProcess) {
16909        if (!mTrackingAssociations) {
16910            return null;
16911        }
16912        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16913                = mAssociations.get(targetUid);
16914        if (components == null) {
16915            components = new ArrayMap<>();
16916            mAssociations.put(targetUid, components);
16917        }
16918        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16919        if (sourceUids == null) {
16920            sourceUids = new SparseArray<>();
16921            components.put(targetComponent, sourceUids);
16922        }
16923        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16924        if (sourceProcesses == null) {
16925            sourceProcesses = new ArrayMap<>();
16926            sourceUids.put(sourceUid, sourceProcesses);
16927        }
16928        Association ass = sourceProcesses.get(sourceProcess);
16929        if (ass == null) {
16930            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16931                    targetProcess);
16932            sourceProcesses.put(sourceProcess, ass);
16933        }
16934        ass.mCount++;
16935        ass.mNesting++;
16936        if (ass.mNesting == 1) {
16937            ass.mStartTime = SystemClock.uptimeMillis();
16938        }
16939        return ass;
16940    }
16941
16942    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16943            ComponentName targetComponent) {
16944        if (!mTrackingAssociations) {
16945            return;
16946        }
16947        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16948                = mAssociations.get(targetUid);
16949        if (components == null) {
16950            return;
16951        }
16952        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16953        if (sourceUids == null) {
16954            return;
16955        }
16956        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16957        if (sourceProcesses == null) {
16958            return;
16959        }
16960        Association ass = sourceProcesses.get(sourceProcess);
16961        if (ass == null || ass.mNesting <= 0) {
16962            return;
16963        }
16964        ass.mNesting--;
16965        if (ass.mNesting == 0) {
16966            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16967        }
16968    }
16969
16970    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16971            boolean doingAll, long now) {
16972        if (mAdjSeq == app.adjSeq) {
16973            // This adjustment has already been computed.
16974            return app.curRawAdj;
16975        }
16976
16977        if (app.thread == null) {
16978            app.adjSeq = mAdjSeq;
16979            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16980            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16981            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16982        }
16983
16984        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16985        app.adjSource = null;
16986        app.adjTarget = null;
16987        app.empty = false;
16988        app.cached = false;
16989
16990        final int activitiesSize = app.activities.size();
16991
16992        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16993            // The max adjustment doesn't allow this app to be anything
16994            // below foreground, so it is not worth doing work for it.
16995            app.adjType = "fixed";
16996            app.adjSeq = mAdjSeq;
16997            app.curRawAdj = app.maxAdj;
16998            app.foregroundActivities = false;
16999            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17000            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17001            // System processes can do UI, and when they do we want to have
17002            // them trim their memory after the user leaves the UI.  To
17003            // facilitate this, here we need to determine whether or not it
17004            // is currently showing UI.
17005            app.systemNoUi = true;
17006            if (app == TOP_APP) {
17007                app.systemNoUi = false;
17008            } else if (activitiesSize > 0) {
17009                for (int j = 0; j < activitiesSize; j++) {
17010                    final ActivityRecord r = app.activities.get(j);
17011                    if (r.visible) {
17012                        app.systemNoUi = false;
17013                    }
17014                }
17015            }
17016            if (!app.systemNoUi) {
17017                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17018            }
17019            return (app.curAdj=app.maxAdj);
17020        }
17021
17022        app.systemNoUi = false;
17023
17024        final int PROCESS_STATE_TOP = mTopProcessState;
17025
17026        // Determine the importance of the process, starting with most
17027        // important to least, and assign an appropriate OOM adjustment.
17028        int adj;
17029        int schedGroup;
17030        int procState;
17031        boolean foregroundActivities = false;
17032        BroadcastQueue queue;
17033        if (app == TOP_APP) {
17034            // The last app on the list is the foreground app.
17035            adj = ProcessList.FOREGROUND_APP_ADJ;
17036            schedGroup = Process.THREAD_GROUP_DEFAULT;
17037            app.adjType = "top-activity";
17038            foregroundActivities = true;
17039            procState = PROCESS_STATE_TOP;
17040        } else if (app.instrumentationClass != null) {
17041            // Don't want to kill running instrumentation.
17042            adj = ProcessList.FOREGROUND_APP_ADJ;
17043            schedGroup = Process.THREAD_GROUP_DEFAULT;
17044            app.adjType = "instrumentation";
17045            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17046        } else if ((queue = isReceivingBroadcast(app)) != null) {
17047            // An app that is currently receiving a broadcast also
17048            // counts as being in the foreground for OOM killer purposes.
17049            // It's placed in a sched group based on the nature of the
17050            // broadcast as reflected by which queue it's active in.
17051            adj = ProcessList.FOREGROUND_APP_ADJ;
17052            schedGroup = (queue == mFgBroadcastQueue)
17053                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17054            app.adjType = "broadcast";
17055            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17056        } else if (app.executingServices.size() > 0) {
17057            // An app that is currently executing a service callback also
17058            // counts as being in the foreground.
17059            adj = ProcessList.FOREGROUND_APP_ADJ;
17060            schedGroup = app.execServicesFg ?
17061                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17062            app.adjType = "exec-service";
17063            procState = ActivityManager.PROCESS_STATE_SERVICE;
17064            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17065        } else {
17066            // As far as we know the process is empty.  We may change our mind later.
17067            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17068            // At this point we don't actually know the adjustment.  Use the cached adj
17069            // value that the caller wants us to.
17070            adj = cachedAdj;
17071            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17072            app.cached = true;
17073            app.empty = true;
17074            app.adjType = "cch-empty";
17075        }
17076
17077        // Examine all activities if not already foreground.
17078        if (!foregroundActivities && activitiesSize > 0) {
17079            for (int j = 0; j < activitiesSize; j++) {
17080                final ActivityRecord r = app.activities.get(j);
17081                if (r.app != app) {
17082                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17083                            + app + "?!?");
17084                    continue;
17085                }
17086                if (r.visible) {
17087                    // App has a visible activity; only upgrade adjustment.
17088                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17089                        adj = ProcessList.VISIBLE_APP_ADJ;
17090                        app.adjType = "visible";
17091                    }
17092                    if (procState > PROCESS_STATE_TOP) {
17093                        procState = PROCESS_STATE_TOP;
17094                    }
17095                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17096                    app.cached = false;
17097                    app.empty = false;
17098                    foregroundActivities = true;
17099                    break;
17100                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17101                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17102                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17103                        app.adjType = "pausing";
17104                    }
17105                    if (procState > PROCESS_STATE_TOP) {
17106                        procState = PROCESS_STATE_TOP;
17107                    }
17108                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17109                    app.cached = false;
17110                    app.empty = false;
17111                    foregroundActivities = true;
17112                } else if (r.state == ActivityState.STOPPING) {
17113                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17114                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17115                        app.adjType = "stopping";
17116                    }
17117                    // For the process state, we will at this point consider the
17118                    // process to be cached.  It will be cached either as an activity
17119                    // or empty depending on whether the activity is finishing.  We do
17120                    // this so that we can treat the process as cached for purposes of
17121                    // memory trimming (determing current memory level, trim command to
17122                    // send to process) since there can be an arbitrary number of stopping
17123                    // processes and they should soon all go into the cached state.
17124                    if (!r.finishing) {
17125                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17126                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17127                        }
17128                    }
17129                    app.cached = false;
17130                    app.empty = false;
17131                    foregroundActivities = true;
17132                } else {
17133                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17134                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17135                        app.adjType = "cch-act";
17136                    }
17137                }
17138            }
17139        }
17140
17141        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17142            if (app.foregroundServices) {
17143                // The user is aware of this app, so make it visible.
17144                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17145                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17146                app.cached = false;
17147                app.adjType = "fg-service";
17148                schedGroup = Process.THREAD_GROUP_DEFAULT;
17149            } else if (app.forcingToForeground != null) {
17150                // The user is aware of this app, so make it visible.
17151                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17152                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17153                app.cached = false;
17154                app.adjType = "force-fg";
17155                app.adjSource = app.forcingToForeground;
17156                schedGroup = Process.THREAD_GROUP_DEFAULT;
17157            }
17158        }
17159
17160        if (app == mHeavyWeightProcess) {
17161            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17162                // We don't want to kill the current heavy-weight process.
17163                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17164                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17165                app.cached = false;
17166                app.adjType = "heavy";
17167            }
17168            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17169                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17170            }
17171        }
17172
17173        if (app == mHomeProcess) {
17174            if (adj > ProcessList.HOME_APP_ADJ) {
17175                // This process is hosting what we currently consider to be the
17176                // home app, so we don't want to let it go into the background.
17177                adj = ProcessList.HOME_APP_ADJ;
17178                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17179                app.cached = false;
17180                app.adjType = "home";
17181            }
17182            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17183                procState = ActivityManager.PROCESS_STATE_HOME;
17184            }
17185        }
17186
17187        if (app == mPreviousProcess && app.activities.size() > 0) {
17188            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17189                // This was the previous process that showed UI to the user.
17190                // We want to try to keep it around more aggressively, to give
17191                // a good experience around switching between two apps.
17192                adj = ProcessList.PREVIOUS_APP_ADJ;
17193                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17194                app.cached = false;
17195                app.adjType = "previous";
17196            }
17197            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17198                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17199            }
17200        }
17201
17202        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17203                + " reason=" + app.adjType);
17204
17205        // By default, we use the computed adjustment.  It may be changed if
17206        // there are applications dependent on our services or providers, but
17207        // this gives us a baseline and makes sure we don't get into an
17208        // infinite recursion.
17209        app.adjSeq = mAdjSeq;
17210        app.curRawAdj = adj;
17211        app.hasStartedServices = false;
17212
17213        if (mBackupTarget != null && app == mBackupTarget.app) {
17214            // If possible we want to avoid killing apps while they're being backed up
17215            if (adj > ProcessList.BACKUP_APP_ADJ) {
17216                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17217                adj = ProcessList.BACKUP_APP_ADJ;
17218                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17219                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17220                }
17221                app.adjType = "backup";
17222                app.cached = false;
17223            }
17224            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17225                procState = ActivityManager.PROCESS_STATE_BACKUP;
17226            }
17227        }
17228
17229        boolean mayBeTop = false;
17230
17231        for (int is = app.services.size()-1;
17232                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17233                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17234                        || procState > ActivityManager.PROCESS_STATE_TOP);
17235                is--) {
17236            ServiceRecord s = app.services.valueAt(is);
17237            if (s.startRequested) {
17238                app.hasStartedServices = true;
17239                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17240                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17241                }
17242                if (app.hasShownUi && app != mHomeProcess) {
17243                    // If this process has shown some UI, let it immediately
17244                    // go to the LRU list because it may be pretty heavy with
17245                    // UI stuff.  We'll tag it with a label just to help
17246                    // debug and understand what is going on.
17247                    if (adj > ProcessList.SERVICE_ADJ) {
17248                        app.adjType = "cch-started-ui-services";
17249                    }
17250                } else {
17251                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17252                        // This service has seen some activity within
17253                        // recent memory, so we will keep its process ahead
17254                        // of the background processes.
17255                        if (adj > ProcessList.SERVICE_ADJ) {
17256                            adj = ProcessList.SERVICE_ADJ;
17257                            app.adjType = "started-services";
17258                            app.cached = false;
17259                        }
17260                    }
17261                    // If we have let the service slide into the background
17262                    // state, still have some text describing what it is doing
17263                    // even though the service no longer has an impact.
17264                    if (adj > ProcessList.SERVICE_ADJ) {
17265                        app.adjType = "cch-started-services";
17266                    }
17267                }
17268            }
17269            for (int conni = s.connections.size()-1;
17270                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17271                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17272                            || procState > ActivityManager.PROCESS_STATE_TOP);
17273                    conni--) {
17274                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17275                for (int i = 0;
17276                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17277                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17278                                || procState > ActivityManager.PROCESS_STATE_TOP);
17279                        i++) {
17280                    // XXX should compute this based on the max of
17281                    // all connected clients.
17282                    ConnectionRecord cr = clist.get(i);
17283                    if (cr.binding.client == app) {
17284                        // Binding to ourself is not interesting.
17285                        continue;
17286                    }
17287                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17288                        ProcessRecord client = cr.binding.client;
17289                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17290                                TOP_APP, doingAll, now);
17291                        int clientProcState = client.curProcState;
17292                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17293                            // If the other app is cached for any reason, for purposes here
17294                            // we are going to consider it empty.  The specific cached state
17295                            // doesn't propagate except under certain conditions.
17296                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17297                        }
17298                        String adjType = null;
17299                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17300                            // Not doing bind OOM management, so treat
17301                            // this guy more like a started service.
17302                            if (app.hasShownUi && app != mHomeProcess) {
17303                                // If this process has shown some UI, let it immediately
17304                                // go to the LRU list because it may be pretty heavy with
17305                                // UI stuff.  We'll tag it with a label just to help
17306                                // debug and understand what is going on.
17307                                if (adj > clientAdj) {
17308                                    adjType = "cch-bound-ui-services";
17309                                }
17310                                app.cached = false;
17311                                clientAdj = adj;
17312                                clientProcState = procState;
17313                            } else {
17314                                if (now >= (s.lastActivity
17315                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17316                                    // This service has not seen activity within
17317                                    // recent memory, so allow it to drop to the
17318                                    // LRU list if there is no other reason to keep
17319                                    // it around.  We'll also tag it with a label just
17320                                    // to help debug and undertand what is going on.
17321                                    if (adj > clientAdj) {
17322                                        adjType = "cch-bound-services";
17323                                    }
17324                                    clientAdj = adj;
17325                                }
17326                            }
17327                        }
17328                        if (adj > clientAdj) {
17329                            // If this process has recently shown UI, and
17330                            // the process that is binding to it is less
17331                            // important than being visible, then we don't
17332                            // care about the binding as much as we care
17333                            // about letting this process get into the LRU
17334                            // list to be killed and restarted if needed for
17335                            // memory.
17336                            if (app.hasShownUi && app != mHomeProcess
17337                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17338                                adjType = "cch-bound-ui-services";
17339                            } else {
17340                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17341                                        |Context.BIND_IMPORTANT)) != 0) {
17342                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17343                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17344                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17345                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17346                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17347                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17348                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17349                                    adj = clientAdj;
17350                                } else {
17351                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17352                                        adj = ProcessList.VISIBLE_APP_ADJ;
17353                                    }
17354                                }
17355                                if (!client.cached) {
17356                                    app.cached = false;
17357                                }
17358                                adjType = "service";
17359                            }
17360                        }
17361                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17362                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17363                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17364                            }
17365                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17366                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17367                                    // Special handling of clients who are in the top state.
17368                                    // We *may* want to consider this process to be in the
17369                                    // top state as well, but only if there is not another
17370                                    // reason for it to be running.  Being on the top is a
17371                                    // special state, meaning you are specifically running
17372                                    // for the current top app.  If the process is already
17373                                    // running in the background for some other reason, it
17374                                    // is more important to continue considering it to be
17375                                    // in the background state.
17376                                    mayBeTop = true;
17377                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17378                                } else {
17379                                    // Special handling for above-top states (persistent
17380                                    // processes).  These should not bring the current process
17381                                    // into the top state, since they are not on top.  Instead
17382                                    // give them the best state after that.
17383                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17384                                        clientProcState =
17385                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17386                                    } else if (mWakefulness
17387                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17388                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17389                                                    != 0) {
17390                                        clientProcState =
17391                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17392                                    } else {
17393                                        clientProcState =
17394                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17395                                    }
17396                                }
17397                            }
17398                        } else {
17399                            if (clientProcState <
17400                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17401                                clientProcState =
17402                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17403                            }
17404                        }
17405                        if (procState > clientProcState) {
17406                            procState = clientProcState;
17407                        }
17408                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17409                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17410                            app.pendingUiClean = true;
17411                        }
17412                        if (adjType != null) {
17413                            app.adjType = adjType;
17414                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17415                                    .REASON_SERVICE_IN_USE;
17416                            app.adjSource = cr.binding.client;
17417                            app.adjSourceProcState = clientProcState;
17418                            app.adjTarget = s.name;
17419                        }
17420                    }
17421                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17422                        app.treatLikeActivity = true;
17423                    }
17424                    final ActivityRecord a = cr.activity;
17425                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17426                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17427                                (a.visible || a.state == ActivityState.RESUMED
17428                                 || a.state == ActivityState.PAUSING)) {
17429                            adj = ProcessList.FOREGROUND_APP_ADJ;
17430                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17431                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17432                            }
17433                            app.cached = false;
17434                            app.adjType = "service";
17435                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17436                                    .REASON_SERVICE_IN_USE;
17437                            app.adjSource = a;
17438                            app.adjSourceProcState = procState;
17439                            app.adjTarget = s.name;
17440                        }
17441                    }
17442                }
17443            }
17444        }
17445
17446        for (int provi = app.pubProviders.size()-1;
17447                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17448                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17449                        || procState > ActivityManager.PROCESS_STATE_TOP);
17450                provi--) {
17451            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17452            for (int i = cpr.connections.size()-1;
17453                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17454                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17455                            || procState > ActivityManager.PROCESS_STATE_TOP);
17456                    i--) {
17457                ContentProviderConnection conn = cpr.connections.get(i);
17458                ProcessRecord client = conn.client;
17459                if (client == app) {
17460                    // Being our own client is not interesting.
17461                    continue;
17462                }
17463                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17464                int clientProcState = client.curProcState;
17465                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17466                    // If the other app is cached for any reason, for purposes here
17467                    // we are going to consider it empty.
17468                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17469                }
17470                if (adj > clientAdj) {
17471                    if (app.hasShownUi && app != mHomeProcess
17472                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17473                        app.adjType = "cch-ui-provider";
17474                    } else {
17475                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17476                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17477                        app.adjType = "provider";
17478                    }
17479                    app.cached &= client.cached;
17480                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17481                            .REASON_PROVIDER_IN_USE;
17482                    app.adjSource = client;
17483                    app.adjSourceProcState = clientProcState;
17484                    app.adjTarget = cpr.name;
17485                }
17486                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17487                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17488                        // Special handling of clients who are in the top state.
17489                        // We *may* want to consider this process to be in the
17490                        // top state as well, but only if there is not another
17491                        // reason for it to be running.  Being on the top is a
17492                        // special state, meaning you are specifically running
17493                        // for the current top app.  If the process is already
17494                        // running in the background for some other reason, it
17495                        // is more important to continue considering it to be
17496                        // in the background state.
17497                        mayBeTop = true;
17498                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17499                    } else {
17500                        // Special handling for above-top states (persistent
17501                        // processes).  These should not bring the current process
17502                        // into the top state, since they are not on top.  Instead
17503                        // give them the best state after that.
17504                        clientProcState =
17505                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17506                    }
17507                }
17508                if (procState > clientProcState) {
17509                    procState = clientProcState;
17510                }
17511                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17512                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17513                }
17514            }
17515            // If the provider has external (non-framework) process
17516            // dependencies, ensure that its adjustment is at least
17517            // FOREGROUND_APP_ADJ.
17518            if (cpr.hasExternalProcessHandles()) {
17519                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17520                    adj = ProcessList.FOREGROUND_APP_ADJ;
17521                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17522                    app.cached = false;
17523                    app.adjType = "provider";
17524                    app.adjTarget = cpr.name;
17525                }
17526                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17527                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17528                }
17529            }
17530        }
17531
17532        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17533            // A client of one of our services or providers is in the top state.  We
17534            // *may* want to be in the top state, but not if we are already running in
17535            // the background for some other reason.  For the decision here, we are going
17536            // to pick out a few specific states that we want to remain in when a client
17537            // is top (states that tend to be longer-term) and otherwise allow it to go
17538            // to the top state.
17539            switch (procState) {
17540                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17541                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17542                case ActivityManager.PROCESS_STATE_SERVICE:
17543                    // These all are longer-term states, so pull them up to the top
17544                    // of the background states, but not all the way to the top state.
17545                    procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17546                    break;
17547                default:
17548                    // Otherwise, top is a better choice, so take it.
17549                    procState = ActivityManager.PROCESS_STATE_TOP;
17550                    break;
17551            }
17552        }
17553
17554        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17555            if (app.hasClientActivities) {
17556                // This is a cached process, but with client activities.  Mark it so.
17557                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17558                app.adjType = "cch-client-act";
17559            } else if (app.treatLikeActivity) {
17560                // This is a cached process, but somebody wants us to treat it like it has
17561                // an activity, okay!
17562                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17563                app.adjType = "cch-as-act";
17564            }
17565        }
17566
17567        if (adj == ProcessList.SERVICE_ADJ) {
17568            if (doingAll) {
17569                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17570                mNewNumServiceProcs++;
17571                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17572                if (!app.serviceb) {
17573                    // This service isn't far enough down on the LRU list to
17574                    // normally be a B service, but if we are low on RAM and it
17575                    // is large we want to force it down since we would prefer to
17576                    // keep launcher over it.
17577                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17578                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17579                        app.serviceHighRam = true;
17580                        app.serviceb = true;
17581                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17582                    } else {
17583                        mNewNumAServiceProcs++;
17584                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17585                    }
17586                } else {
17587                    app.serviceHighRam = false;
17588                }
17589            }
17590            if (app.serviceb) {
17591                adj = ProcessList.SERVICE_B_ADJ;
17592            }
17593        }
17594
17595        app.curRawAdj = adj;
17596
17597        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17598        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17599        if (adj > app.maxAdj) {
17600            adj = app.maxAdj;
17601            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17602                schedGroup = Process.THREAD_GROUP_DEFAULT;
17603            }
17604        }
17605
17606        // Do final modification to adj.  Everything we do between here and applying
17607        // the final setAdj must be done in this function, because we will also use
17608        // it when computing the final cached adj later.  Note that we don't need to
17609        // worry about this for max adj above, since max adj will always be used to
17610        // keep it out of the cached vaues.
17611        app.curAdj = app.modifyRawOomAdj(adj);
17612        app.curSchedGroup = schedGroup;
17613        app.curProcState = procState;
17614        app.foregroundActivities = foregroundActivities;
17615
17616        return app.curRawAdj;
17617    }
17618
17619    /**
17620     * Record new PSS sample for a process.
17621     */
17622    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17623        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
17624        proc.lastPssTime = now;
17625        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17626        if (DEBUG_PSS) Slog.d(TAG_PSS,
17627                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
17628                + " state=" + ProcessList.makeProcStateString(procState));
17629        if (proc.initialIdlePss == 0) {
17630            proc.initialIdlePss = pss;
17631        }
17632        proc.lastPss = pss;
17633        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17634            proc.lastCachedPss = pss;
17635        }
17636
17637        final SparseArray<Pair<Long, String>> watchUids
17638                = mMemWatchProcesses.getMap().get(proc.processName);
17639        Long check = null;
17640        if (watchUids != null) {
17641            Pair<Long, String> val = watchUids.get(proc.uid);
17642            if (val == null) {
17643                val = watchUids.get(0);
17644            }
17645            if (val != null) {
17646                check = val.first;
17647            }
17648        }
17649        if (check != null) {
17650            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17651                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17652                if (!isDebuggable) {
17653                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17654                        isDebuggable = true;
17655                    }
17656                }
17657                if (isDebuggable) {
17658                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17659                    final ProcessRecord myProc = proc;
17660                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17661                    mMemWatchDumpProcName = proc.processName;
17662                    mMemWatchDumpFile = heapdumpFile.toString();
17663                    mMemWatchDumpPid = proc.pid;
17664                    mMemWatchDumpUid = proc.uid;
17665                    BackgroundThread.getHandler().post(new Runnable() {
17666                        @Override
17667                        public void run() {
17668                            revokeUriPermission(ActivityThread.currentActivityThread()
17669                                            .getApplicationThread(),
17670                                    DumpHeapActivity.JAVA_URI,
17671                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
17672                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
17673                                    UserHandle.myUserId());
17674                            ParcelFileDescriptor fd = null;
17675                            try {
17676                                heapdumpFile.delete();
17677                                fd = ParcelFileDescriptor.open(heapdumpFile,
17678                                        ParcelFileDescriptor.MODE_CREATE |
17679                                                ParcelFileDescriptor.MODE_TRUNCATE |
17680                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
17681                                                ParcelFileDescriptor.MODE_APPEND);
17682                                IApplicationThread thread = myProc.thread;
17683                                if (thread != null) {
17684                                    try {
17685                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
17686                                                "Requesting dump heap from "
17687                                                + myProc + " to " + heapdumpFile);
17688                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
17689                                    } catch (RemoteException e) {
17690                                    }
17691                                }
17692                            } catch (FileNotFoundException e) {
17693                                e.printStackTrace();
17694                            } finally {
17695                                if (fd != null) {
17696                                    try {
17697                                        fd.close();
17698                                    } catch (IOException e) {
17699                                    }
17700                                }
17701                            }
17702                        }
17703                    });
17704                } else {
17705                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
17706                            + ", but debugging not enabled");
17707                }
17708            }
17709        }
17710    }
17711
17712    /**
17713     * Schedule PSS collection of a process.
17714     */
17715    void requestPssLocked(ProcessRecord proc, int procState) {
17716        if (mPendingPssProcesses.contains(proc)) {
17717            return;
17718        }
17719        if (mPendingPssProcesses.size() == 0) {
17720            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17721        }
17722        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
17723        proc.pssProcState = procState;
17724        mPendingPssProcesses.add(proc);
17725    }
17726
17727    /**
17728     * Schedule PSS collection of all processes.
17729     */
17730    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17731        if (!always) {
17732            if (now < (mLastFullPssTime +
17733                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17734                return;
17735            }
17736        }
17737        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
17738        mLastFullPssTime = now;
17739        mFullPssPending = true;
17740        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17741        mPendingPssProcesses.clear();
17742        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17743            ProcessRecord app = mLruProcesses.get(i);
17744            if (app.thread == null
17745                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
17746                continue;
17747            }
17748            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17749                app.pssProcState = app.setProcState;
17750                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17751                        mTestPssMode, isSleeping(), now);
17752                mPendingPssProcesses.add(app);
17753            }
17754        }
17755        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17756    }
17757
17758    public void setTestPssMode(boolean enabled) {
17759        synchronized (this) {
17760            mTestPssMode = enabled;
17761            if (enabled) {
17762                // Whenever we enable the mode, we want to take a snapshot all of current
17763                // process mem use.
17764                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17765            }
17766        }
17767    }
17768
17769    /**
17770     * Ask a given process to GC right now.
17771     */
17772    final void performAppGcLocked(ProcessRecord app) {
17773        try {
17774            app.lastRequestedGc = SystemClock.uptimeMillis();
17775            if (app.thread != null) {
17776                if (app.reportLowMemory) {
17777                    app.reportLowMemory = false;
17778                    app.thread.scheduleLowMemory();
17779                } else {
17780                    app.thread.processInBackground();
17781                }
17782            }
17783        } catch (Exception e) {
17784            // whatever.
17785        }
17786    }
17787
17788    /**
17789     * Returns true if things are idle enough to perform GCs.
17790     */
17791    private final boolean canGcNowLocked() {
17792        boolean processingBroadcasts = false;
17793        for (BroadcastQueue q : mBroadcastQueues) {
17794            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17795                processingBroadcasts = true;
17796            }
17797        }
17798        return !processingBroadcasts
17799                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17800    }
17801
17802    /**
17803     * Perform GCs on all processes that are waiting for it, but only
17804     * if things are idle.
17805     */
17806    final void performAppGcsLocked() {
17807        final int N = mProcessesToGc.size();
17808        if (N <= 0) {
17809            return;
17810        }
17811        if (canGcNowLocked()) {
17812            while (mProcessesToGc.size() > 0) {
17813                ProcessRecord proc = mProcessesToGc.remove(0);
17814                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17815                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17816                            <= SystemClock.uptimeMillis()) {
17817                        // To avoid spamming the system, we will GC processes one
17818                        // at a time, waiting a few seconds between each.
17819                        performAppGcLocked(proc);
17820                        scheduleAppGcsLocked();
17821                        return;
17822                    } else {
17823                        // It hasn't been long enough since we last GCed this
17824                        // process...  put it in the list to wait for its time.
17825                        addProcessToGcListLocked(proc);
17826                        break;
17827                    }
17828                }
17829            }
17830
17831            scheduleAppGcsLocked();
17832        }
17833    }
17834
17835    /**
17836     * If all looks good, perform GCs on all processes waiting for them.
17837     */
17838    final void performAppGcsIfAppropriateLocked() {
17839        if (canGcNowLocked()) {
17840            performAppGcsLocked();
17841            return;
17842        }
17843        // Still not idle, wait some more.
17844        scheduleAppGcsLocked();
17845    }
17846
17847    /**
17848     * Schedule the execution of all pending app GCs.
17849     */
17850    final void scheduleAppGcsLocked() {
17851        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17852
17853        if (mProcessesToGc.size() > 0) {
17854            // Schedule a GC for the time to the next process.
17855            ProcessRecord proc = mProcessesToGc.get(0);
17856            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17857
17858            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17859            long now = SystemClock.uptimeMillis();
17860            if (when < (now+GC_TIMEOUT)) {
17861                when = now + GC_TIMEOUT;
17862            }
17863            mHandler.sendMessageAtTime(msg, when);
17864        }
17865    }
17866
17867    /**
17868     * Add a process to the array of processes waiting to be GCed.  Keeps the
17869     * list in sorted order by the last GC time.  The process can't already be
17870     * on the list.
17871     */
17872    final void addProcessToGcListLocked(ProcessRecord proc) {
17873        boolean added = false;
17874        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17875            if (mProcessesToGc.get(i).lastRequestedGc <
17876                    proc.lastRequestedGc) {
17877                added = true;
17878                mProcessesToGc.add(i+1, proc);
17879                break;
17880            }
17881        }
17882        if (!added) {
17883            mProcessesToGc.add(0, proc);
17884        }
17885    }
17886
17887    /**
17888     * Set up to ask a process to GC itself.  This will either do it
17889     * immediately, or put it on the list of processes to gc the next
17890     * time things are idle.
17891     */
17892    final void scheduleAppGcLocked(ProcessRecord app) {
17893        long now = SystemClock.uptimeMillis();
17894        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17895            return;
17896        }
17897        if (!mProcessesToGc.contains(app)) {
17898            addProcessToGcListLocked(app);
17899            scheduleAppGcsLocked();
17900        }
17901    }
17902
17903    final void checkExcessivePowerUsageLocked(boolean doKills) {
17904        updateCpuStatsNow();
17905
17906        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17907        boolean doWakeKills = doKills;
17908        boolean doCpuKills = doKills;
17909        if (mLastPowerCheckRealtime == 0) {
17910            doWakeKills = false;
17911        }
17912        if (mLastPowerCheckUptime == 0) {
17913            doCpuKills = false;
17914        }
17915        if (stats.isScreenOn()) {
17916            doWakeKills = false;
17917        }
17918        final long curRealtime = SystemClock.elapsedRealtime();
17919        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17920        final long curUptime = SystemClock.uptimeMillis();
17921        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17922        mLastPowerCheckRealtime = curRealtime;
17923        mLastPowerCheckUptime = curUptime;
17924        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17925            doWakeKills = false;
17926        }
17927        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17928            doCpuKills = false;
17929        }
17930        int i = mLruProcesses.size();
17931        while (i > 0) {
17932            i--;
17933            ProcessRecord app = mLruProcesses.get(i);
17934            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17935                long wtime;
17936                synchronized (stats) {
17937                    wtime = stats.getProcessWakeTime(app.info.uid,
17938                            app.pid, curRealtime);
17939                }
17940                long wtimeUsed = wtime - app.lastWakeTime;
17941                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17942                if (DEBUG_POWER) {
17943                    StringBuilder sb = new StringBuilder(128);
17944                    sb.append("Wake for ");
17945                    app.toShortString(sb);
17946                    sb.append(": over ");
17947                    TimeUtils.formatDuration(realtimeSince, sb);
17948                    sb.append(" used ");
17949                    TimeUtils.formatDuration(wtimeUsed, sb);
17950                    sb.append(" (");
17951                    sb.append((wtimeUsed*100)/realtimeSince);
17952                    sb.append("%)");
17953                    Slog.i(TAG_POWER, sb.toString());
17954                    sb.setLength(0);
17955                    sb.append("CPU for ");
17956                    app.toShortString(sb);
17957                    sb.append(": over ");
17958                    TimeUtils.formatDuration(uptimeSince, sb);
17959                    sb.append(" used ");
17960                    TimeUtils.formatDuration(cputimeUsed, sb);
17961                    sb.append(" (");
17962                    sb.append((cputimeUsed*100)/uptimeSince);
17963                    sb.append("%)");
17964                    Slog.i(TAG_POWER, sb.toString());
17965                }
17966                // If a process has held a wake lock for more
17967                // than 50% of the time during this period,
17968                // that sounds bad.  Kill!
17969                if (doWakeKills && realtimeSince > 0
17970                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17971                    synchronized (stats) {
17972                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17973                                realtimeSince, wtimeUsed);
17974                    }
17975                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17976                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17977                } else if (doCpuKills && uptimeSince > 0
17978                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17979                    synchronized (stats) {
17980                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17981                                uptimeSince, cputimeUsed);
17982                    }
17983                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17984                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17985                } else {
17986                    app.lastWakeTime = wtime;
17987                    app.lastCpuTime = app.curCpuTime;
17988                }
17989            }
17990        }
17991    }
17992
17993    private final boolean applyOomAdjLocked(ProcessRecord app,
17994            ProcessRecord TOP_APP, boolean doingAll, long now) {
17995        boolean success = true;
17996
17997        if (app.curRawAdj != app.setRawAdj) {
17998            app.setRawAdj = app.curRawAdj;
17999        }
18000
18001        int changes = 0;
18002
18003        if (app.curAdj != app.setAdj) {
18004            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18005            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18006                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18007                    + app.adjType);
18008            app.setAdj = app.curAdj;
18009        }
18010
18011        if (app.setSchedGroup != app.curSchedGroup) {
18012            app.setSchedGroup = app.curSchedGroup;
18013            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18014                    "Setting process group of " + app.processName
18015                    + " to " + app.curSchedGroup);
18016            if (app.waitingToKill != null &&
18017                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18018                app.kill(app.waitingToKill, true);
18019                success = false;
18020            } else {
18021                if (true) {
18022                    long oldId = Binder.clearCallingIdentity();
18023                    try {
18024                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18025                    } catch (Exception e) {
18026                        Slog.w(TAG, "Failed setting process group of " + app.pid
18027                                + " to " + app.curSchedGroup);
18028                        e.printStackTrace();
18029                    } finally {
18030                        Binder.restoreCallingIdentity(oldId);
18031                    }
18032                } else {
18033                    if (app.thread != null) {
18034                        try {
18035                            app.thread.setSchedulingGroup(app.curSchedGroup);
18036                        } catch (RemoteException e) {
18037                        }
18038                    }
18039                }
18040                Process.setSwappiness(app.pid,
18041                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18042            }
18043        }
18044        if (app.repForegroundActivities != app.foregroundActivities) {
18045            app.repForegroundActivities = app.foregroundActivities;
18046            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18047        }
18048        if (app.repProcState != app.curProcState) {
18049            app.repProcState = app.curProcState;
18050            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18051            if (app.thread != null) {
18052                try {
18053                    if (false) {
18054                        //RuntimeException h = new RuntimeException("here");
18055                        Slog.i(TAG, "Sending new process state " + app.repProcState
18056                                + " to " + app /*, h*/);
18057                    }
18058                    app.thread.setProcessState(app.repProcState);
18059                } catch (RemoteException e) {
18060                }
18061            }
18062        }
18063        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18064                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18065            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18066                // Experimental code to more aggressively collect pss while
18067                // running test...  the problem is that this tends to collect
18068                // the data right when a process is transitioning between process
18069                // states, which well tend to give noisy data.
18070                long start = SystemClock.uptimeMillis();
18071                long pss = Debug.getPss(app.pid, mTmpLong, null);
18072                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18073                mPendingPssProcesses.remove(app);
18074                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18075                        + " to " + app.curProcState + ": "
18076                        + (SystemClock.uptimeMillis()-start) + "ms");
18077            }
18078            app.lastStateTime = now;
18079            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18080                    mTestPssMode, isSleeping(), now);
18081            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18082                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18083                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18084                    + (app.nextPssTime-now) + ": " + app);
18085        } else {
18086            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18087                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18088                    mTestPssMode)))) {
18089                requestPssLocked(app, app.setProcState);
18090                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18091                        mTestPssMode, isSleeping(), now);
18092            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18093                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18094        }
18095        if (app.setProcState != app.curProcState) {
18096            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18097                    "Proc state change of " + app.processName
18098                    + " to " + app.curProcState);
18099            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18100            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18101            if (setImportant && !curImportant) {
18102                // This app is no longer something we consider important enough to allow to
18103                // use arbitrary amounts of battery power.  Note
18104                // its current wake lock time to later know to kill it if
18105                // it is not behaving well.
18106                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18107                synchronized (stats) {
18108                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18109                            app.pid, SystemClock.elapsedRealtime());
18110                }
18111                app.lastCpuTime = app.curCpuTime;
18112
18113            }
18114            // Inform UsageStats of important process state change
18115            // Must be called before updating setProcState
18116            maybeUpdateUsageStats(app);
18117
18118            app.setProcState = app.curProcState;
18119            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18120                app.notCachedSinceIdle = false;
18121            }
18122            if (!doingAll) {
18123                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18124            } else {
18125                app.procStateChanged = true;
18126            }
18127        }
18128
18129        if (changes != 0) {
18130            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18131                    "Changes in " + app + ": " + changes);
18132            int i = mPendingProcessChanges.size()-1;
18133            ProcessChangeItem item = null;
18134            while (i >= 0) {
18135                item = mPendingProcessChanges.get(i);
18136                if (item.pid == app.pid) {
18137                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18138                            "Re-using existing item: " + item);
18139                    break;
18140                }
18141                i--;
18142            }
18143            if (i < 0) {
18144                // No existing item in pending changes; need a new one.
18145                final int NA = mAvailProcessChanges.size();
18146                if (NA > 0) {
18147                    item = mAvailProcessChanges.remove(NA-1);
18148                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18149                            "Retreiving available item: " + item);
18150                } else {
18151                    item = new ProcessChangeItem();
18152                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18153                            "Allocating new item: " + item);
18154                }
18155                item.changes = 0;
18156                item.pid = app.pid;
18157                item.uid = app.info.uid;
18158                if (mPendingProcessChanges.size() == 0) {
18159                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18160                            "*** Enqueueing dispatch processes changed!");
18161                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18162                }
18163                mPendingProcessChanges.add(item);
18164            }
18165            item.changes |= changes;
18166            item.processState = app.repProcState;
18167            item.foregroundActivities = app.repForegroundActivities;
18168            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18169                    "Item " + Integer.toHexString(System.identityHashCode(item))
18170                    + " " + app.toShortString() + ": changes=" + item.changes
18171                    + " procState=" + item.processState
18172                    + " foreground=" + item.foregroundActivities
18173                    + " type=" + app.adjType + " source=" + app.adjSource
18174                    + " target=" + app.adjTarget);
18175        }
18176
18177        return success;
18178    }
18179
18180    private void maybeUpdateUsageStats(ProcessRecord app) {
18181        if (DEBUG_USAGE_STATS) {
18182            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18183                    + "] state changes: old = " + app.setProcState + ", new = "
18184                    + app.curProcState);
18185        }
18186        if (mUsageStatsService == null) {
18187            return;
18188        }
18189        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18190                && (app.setProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18191                        || app.setProcState < 0)) {
18192            String[] packages = app.getPackageList();
18193            if (packages != null) {
18194                for (int i = 0; i < packages.length; i++) {
18195                    mUsageStatsService.reportEvent(packages[i], app.userId,
18196                            UsageEvents.Event.INTERACTION);
18197                }
18198            }
18199        }
18200    }
18201
18202    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18203        if (proc.thread != null) {
18204            if (proc.baseProcessTracker != null) {
18205                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18206            }
18207            if (proc.repProcState >= 0) {
18208                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18209                        proc.repProcState);
18210            }
18211        }
18212    }
18213
18214    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18215            ProcessRecord TOP_APP, boolean doingAll, long now) {
18216        if (app.thread == null) {
18217            return false;
18218        }
18219
18220        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18221
18222        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18223    }
18224
18225    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18226            boolean oomAdj) {
18227        if (isForeground != proc.foregroundServices) {
18228            proc.foregroundServices = isForeground;
18229            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18230                    proc.info.uid);
18231            if (isForeground) {
18232                if (curProcs == null) {
18233                    curProcs = new ArrayList<ProcessRecord>();
18234                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18235                }
18236                if (!curProcs.contains(proc)) {
18237                    curProcs.add(proc);
18238                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18239                            proc.info.packageName, proc.info.uid);
18240                }
18241            } else {
18242                if (curProcs != null) {
18243                    if (curProcs.remove(proc)) {
18244                        mBatteryStatsService.noteEvent(
18245                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18246                                proc.info.packageName, proc.info.uid);
18247                        if (curProcs.size() <= 0) {
18248                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18249                        }
18250                    }
18251                }
18252            }
18253            if (oomAdj) {
18254                updateOomAdjLocked();
18255            }
18256        }
18257    }
18258
18259    private final ActivityRecord resumedAppLocked() {
18260        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18261        String pkg;
18262        int uid;
18263        if (act != null) {
18264            pkg = act.packageName;
18265            uid = act.info.applicationInfo.uid;
18266        } else {
18267            pkg = null;
18268            uid = -1;
18269        }
18270        // Has the UID or resumed package name changed?
18271        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18272                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18273            if (mCurResumedPackage != null) {
18274                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18275                        mCurResumedPackage, mCurResumedUid);
18276            }
18277            mCurResumedPackage = pkg;
18278            mCurResumedUid = uid;
18279            if (mCurResumedPackage != null) {
18280                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18281                        mCurResumedPackage, mCurResumedUid);
18282            }
18283        }
18284        return act;
18285    }
18286
18287    final boolean updateOomAdjLocked(ProcessRecord app) {
18288        final ActivityRecord TOP_ACT = resumedAppLocked();
18289        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18290        final boolean wasCached = app.cached;
18291
18292        mAdjSeq++;
18293
18294        // This is the desired cached adjusment we want to tell it to use.
18295        // If our app is currently cached, we know it, and that is it.  Otherwise,
18296        // we don't know it yet, and it needs to now be cached we will then
18297        // need to do a complete oom adj.
18298        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18299                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18300        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18301                SystemClock.uptimeMillis());
18302        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18303            // Changed to/from cached state, so apps after it in the LRU
18304            // list may also be changed.
18305            updateOomAdjLocked();
18306        }
18307        return success;
18308    }
18309
18310    final void updateOomAdjLocked() {
18311        final ActivityRecord TOP_ACT = resumedAppLocked();
18312        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18313        final long now = SystemClock.uptimeMillis();
18314        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18315        final int N = mLruProcesses.size();
18316
18317        if (false) {
18318            RuntimeException e = new RuntimeException();
18319            e.fillInStackTrace();
18320            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18321        }
18322
18323        mAdjSeq++;
18324        mNewNumServiceProcs = 0;
18325        mNewNumAServiceProcs = 0;
18326
18327        final int emptyProcessLimit;
18328        final int cachedProcessLimit;
18329        if (mProcessLimit <= 0) {
18330            emptyProcessLimit = cachedProcessLimit = 0;
18331        } else if (mProcessLimit == 1) {
18332            emptyProcessLimit = 1;
18333            cachedProcessLimit = 0;
18334        } else {
18335            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18336            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18337        }
18338
18339        // Let's determine how many processes we have running vs.
18340        // how many slots we have for background processes; we may want
18341        // to put multiple processes in a slot of there are enough of
18342        // them.
18343        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18344                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18345        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18346        if (numEmptyProcs > cachedProcessLimit) {
18347            // If there are more empty processes than our limit on cached
18348            // processes, then use the cached process limit for the factor.
18349            // This ensures that the really old empty processes get pushed
18350            // down to the bottom, so if we are running low on memory we will
18351            // have a better chance at keeping around more cached processes
18352            // instead of a gazillion empty processes.
18353            numEmptyProcs = cachedProcessLimit;
18354        }
18355        int emptyFactor = numEmptyProcs/numSlots;
18356        if (emptyFactor < 1) emptyFactor = 1;
18357        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18358        if (cachedFactor < 1) cachedFactor = 1;
18359        int stepCached = 0;
18360        int stepEmpty = 0;
18361        int numCached = 0;
18362        int numEmpty = 0;
18363        int numTrimming = 0;
18364
18365        mNumNonCachedProcs = 0;
18366        mNumCachedHiddenProcs = 0;
18367
18368        // First update the OOM adjustment for each of the
18369        // application processes based on their current state.
18370        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18371        int nextCachedAdj = curCachedAdj+1;
18372        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18373        int nextEmptyAdj = curEmptyAdj+2;
18374        for (int i=N-1; i>=0; i--) {
18375            ProcessRecord app = mLruProcesses.get(i);
18376            if (!app.killedByAm && app.thread != null) {
18377                app.procStateChanged = false;
18378                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18379
18380                // If we haven't yet assigned the final cached adj
18381                // to the process, do that now.
18382                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18383                    switch (app.curProcState) {
18384                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18385                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18386                            // This process is a cached process holding activities...
18387                            // assign it the next cached value for that type, and then
18388                            // step that cached level.
18389                            app.curRawAdj = curCachedAdj;
18390                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18391                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18392                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18393                                    + ")");
18394                            if (curCachedAdj != nextCachedAdj) {
18395                                stepCached++;
18396                                if (stepCached >= cachedFactor) {
18397                                    stepCached = 0;
18398                                    curCachedAdj = nextCachedAdj;
18399                                    nextCachedAdj += 2;
18400                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18401                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18402                                    }
18403                                }
18404                            }
18405                            break;
18406                        default:
18407                            // For everything else, assign next empty cached process
18408                            // level and bump that up.  Note that this means that
18409                            // long-running services that have dropped down to the
18410                            // cached level will be treated as empty (since their process
18411                            // state is still as a service), which is what we want.
18412                            app.curRawAdj = curEmptyAdj;
18413                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18414                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18415                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18416                                    + ")");
18417                            if (curEmptyAdj != nextEmptyAdj) {
18418                                stepEmpty++;
18419                                if (stepEmpty >= emptyFactor) {
18420                                    stepEmpty = 0;
18421                                    curEmptyAdj = nextEmptyAdj;
18422                                    nextEmptyAdj += 2;
18423                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18424                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18425                                    }
18426                                }
18427                            }
18428                            break;
18429                    }
18430                }
18431
18432                applyOomAdjLocked(app, TOP_APP, true, now);
18433
18434                // Count the number of process types.
18435                switch (app.curProcState) {
18436                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18437                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18438                        mNumCachedHiddenProcs++;
18439                        numCached++;
18440                        if (numCached > cachedProcessLimit) {
18441                            app.kill("cached #" + numCached, true);
18442                        }
18443                        break;
18444                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18445                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18446                                && app.lastActivityTime < oldTime) {
18447                            app.kill("empty for "
18448                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18449                                    / 1000) + "s", true);
18450                        } else {
18451                            numEmpty++;
18452                            if (numEmpty > emptyProcessLimit) {
18453                                app.kill("empty #" + numEmpty, true);
18454                            }
18455                        }
18456                        break;
18457                    default:
18458                        mNumNonCachedProcs++;
18459                        break;
18460                }
18461
18462                if (app.isolated && app.services.size() <= 0) {
18463                    // If this is an isolated process, and there are no
18464                    // services running in it, then the process is no longer
18465                    // needed.  We agressively kill these because we can by
18466                    // definition not re-use the same process again, and it is
18467                    // good to avoid having whatever code was running in them
18468                    // left sitting around after no longer needed.
18469                    app.kill("isolated not needed", true);
18470                }
18471
18472                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18473                        && !app.killedByAm) {
18474                    numTrimming++;
18475                }
18476            }
18477        }
18478
18479        mNumServiceProcs = mNewNumServiceProcs;
18480
18481        // Now determine the memory trimming level of background processes.
18482        // Unfortunately we need to start at the back of the list to do this
18483        // properly.  We only do this if the number of background apps we
18484        // are managing to keep around is less than half the maximum we desire;
18485        // if we are keeping a good number around, we'll let them use whatever
18486        // memory they want.
18487        final int numCachedAndEmpty = numCached + numEmpty;
18488        int memFactor;
18489        if (numCached <= ProcessList.TRIM_CACHED_APPS
18490                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18491            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18492                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18493            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18494                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18495            } else {
18496                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18497            }
18498        } else {
18499            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18500        }
18501        // We always allow the memory level to go up (better).  We only allow it to go
18502        // down if we are in a state where that is allowed, *and* the total number of processes
18503        // has gone down since last time.
18504        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18505                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18506                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18507        if (memFactor > mLastMemoryLevel) {
18508            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18509                memFactor = mLastMemoryLevel;
18510                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18511            }
18512        }
18513        mLastMemoryLevel = memFactor;
18514        mLastNumProcesses = mLruProcesses.size();
18515        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18516        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18517        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18518            if (mLowRamStartTime == 0) {
18519                mLowRamStartTime = now;
18520            }
18521            int step = 0;
18522            int fgTrimLevel;
18523            switch (memFactor) {
18524                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18525                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18526                    break;
18527                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18528                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18529                    break;
18530                default:
18531                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18532                    break;
18533            }
18534            int factor = numTrimming/3;
18535            int minFactor = 2;
18536            if (mHomeProcess != null) minFactor++;
18537            if (mPreviousProcess != null) minFactor++;
18538            if (factor < minFactor) factor = minFactor;
18539            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18540            for (int i=N-1; i>=0; i--) {
18541                ProcessRecord app = mLruProcesses.get(i);
18542                if (allChanged || app.procStateChanged) {
18543                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18544                    app.procStateChanged = false;
18545                }
18546                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18547                        && !app.killedByAm) {
18548                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18549                        try {
18550                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18551                                    "Trimming memory of " + app.processName + " to " + curLevel);
18552                            app.thread.scheduleTrimMemory(curLevel);
18553                        } catch (RemoteException e) {
18554                        }
18555                        if (false) {
18556                            // For now we won't do this; our memory trimming seems
18557                            // to be good enough at this point that destroying
18558                            // activities causes more harm than good.
18559                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18560                                    && app != mHomeProcess && app != mPreviousProcess) {
18561                                // Need to do this on its own message because the stack may not
18562                                // be in a consistent state at this point.
18563                                // For these apps we will also finish their activities
18564                                // to help them free memory.
18565                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18566                            }
18567                        }
18568                    }
18569                    app.trimMemoryLevel = curLevel;
18570                    step++;
18571                    if (step >= factor) {
18572                        step = 0;
18573                        switch (curLevel) {
18574                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18575                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18576                                break;
18577                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18578                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18579                                break;
18580                        }
18581                    }
18582                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18583                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18584                            && app.thread != null) {
18585                        try {
18586                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18587                                    "Trimming memory of heavy-weight " + app.processName
18588                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18589                            app.thread.scheduleTrimMemory(
18590                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18591                        } catch (RemoteException e) {
18592                        }
18593                    }
18594                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18595                } else {
18596                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18597                            || app.systemNoUi) && app.pendingUiClean) {
18598                        // If this application is now in the background and it
18599                        // had done UI, then give it the special trim level to
18600                        // have it free UI resources.
18601                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18602                        if (app.trimMemoryLevel < level && app.thread != null) {
18603                            try {
18604                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18605                                        "Trimming memory of bg-ui " + app.processName
18606                                        + " to " + level);
18607                                app.thread.scheduleTrimMemory(level);
18608                            } catch (RemoteException e) {
18609                            }
18610                        }
18611                        app.pendingUiClean = false;
18612                    }
18613                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18614                        try {
18615                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18616                                    "Trimming memory of fg " + app.processName
18617                                    + " to " + fgTrimLevel);
18618                            app.thread.scheduleTrimMemory(fgTrimLevel);
18619                        } catch (RemoteException e) {
18620                        }
18621                    }
18622                    app.trimMemoryLevel = fgTrimLevel;
18623                }
18624            }
18625        } else {
18626            if (mLowRamStartTime != 0) {
18627                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18628                mLowRamStartTime = 0;
18629            }
18630            for (int i=N-1; i>=0; i--) {
18631                ProcessRecord app = mLruProcesses.get(i);
18632                if (allChanged || app.procStateChanged) {
18633                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18634                    app.procStateChanged = false;
18635                }
18636                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18637                        || app.systemNoUi) && app.pendingUiClean) {
18638                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18639                            && app.thread != null) {
18640                        try {
18641                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18642                                    "Trimming memory of ui hidden " + app.processName
18643                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18644                            app.thread.scheduleTrimMemory(
18645                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18646                        } catch (RemoteException e) {
18647                        }
18648                    }
18649                    app.pendingUiClean = false;
18650                }
18651                app.trimMemoryLevel = 0;
18652            }
18653        }
18654
18655        if (mAlwaysFinishActivities) {
18656            // Need to do this on its own message because the stack may not
18657            // be in a consistent state at this point.
18658            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18659        }
18660
18661        if (allChanged) {
18662            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18663        }
18664
18665        if (mProcessStats.shouldWriteNowLocked(now)) {
18666            mHandler.post(new Runnable() {
18667                @Override public void run() {
18668                    synchronized (ActivityManagerService.this) {
18669                        mProcessStats.writeStateAsyncLocked();
18670                    }
18671                }
18672            });
18673        }
18674
18675        if (DEBUG_OOM_ADJ) {
18676            final long duration = SystemClock.uptimeMillis() - now;
18677            if (false) {
18678                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
18679                        new RuntimeException("here").fillInStackTrace());
18680            } else {
18681                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
18682            }
18683        }
18684    }
18685
18686    final void trimApplications() {
18687        synchronized (this) {
18688            int i;
18689
18690            // First remove any unused application processes whose package
18691            // has been removed.
18692            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18693                final ProcessRecord app = mRemovedProcesses.get(i);
18694                if (app.activities.size() == 0
18695                        && app.curReceiver == null && app.services.size() == 0) {
18696                    Slog.i(
18697                        TAG, "Exiting empty application process "
18698                        + app.processName + " ("
18699                        + (app.thread != null ? app.thread.asBinder() : null)
18700                        + ")\n");
18701                    if (app.pid > 0 && app.pid != MY_PID) {
18702                        app.kill("empty", false);
18703                    } else {
18704                        try {
18705                            app.thread.scheduleExit();
18706                        } catch (Exception e) {
18707                            // Ignore exceptions.
18708                        }
18709                    }
18710                    cleanUpApplicationRecordLocked(app, false, true, -1);
18711                    mRemovedProcesses.remove(i);
18712
18713                    if (app.persistent) {
18714                        addAppLocked(app.info, false, null /* ABI override */);
18715                    }
18716                }
18717            }
18718
18719            // Now update the oom adj for all processes.
18720            updateOomAdjLocked();
18721        }
18722    }
18723
18724    /** This method sends the specified signal to each of the persistent apps */
18725    public void signalPersistentProcesses(int sig) throws RemoteException {
18726        if (sig != Process.SIGNAL_USR1) {
18727            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18728        }
18729
18730        synchronized (this) {
18731            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18732                    != PackageManager.PERMISSION_GRANTED) {
18733                throw new SecurityException("Requires permission "
18734                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18735            }
18736
18737            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18738                ProcessRecord r = mLruProcesses.get(i);
18739                if (r.thread != null && r.persistent) {
18740                    Process.sendSignal(r.pid, sig);
18741                }
18742            }
18743        }
18744    }
18745
18746    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18747        if (proc == null || proc == mProfileProc) {
18748            proc = mProfileProc;
18749            profileType = mProfileType;
18750            clearProfilerLocked();
18751        }
18752        if (proc == null) {
18753            return;
18754        }
18755        try {
18756            proc.thread.profilerControl(false, null, profileType);
18757        } catch (RemoteException e) {
18758            throw new IllegalStateException("Process disappeared");
18759        }
18760    }
18761
18762    private void clearProfilerLocked() {
18763        if (mProfileFd != null) {
18764            try {
18765                mProfileFd.close();
18766            } catch (IOException e) {
18767            }
18768        }
18769        mProfileApp = null;
18770        mProfileProc = null;
18771        mProfileFile = null;
18772        mProfileType = 0;
18773        mAutoStopProfiler = false;
18774        mSamplingInterval = 0;
18775    }
18776
18777    public boolean profileControl(String process, int userId, boolean start,
18778            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18779
18780        try {
18781            synchronized (this) {
18782                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18783                // its own permission.
18784                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18785                        != PackageManager.PERMISSION_GRANTED) {
18786                    throw new SecurityException("Requires permission "
18787                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18788                }
18789
18790                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18791                    throw new IllegalArgumentException("null profile info or fd");
18792                }
18793
18794                ProcessRecord proc = null;
18795                if (process != null) {
18796                    proc = findProcessLocked(process, userId, "profileControl");
18797                }
18798
18799                if (start && (proc == null || proc.thread == null)) {
18800                    throw new IllegalArgumentException("Unknown process: " + process);
18801                }
18802
18803                if (start) {
18804                    stopProfilerLocked(null, 0);
18805                    setProfileApp(proc.info, proc.processName, profilerInfo);
18806                    mProfileProc = proc;
18807                    mProfileType = profileType;
18808                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18809                    try {
18810                        fd = fd.dup();
18811                    } catch (IOException e) {
18812                        fd = null;
18813                    }
18814                    profilerInfo.profileFd = fd;
18815                    proc.thread.profilerControl(start, profilerInfo, profileType);
18816                    fd = null;
18817                    mProfileFd = null;
18818                } else {
18819                    stopProfilerLocked(proc, profileType);
18820                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18821                        try {
18822                            profilerInfo.profileFd.close();
18823                        } catch (IOException e) {
18824                        }
18825                    }
18826                }
18827
18828                return true;
18829            }
18830        } catch (RemoteException e) {
18831            throw new IllegalStateException("Process disappeared");
18832        } finally {
18833            if (profilerInfo != null && profilerInfo.profileFd != null) {
18834                try {
18835                    profilerInfo.profileFd.close();
18836                } catch (IOException e) {
18837                }
18838            }
18839        }
18840    }
18841
18842    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18844                userId, true, ALLOW_FULL_ONLY, callName, null);
18845        ProcessRecord proc = null;
18846        try {
18847            int pid = Integer.parseInt(process);
18848            synchronized (mPidsSelfLocked) {
18849                proc = mPidsSelfLocked.get(pid);
18850            }
18851        } catch (NumberFormatException e) {
18852        }
18853
18854        if (proc == null) {
18855            ArrayMap<String, SparseArray<ProcessRecord>> all
18856                    = mProcessNames.getMap();
18857            SparseArray<ProcessRecord> procs = all.get(process);
18858            if (procs != null && procs.size() > 0) {
18859                proc = procs.valueAt(0);
18860                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18861                    for (int i=1; i<procs.size(); i++) {
18862                        ProcessRecord thisProc = procs.valueAt(i);
18863                        if (thisProc.userId == userId) {
18864                            proc = thisProc;
18865                            break;
18866                        }
18867                    }
18868                }
18869            }
18870        }
18871
18872        return proc;
18873    }
18874
18875    public boolean dumpHeap(String process, int userId, boolean managed,
18876            String path, ParcelFileDescriptor fd) throws RemoteException {
18877
18878        try {
18879            synchronized (this) {
18880                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18881                // its own permission (same as profileControl).
18882                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18883                        != PackageManager.PERMISSION_GRANTED) {
18884                    throw new SecurityException("Requires permission "
18885                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18886                }
18887
18888                if (fd == null) {
18889                    throw new IllegalArgumentException("null fd");
18890                }
18891
18892                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18893                if (proc == null || proc.thread == null) {
18894                    throw new IllegalArgumentException("Unknown process: " + process);
18895                }
18896
18897                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18898                if (!isDebuggable) {
18899                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18900                        throw new SecurityException("Process not debuggable: " + proc);
18901                    }
18902                }
18903
18904                proc.thread.dumpHeap(managed, path, fd);
18905                fd = null;
18906                return true;
18907            }
18908        } catch (RemoteException e) {
18909            throw new IllegalStateException("Process disappeared");
18910        } finally {
18911            if (fd != null) {
18912                try {
18913                    fd.close();
18914                } catch (IOException e) {
18915                }
18916            }
18917        }
18918    }
18919
18920    @Override
18921    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
18922            String reportPackage) {
18923        if (processName != null) {
18924            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
18925                    "setDumpHeapDebugLimit()");
18926        } else {
18927            if (!Build.IS_DEBUGGABLE) {
18928                throw new SecurityException("Not running a debuggable build");
18929            }
18930            synchronized (mPidsSelfLocked) {
18931                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
18932                if (proc == null) {
18933                    throw new SecurityException("No process found for calling pid "
18934                            + Binder.getCallingPid());
18935                }
18936                processName = proc.processName;
18937                uid = proc.uid;
18938                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
18939                    throw new SecurityException("Package " + reportPackage + " is not running in "
18940                            + proc);
18941                }
18942            }
18943        }
18944        synchronized (this) {
18945            if (maxMemSize > 0) {
18946                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
18947            } else {
18948                if (uid != 0) {
18949                    mMemWatchProcesses.remove(processName, uid);
18950                } else {
18951                    mMemWatchProcesses.getMap().remove(processName);
18952                }
18953            }
18954        }
18955    }
18956
18957    @Override
18958    public void dumpHeapFinished(String path) {
18959        synchronized (this) {
18960            if (Binder.getCallingPid() != mMemWatchDumpPid) {
18961                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
18962                        + " does not match last pid " + mMemWatchDumpPid);
18963                return;
18964            }
18965            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
18966                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
18967                        + " does not match last path " + mMemWatchDumpFile);
18968                return;
18969            }
18970            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
18971            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18972        }
18973    }
18974
18975    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18976    public void monitor() {
18977        synchronized (this) { }
18978    }
18979
18980    void onCoreSettingsChange(Bundle settings) {
18981        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18982            ProcessRecord processRecord = mLruProcesses.get(i);
18983            try {
18984                if (processRecord.thread != null) {
18985                    processRecord.thread.setCoreSettings(settings);
18986                }
18987            } catch (RemoteException re) {
18988                /* ignore */
18989            }
18990        }
18991    }
18992
18993    // Multi-user methods
18994
18995    /**
18996     * Start user, if its not already running, but don't bring it to foreground.
18997     */
18998    @Override
18999    public boolean startUserInBackground(final int userId) {
19000        return startUser(userId, /* foreground */ false);
19001    }
19002
19003    /**
19004     * Start user, if its not already running, and bring it to foreground.
19005     */
19006    boolean startUserInForeground(final int userId, Dialog dlg) {
19007        boolean result = startUser(userId, /* foreground */ true);
19008        dlg.dismiss();
19009        return result;
19010    }
19011
19012    /**
19013     * Refreshes the list of users related to the current user when either a
19014     * user switch happens or when a new related user is started in the
19015     * background.
19016     */
19017    private void updateCurrentProfileIdsLocked() {
19018        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19019                mCurrentUserId, false /* enabledOnly */);
19020        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19021        for (int i = 0; i < currentProfileIds.length; i++) {
19022            currentProfileIds[i] = profiles.get(i).id;
19023        }
19024        mCurrentProfileIds = currentProfileIds;
19025
19026        synchronized (mUserProfileGroupIdsSelfLocked) {
19027            mUserProfileGroupIdsSelfLocked.clear();
19028            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19029            for (int i = 0; i < users.size(); i++) {
19030                UserInfo user = users.get(i);
19031                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19032                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19033                }
19034            }
19035        }
19036    }
19037
19038    private Set<Integer> getProfileIdsLocked(int userId) {
19039        Set<Integer> userIds = new HashSet<Integer>();
19040        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19041                userId, false /* enabledOnly */);
19042        for (UserInfo user : profiles) {
19043            userIds.add(Integer.valueOf(user.id));
19044        }
19045        return userIds;
19046    }
19047
19048    @Override
19049    public boolean switchUser(final int userId) {
19050        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19051        String userName;
19052        synchronized (this) {
19053            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19054            if (userInfo == null) {
19055                Slog.w(TAG, "No user info for user #" + userId);
19056                return false;
19057            }
19058            if (userInfo.isManagedProfile()) {
19059                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19060                return false;
19061            }
19062            userName = userInfo.name;
19063            mTargetUserId = userId;
19064        }
19065        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19066        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19067        return true;
19068    }
19069
19070    private void showUserSwitchDialog(int userId, String userName) {
19071        // The dialog will show and then initiate the user switch by calling startUserInForeground
19072        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19073                true /* above system */);
19074        d.show();
19075    }
19076
19077    private boolean startUser(final int userId, final boolean foreground) {
19078        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19079                != PackageManager.PERMISSION_GRANTED) {
19080            String msg = "Permission Denial: switchUser() from pid="
19081                    + Binder.getCallingPid()
19082                    + ", uid=" + Binder.getCallingUid()
19083                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19084            Slog.w(TAG, msg);
19085            throw new SecurityException(msg);
19086        }
19087
19088        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19089
19090        final long ident = Binder.clearCallingIdentity();
19091        try {
19092            synchronized (this) {
19093                final int oldUserId = mCurrentUserId;
19094                if (oldUserId == userId) {
19095                    return true;
19096                }
19097
19098                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19099                        "startUser");
19100
19101                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19102                if (userInfo == null) {
19103                    Slog.w(TAG, "No user info for user #" + userId);
19104                    return false;
19105                }
19106                if (foreground && userInfo.isManagedProfile()) {
19107                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19108                    return false;
19109                }
19110
19111                if (foreground) {
19112                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19113                            R.anim.screen_user_enter);
19114                }
19115
19116                boolean needStart = false;
19117
19118                // If the user we are switching to is not currently started, then
19119                // we need to start it now.
19120                if (mStartedUsers.get(userId) == null) {
19121                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19122                    updateStartedUserArrayLocked();
19123                    needStart = true;
19124                }
19125
19126                final Integer userIdInt = Integer.valueOf(userId);
19127                mUserLru.remove(userIdInt);
19128                mUserLru.add(userIdInt);
19129
19130                if (foreground) {
19131                    mCurrentUserId = userId;
19132                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19133                    updateCurrentProfileIdsLocked();
19134                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19135                    // Once the internal notion of the active user has switched, we lock the device
19136                    // with the option to show the user switcher on the keyguard.
19137                    mWindowManager.lockNow(null);
19138                } else {
19139                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19140                    updateCurrentProfileIdsLocked();
19141                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19142                    mUserLru.remove(currentUserIdInt);
19143                    mUserLru.add(currentUserIdInt);
19144                }
19145
19146                final UserStartedState uss = mStartedUsers.get(userId);
19147
19148                // Make sure user is in the started state.  If it is currently
19149                // stopping, we need to knock that off.
19150                if (uss.mState == UserStartedState.STATE_STOPPING) {
19151                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19152                    // so we can just fairly silently bring the user back from
19153                    // the almost-dead.
19154                    uss.mState = UserStartedState.STATE_RUNNING;
19155                    updateStartedUserArrayLocked();
19156                    needStart = true;
19157                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19158                    // This means ACTION_SHUTDOWN has been sent, so we will
19159                    // need to treat this as a new boot of the user.
19160                    uss.mState = UserStartedState.STATE_BOOTING;
19161                    updateStartedUserArrayLocked();
19162                    needStart = true;
19163                }
19164
19165                if (uss.mState == UserStartedState.STATE_BOOTING) {
19166                    // Booting up a new user, need to tell system services about it.
19167                    // Note that this is on the same handler as scheduling of broadcasts,
19168                    // which is important because it needs to go first.
19169                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19170                }
19171
19172                if (foreground) {
19173                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19174                            oldUserId));
19175                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19176                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19177                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19178                            oldUserId, userId, uss));
19179                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19180                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19181                }
19182
19183                if (needStart) {
19184                    // Send USER_STARTED broadcast
19185                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19186                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19187                            | Intent.FLAG_RECEIVER_FOREGROUND);
19188                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19189                    broadcastIntentLocked(null, null, intent,
19190                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19191                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19192                }
19193
19194                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19195                    if (userId != UserHandle.USER_OWNER) {
19196                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19197                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19198                        broadcastIntentLocked(null, null, intent, null,
19199                                new IIntentReceiver.Stub() {
19200                                    public void performReceive(Intent intent, int resultCode,
19201                                            String data, Bundle extras, boolean ordered,
19202                                            boolean sticky, int sendingUser) {
19203                                        onUserInitialized(uss, foreground, oldUserId, userId);
19204                                    }
19205                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19206                                true, false, MY_PID, Process.SYSTEM_UID,
19207                                userId);
19208                        uss.initializing = true;
19209                    } else {
19210                        getUserManagerLocked().makeInitialized(userInfo.id);
19211                    }
19212                }
19213
19214                if (foreground) {
19215                    if (!uss.initializing) {
19216                        moveUserToForeground(uss, oldUserId, userId);
19217                    }
19218                } else {
19219                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19220                }
19221
19222                if (needStart) {
19223                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19224                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19225                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19226                    broadcastIntentLocked(null, null, intent,
19227                            null, new IIntentReceiver.Stub() {
19228                                @Override
19229                                public void performReceive(Intent intent, int resultCode, String data,
19230                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19231                                        throws RemoteException {
19232                                }
19233                            }, 0, null, null,
19234                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19235                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19236                }
19237            }
19238        } finally {
19239            Binder.restoreCallingIdentity(ident);
19240        }
19241
19242        return true;
19243    }
19244
19245    void dispatchForegroundProfileChanged(int userId) {
19246        final int N = mUserSwitchObservers.beginBroadcast();
19247        for (int i = 0; i < N; i++) {
19248            try {
19249                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19250            } catch (RemoteException e) {
19251                // Ignore
19252            }
19253        }
19254        mUserSwitchObservers.finishBroadcast();
19255    }
19256
19257    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19258        long ident = Binder.clearCallingIdentity();
19259        try {
19260            Intent intent;
19261            if (oldUserId >= 0) {
19262                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19263                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19264                int count = profiles.size();
19265                for (int i = 0; i < count; i++) {
19266                    int profileUserId = profiles.get(i).id;
19267                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19268                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19269                            | Intent.FLAG_RECEIVER_FOREGROUND);
19270                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19271                    broadcastIntentLocked(null, null, intent,
19272                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19273                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19274                }
19275            }
19276            if (newUserId >= 0) {
19277                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19278                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19279                int count = profiles.size();
19280                for (int i = 0; i < count; i++) {
19281                    int profileUserId = profiles.get(i).id;
19282                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19283                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19284                            | Intent.FLAG_RECEIVER_FOREGROUND);
19285                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19286                    broadcastIntentLocked(null, null, intent,
19287                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19288                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19289                }
19290                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19291                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19292                        | Intent.FLAG_RECEIVER_FOREGROUND);
19293                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19294                broadcastIntentLocked(null, null, intent,
19295                        null, null, 0, null, null,
19296                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19297                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19298            }
19299        } finally {
19300            Binder.restoreCallingIdentity(ident);
19301        }
19302    }
19303
19304    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19305            final int newUserId) {
19306        final int N = mUserSwitchObservers.beginBroadcast();
19307        if (N > 0) {
19308            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19309                int mCount = 0;
19310                @Override
19311                public void sendResult(Bundle data) throws RemoteException {
19312                    synchronized (ActivityManagerService.this) {
19313                        if (mCurUserSwitchCallback == this) {
19314                            mCount++;
19315                            if (mCount == N) {
19316                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19317                            }
19318                        }
19319                    }
19320                }
19321            };
19322            synchronized (this) {
19323                uss.switching = true;
19324                mCurUserSwitchCallback = callback;
19325            }
19326            for (int i=0; i<N; i++) {
19327                try {
19328                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19329                            newUserId, callback);
19330                } catch (RemoteException e) {
19331                }
19332            }
19333        } else {
19334            synchronized (this) {
19335                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19336            }
19337        }
19338        mUserSwitchObservers.finishBroadcast();
19339    }
19340
19341    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19342        synchronized (this) {
19343            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19344            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19345        }
19346    }
19347
19348    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19349        mCurUserSwitchCallback = null;
19350        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19351        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19352                oldUserId, newUserId, uss));
19353    }
19354
19355    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19356        synchronized (this) {
19357            if (foreground) {
19358                moveUserToForeground(uss, oldUserId, newUserId);
19359            }
19360        }
19361
19362        completeSwitchAndInitalize(uss, newUserId, true, false);
19363    }
19364
19365    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19366        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19367        if (homeInFront) {
19368            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19369        } else {
19370            mStackSupervisor.resumeTopActivitiesLocked();
19371        }
19372        EventLogTags.writeAmSwitchUser(newUserId);
19373        getUserManagerLocked().userForeground(newUserId);
19374        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19375    }
19376
19377    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19378        completeSwitchAndInitalize(uss, newUserId, false, true);
19379    }
19380
19381    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19382            boolean clearInitializing, boolean clearSwitching) {
19383        boolean unfrozen = false;
19384        synchronized (this) {
19385            if (clearInitializing) {
19386                uss.initializing = false;
19387                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19388            }
19389            if (clearSwitching) {
19390                uss.switching = false;
19391            }
19392            if (!uss.switching && !uss.initializing) {
19393                mWindowManager.stopFreezingScreen();
19394                unfrozen = true;
19395            }
19396        }
19397        if (unfrozen) {
19398            final int N = mUserSwitchObservers.beginBroadcast();
19399            for (int i=0; i<N; i++) {
19400                try {
19401                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19402                } catch (RemoteException e) {
19403                }
19404            }
19405            mUserSwitchObservers.finishBroadcast();
19406        }
19407        stopGuestUserIfBackground();
19408    }
19409
19410    /**
19411     * Stops the guest user if it has gone to the background.
19412     */
19413    private void stopGuestUserIfBackground() {
19414        synchronized (this) {
19415            final int num = mUserLru.size();
19416            for (int i = 0; i < num; i++) {
19417                Integer oldUserId = mUserLru.get(i);
19418                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19419                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19420                        || oldUss.mState == UserStartedState.STATE_STOPPING
19421                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19422                    continue;
19423                }
19424                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19425                if (userInfo.isGuest()) {
19426                    // This is a user to be stopped.
19427                    stopUserLocked(oldUserId, null);
19428                    break;
19429                }
19430            }
19431        }
19432    }
19433
19434    void scheduleStartProfilesLocked() {
19435        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19436            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19437                    DateUtils.SECOND_IN_MILLIS);
19438        }
19439    }
19440
19441    void startProfilesLocked() {
19442        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19443        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19444                mCurrentUserId, false /* enabledOnly */);
19445        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19446        for (UserInfo user : profiles) {
19447            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19448                    && user.id != mCurrentUserId) {
19449                toStart.add(user);
19450            }
19451        }
19452        final int n = toStart.size();
19453        int i = 0;
19454        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19455            startUserInBackground(toStart.get(i).id);
19456        }
19457        if (i < n) {
19458            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19459        }
19460    }
19461
19462    void finishUserBoot(UserStartedState uss) {
19463        synchronized (this) {
19464            if (uss.mState == UserStartedState.STATE_BOOTING
19465                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19466                uss.mState = UserStartedState.STATE_RUNNING;
19467                final int userId = uss.mHandle.getIdentifier();
19468                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19469                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19470                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19471                broadcastIntentLocked(null, null, intent,
19472                        null, null, 0, null, null,
19473                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19474                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19475            }
19476        }
19477    }
19478
19479    void finishUserSwitch(UserStartedState uss) {
19480        synchronized (this) {
19481            finishUserBoot(uss);
19482
19483            startProfilesLocked();
19484
19485            int num = mUserLru.size();
19486            int i = 0;
19487            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19488                Integer oldUserId = mUserLru.get(i);
19489                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19490                if (oldUss == null) {
19491                    // Shouldn't happen, but be sane if it does.
19492                    mUserLru.remove(i);
19493                    num--;
19494                    continue;
19495                }
19496                if (oldUss.mState == UserStartedState.STATE_STOPPING
19497                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19498                    // This user is already stopping, doesn't count.
19499                    num--;
19500                    i++;
19501                    continue;
19502                }
19503                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19504                    // Owner and current can't be stopped, but count as running.
19505                    i++;
19506                    continue;
19507                }
19508                // This is a user to be stopped.
19509                stopUserLocked(oldUserId, null);
19510                num--;
19511                i++;
19512            }
19513        }
19514    }
19515
19516    @Override
19517    public int stopUser(final int userId, final IStopUserCallback callback) {
19518        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19519                != PackageManager.PERMISSION_GRANTED) {
19520            String msg = "Permission Denial: switchUser() from pid="
19521                    + Binder.getCallingPid()
19522                    + ", uid=" + Binder.getCallingUid()
19523                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19524            Slog.w(TAG, msg);
19525            throw new SecurityException(msg);
19526        }
19527        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19528            throw new IllegalArgumentException("Can't stop primary user " + userId);
19529        }
19530        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19531        synchronized (this) {
19532            return stopUserLocked(userId, callback);
19533        }
19534    }
19535
19536    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19537        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19538        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19539            return ActivityManager.USER_OP_IS_CURRENT;
19540        }
19541
19542        final UserStartedState uss = mStartedUsers.get(userId);
19543        if (uss == null) {
19544            // User is not started, nothing to do...  but we do need to
19545            // callback if requested.
19546            if (callback != null) {
19547                mHandler.post(new Runnable() {
19548                    @Override
19549                    public void run() {
19550                        try {
19551                            callback.userStopped(userId);
19552                        } catch (RemoteException e) {
19553                        }
19554                    }
19555                });
19556            }
19557            return ActivityManager.USER_OP_SUCCESS;
19558        }
19559
19560        if (callback != null) {
19561            uss.mStopCallbacks.add(callback);
19562        }
19563
19564        if (uss.mState != UserStartedState.STATE_STOPPING
19565                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19566            uss.mState = UserStartedState.STATE_STOPPING;
19567            updateStartedUserArrayLocked();
19568
19569            long ident = Binder.clearCallingIdentity();
19570            try {
19571                // We are going to broadcast ACTION_USER_STOPPING and then
19572                // once that is done send a final ACTION_SHUTDOWN and then
19573                // stop the user.
19574                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19575                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19576                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19577                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19578                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19579                // This is the result receiver for the final shutdown broadcast.
19580                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19581                    @Override
19582                    public void performReceive(Intent intent, int resultCode, String data,
19583                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19584                        finishUserStop(uss);
19585                    }
19586                };
19587                // This is the result receiver for the initial stopping broadcast.
19588                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19589                    @Override
19590                    public void performReceive(Intent intent, int resultCode, String data,
19591                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19592                        // On to the next.
19593                        synchronized (ActivityManagerService.this) {
19594                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19595                                // Whoops, we are being started back up.  Abort, abort!
19596                                return;
19597                            }
19598                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19599                        }
19600                        mBatteryStatsService.noteEvent(
19601                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19602                                Integer.toString(userId), userId);
19603                        mSystemServiceManager.stopUser(userId);
19604                        broadcastIntentLocked(null, null, shutdownIntent,
19605                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19606                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19607                    }
19608                };
19609                // Kick things off.
19610                broadcastIntentLocked(null, null, stoppingIntent,
19611                        null, stoppingReceiver, 0, null, null,
19612                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19613                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19614            } finally {
19615                Binder.restoreCallingIdentity(ident);
19616            }
19617        }
19618
19619        return ActivityManager.USER_OP_SUCCESS;
19620    }
19621
19622    void finishUserStop(UserStartedState uss) {
19623        final int userId = uss.mHandle.getIdentifier();
19624        boolean stopped;
19625        ArrayList<IStopUserCallback> callbacks;
19626        synchronized (this) {
19627            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19628            if (mStartedUsers.get(userId) != uss) {
19629                stopped = false;
19630            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19631                stopped = false;
19632            } else {
19633                stopped = true;
19634                // User can no longer run.
19635                mStartedUsers.remove(userId);
19636                mUserLru.remove(Integer.valueOf(userId));
19637                updateStartedUserArrayLocked();
19638
19639                // Clean up all state and processes associated with the user.
19640                // Kill all the processes for the user.
19641                forceStopUserLocked(userId, "finish user");
19642            }
19643
19644            // Explicitly remove the old information in mRecentTasks.
19645            mRecentTasks.removeTasksForUserLocked(userId);
19646        }
19647
19648        for (int i=0; i<callbacks.size(); i++) {
19649            try {
19650                if (stopped) callbacks.get(i).userStopped(userId);
19651                else callbacks.get(i).userStopAborted(userId);
19652            } catch (RemoteException e) {
19653            }
19654        }
19655
19656        if (stopped) {
19657            mSystemServiceManager.cleanupUser(userId);
19658            synchronized (this) {
19659                mStackSupervisor.removeUserLocked(userId);
19660            }
19661        }
19662    }
19663
19664    @Override
19665    public UserInfo getCurrentUser() {
19666        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19667                != PackageManager.PERMISSION_GRANTED) && (
19668                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19669                != PackageManager.PERMISSION_GRANTED)) {
19670            String msg = "Permission Denial: getCurrentUser() from pid="
19671                    + Binder.getCallingPid()
19672                    + ", uid=" + Binder.getCallingUid()
19673                    + " requires " + INTERACT_ACROSS_USERS;
19674            Slog.w(TAG, msg);
19675            throw new SecurityException(msg);
19676        }
19677        synchronized (this) {
19678            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19679            return getUserManagerLocked().getUserInfo(userId);
19680        }
19681    }
19682
19683    int getCurrentUserIdLocked() {
19684        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19685    }
19686
19687    @Override
19688    public boolean isUserRunning(int userId, boolean orStopped) {
19689        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19690                != PackageManager.PERMISSION_GRANTED) {
19691            String msg = "Permission Denial: isUserRunning() from pid="
19692                    + Binder.getCallingPid()
19693                    + ", uid=" + Binder.getCallingUid()
19694                    + " requires " + INTERACT_ACROSS_USERS;
19695            Slog.w(TAG, msg);
19696            throw new SecurityException(msg);
19697        }
19698        synchronized (this) {
19699            return isUserRunningLocked(userId, orStopped);
19700        }
19701    }
19702
19703    boolean isUserRunningLocked(int userId, boolean orStopped) {
19704        UserStartedState state = mStartedUsers.get(userId);
19705        if (state == null) {
19706            return false;
19707        }
19708        if (orStopped) {
19709            return true;
19710        }
19711        return state.mState != UserStartedState.STATE_STOPPING
19712                && state.mState != UserStartedState.STATE_SHUTDOWN;
19713    }
19714
19715    @Override
19716    public int[] getRunningUserIds() {
19717        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19718                != PackageManager.PERMISSION_GRANTED) {
19719            String msg = "Permission Denial: isUserRunning() from pid="
19720                    + Binder.getCallingPid()
19721                    + ", uid=" + Binder.getCallingUid()
19722                    + " requires " + INTERACT_ACROSS_USERS;
19723            Slog.w(TAG, msg);
19724            throw new SecurityException(msg);
19725        }
19726        synchronized (this) {
19727            return mStartedUserArray;
19728        }
19729    }
19730
19731    private void updateStartedUserArrayLocked() {
19732        int num = 0;
19733        for (int i=0; i<mStartedUsers.size();  i++) {
19734            UserStartedState uss = mStartedUsers.valueAt(i);
19735            // This list does not include stopping users.
19736            if (uss.mState != UserStartedState.STATE_STOPPING
19737                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19738                num++;
19739            }
19740        }
19741        mStartedUserArray = new int[num];
19742        num = 0;
19743        for (int i=0; i<mStartedUsers.size();  i++) {
19744            UserStartedState uss = mStartedUsers.valueAt(i);
19745            if (uss.mState != UserStartedState.STATE_STOPPING
19746                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19747                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19748                num++;
19749            }
19750        }
19751    }
19752
19753    @Override
19754    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19755        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19756                != PackageManager.PERMISSION_GRANTED) {
19757            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19758                    + Binder.getCallingPid()
19759                    + ", uid=" + Binder.getCallingUid()
19760                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19761            Slog.w(TAG, msg);
19762            throw new SecurityException(msg);
19763        }
19764
19765        mUserSwitchObservers.register(observer);
19766    }
19767
19768    @Override
19769    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19770        mUserSwitchObservers.unregister(observer);
19771    }
19772
19773    int[] getUsersLocked() {
19774        UserManagerService ums = getUserManagerLocked();
19775        return ums != null ? ums.getUserIds() : new int[] { 0 };
19776    }
19777
19778    UserManagerService getUserManagerLocked() {
19779        if (mUserManager == null) {
19780            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19781            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19782        }
19783        return mUserManager;
19784    }
19785
19786    private int applyUserId(int uid, int userId) {
19787        return UserHandle.getUid(userId, uid);
19788    }
19789
19790    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19791        if (info == null) return null;
19792        ApplicationInfo newInfo = new ApplicationInfo(info);
19793        newInfo.uid = applyUserId(info.uid, userId);
19794        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
19795                userId).getAbsolutePath();
19796        return newInfo;
19797    }
19798
19799    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19800        if (aInfo == null
19801                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19802            return aInfo;
19803        }
19804
19805        ActivityInfo info = new ActivityInfo(aInfo);
19806        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19807        return info;
19808    }
19809
19810    private final class LocalService extends ActivityManagerInternal {
19811        @Override
19812        public void onWakefulnessChanged(int wakefulness) {
19813            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19814        }
19815
19816        @Override
19817        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19818                String processName, String abiOverride, int uid, Runnable crashHandler) {
19819            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19820                    processName, abiOverride, uid, crashHandler);
19821        }
19822
19823        @Override
19824        public SleepToken acquireSleepToken(String tag) {
19825            Preconditions.checkNotNull(tag);
19826
19827            synchronized (ActivityManagerService.this) {
19828                SleepTokenImpl token = new SleepTokenImpl(tag);
19829                mSleepTokens.add(token);
19830                updateSleepIfNeededLocked();
19831                return token;
19832            }
19833        }
19834    }
19835
19836    private final class SleepTokenImpl extends SleepToken {
19837        private final String mTag;
19838        private final long mAcquireTime;
19839
19840        public SleepTokenImpl(String tag) {
19841            mTag = tag;
19842            mAcquireTime = SystemClock.uptimeMillis();
19843        }
19844
19845        @Override
19846        public void release() {
19847            synchronized (ActivityManagerService.this) {
19848                if (mSleepTokens.remove(this)) {
19849                    updateSleepIfNeededLocked();
19850                }
19851            }
19852        }
19853
19854        @Override
19855        public String toString() {
19856            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
19857        }
19858    }
19859
19860    /**
19861     * An implementation of IAppTask, that allows an app to manage its own tasks via
19862     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19863     * only the process that calls getAppTasks() can call the AppTask methods.
19864     */
19865    class AppTaskImpl extends IAppTask.Stub {
19866        private int mTaskId;
19867        private int mCallingUid;
19868
19869        public AppTaskImpl(int taskId, int callingUid) {
19870            mTaskId = taskId;
19871            mCallingUid = callingUid;
19872        }
19873
19874        private void checkCaller() {
19875            if (mCallingUid != Binder.getCallingUid()) {
19876                throw new SecurityException("Caller " + mCallingUid
19877                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19878            }
19879        }
19880
19881        @Override
19882        public void finishAndRemoveTask() {
19883            checkCaller();
19884
19885            synchronized (ActivityManagerService.this) {
19886                long origId = Binder.clearCallingIdentity();
19887                try {
19888                    if (!removeTaskByIdLocked(mTaskId, false)) {
19889                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19890                    }
19891                } finally {
19892                    Binder.restoreCallingIdentity(origId);
19893                }
19894            }
19895        }
19896
19897        @Override
19898        public ActivityManager.RecentTaskInfo getTaskInfo() {
19899            checkCaller();
19900
19901            synchronized (ActivityManagerService.this) {
19902                long origId = Binder.clearCallingIdentity();
19903                try {
19904                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19905                    if (tr == null) {
19906                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19907                    }
19908                    return createRecentTaskInfoFromTaskRecord(tr);
19909                } finally {
19910                    Binder.restoreCallingIdentity(origId);
19911                }
19912            }
19913        }
19914
19915        @Override
19916        public void moveToFront() {
19917            checkCaller();
19918            // Will bring task to front if it already has a root activity.
19919            startActivityFromRecentsInner(mTaskId, null);
19920        }
19921
19922        @Override
19923        public int startActivity(IBinder whoThread, String callingPackage,
19924                Intent intent, String resolvedType, Bundle options) {
19925            checkCaller();
19926
19927            int callingUser = UserHandle.getCallingUserId();
19928            TaskRecord tr;
19929            IApplicationThread appThread;
19930            synchronized (ActivityManagerService.this) {
19931                tr = mRecentTasks.taskForIdLocked(mTaskId);
19932                if (tr == null) {
19933                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19934                }
19935                appThread = ApplicationThreadNative.asInterface(whoThread);
19936                if (appThread == null) {
19937                    throw new IllegalArgumentException("Bad app thread " + appThread);
19938                }
19939            }
19940            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19941                    resolvedType, null, null, null, null, 0, 0, null, null,
19942                    null, options, callingUser, null, tr);
19943        }
19944
19945        @Override
19946        public void setExcludeFromRecents(boolean exclude) {
19947            checkCaller();
19948
19949            synchronized (ActivityManagerService.this) {
19950                long origId = Binder.clearCallingIdentity();
19951                try {
19952                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19953                    if (tr == null) {
19954                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19955                    }
19956                    Intent intent = tr.getBaseIntent();
19957                    if (exclude) {
19958                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19959                    } else {
19960                        intent.setFlags(intent.getFlags()
19961                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19962                    }
19963                } finally {
19964                    Binder.restoreCallingIdentity(origId);
19965                }
19966            }
19967        }
19968    }
19969}
19970