ActivityManagerService.java revision 7ddfc7b0245d600605efc4d764378f40d6861437
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_PRIV;
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.BroadcastOptions;
43import android.app.IActivityContainer;
44import android.app.IActivityContainerCallback;
45import android.app.IAppTask;
46import android.app.ITaskStackListener;
47import android.app.ProfilerInfo;
48import android.app.assist.AssistContent;
49import android.app.assist.AssistStructure;
50import android.app.usage.UsageEvents;
51import android.app.usage.UsageStatsManagerInternal;
52import android.appwidget.AppWidgetManager;
53import android.content.pm.PermissionInfo;
54import android.content.res.Resources;
55import android.graphics.Bitmap;
56import android.graphics.Point;
57import android.graphics.Rect;
58import android.os.BatteryStats;
59import android.os.PersistableBundle;
60import android.os.PowerManager;
61import android.os.Trace;
62import android.os.TransactionTooLargeException;
63import android.os.WorkSource;
64import android.os.storage.IMountService;
65import android.os.storage.MountServiceInternal;
66import android.os.storage.StorageManager;
67import android.service.voice.IVoiceInteractionSession;
68import android.service.voice.VoiceInteractionSession;
69import android.util.ArrayMap;
70import android.util.ArraySet;
71import android.util.DebugUtils;
72import android.util.SparseIntArray;
73import android.view.Display;
74
75import com.android.internal.R;
76import com.android.internal.annotations.GuardedBy;
77import com.android.internal.app.AssistUtils;
78import com.android.internal.app.DumpHeapActivity;
79import com.android.internal.app.IAppOpsService;
80import com.android.internal.app.IVoiceInteractor;
81import com.android.internal.app.ProcessMap;
82import com.android.internal.app.ProcessStats;
83import com.android.internal.os.BackgroundThread;
84import com.android.internal.os.BatteryStatsImpl;
85import com.android.internal.os.IResultReceiver;
86import com.android.internal.os.ProcessCpuTracker;
87import com.android.internal.os.TransferPipe;
88import com.android.internal.os.Zygote;
89import com.android.internal.util.ArrayUtils;
90import com.android.internal.util.FastPrintWriter;
91import com.android.internal.util.FastXmlSerializer;
92import com.android.internal.util.MemInfoReader;
93import com.android.internal.util.Preconditions;
94import com.android.server.AppOpsService;
95import com.android.server.AttributeCache;
96import com.android.server.DeviceIdleController;
97import com.android.server.IntentResolver;
98import com.android.server.LocalServices;
99import com.android.server.ServiceThread;
100import com.android.server.SystemService;
101import com.android.server.SystemServiceManager;
102import com.android.server.Watchdog;
103import com.android.server.am.ActivityStack.ActivityState;
104import com.android.server.firewall.IntentFirewall;
105import com.android.server.pm.Installer;
106import com.android.server.pm.UserManagerService;
107import com.android.server.statusbar.StatusBarManagerInternal;
108import com.android.server.wm.AppTransition;
109import com.android.server.wm.WindowManagerService;
110import com.google.android.collect.Lists;
111import com.google.android.collect.Maps;
112
113import libcore.io.IoUtils;
114import libcore.util.EmptyArray;
115
116import org.xmlpull.v1.XmlPullParser;
117import org.xmlpull.v1.XmlPullParserException;
118import org.xmlpull.v1.XmlSerializer;
119
120import android.app.Activity;
121import android.app.ActivityManager;
122import android.app.ActivityManager.RunningTaskInfo;
123import android.app.ActivityManager.StackInfo;
124import android.app.ActivityManagerInternal;
125import android.app.ActivityManagerInternal.SleepToken;
126import android.app.ActivityManagerNative;
127import android.app.ActivityOptions;
128import android.app.ActivityThread;
129import android.app.AlertDialog;
130import android.app.AppGlobals;
131import android.app.ApplicationErrorReport;
132import android.app.Dialog;
133import android.app.IActivityController;
134import android.app.IApplicationThread;
135import android.app.IInstrumentationWatcher;
136import android.app.INotificationManager;
137import android.app.IProcessObserver;
138import android.app.IServiceConnection;
139import android.app.IStopUserCallback;
140import android.app.IUidObserver;
141import android.app.IUiAutomationConnection;
142import android.app.IUserSwitchObserver;
143import android.app.Instrumentation;
144import android.app.Notification;
145import android.app.NotificationManager;
146import android.app.PendingIntent;
147import android.app.backup.IBackupManager;
148import android.app.admin.DevicePolicyManager;
149import android.content.ActivityNotFoundException;
150import android.content.BroadcastReceiver;
151import android.content.ClipData;
152import android.content.ComponentCallbacks2;
153import android.content.ComponentName;
154import android.content.ContentProvider;
155import android.content.ContentResolver;
156import android.content.Context;
157import android.content.DialogInterface;
158import android.content.IContentProvider;
159import android.content.IIntentReceiver;
160import android.content.IIntentSender;
161import android.content.Intent;
162import android.content.IntentFilter;
163import android.content.IntentSender;
164import android.content.pm.ActivityInfo;
165import android.content.pm.ApplicationInfo;
166import android.content.pm.ConfigurationInfo;
167import android.content.pm.IPackageDataObserver;
168import android.content.pm.IPackageManager;
169import android.content.pm.InstrumentationInfo;
170import android.content.pm.PackageInfo;
171import android.content.pm.PackageManager;
172import android.content.pm.ParceledListSlice;
173import android.content.pm.UserInfo;
174import android.content.pm.PackageManager.NameNotFoundException;
175import android.content.pm.PathPermission;
176import android.content.pm.ProviderInfo;
177import android.content.pm.ResolveInfo;
178import android.content.pm.ServiceInfo;
179import android.content.res.CompatibilityInfo;
180import android.content.res.Configuration;
181import android.net.Proxy;
182import android.net.ProxyInfo;
183import android.net.Uri;
184import android.os.Binder;
185import android.os.Build;
186import android.os.Bundle;
187import android.os.Debug;
188import android.os.DropBoxManager;
189import android.os.Environment;
190import android.os.FactoryTest;
191import android.os.FileObserver;
192import android.os.FileUtils;
193import android.os.Handler;
194import android.os.IBinder;
195import android.os.IPermissionController;
196import android.os.IProcessInfoService;
197import android.os.IRemoteCallback;
198import android.os.IUserManager;
199import android.os.Looper;
200import android.os.Message;
201import android.os.Parcel;
202import android.os.ParcelFileDescriptor;
203import android.os.PowerManagerInternal;
204import android.os.Process;
205import android.os.RemoteCallbackList;
206import android.os.RemoteException;
207import android.os.SELinux;
208import android.os.ServiceManager;
209import android.os.StrictMode;
210import android.os.SystemClock;
211import android.os.SystemProperties;
212import android.os.UpdateLock;
213import android.os.UserHandle;
214import android.os.UserManager;
215import android.provider.Settings;
216import android.text.format.DateUtils;
217import android.text.format.Time;
218import android.util.AtomicFile;
219import android.util.EventLog;
220import android.util.Log;
221import android.util.Pair;
222import android.util.PrintWriterPrinter;
223import android.util.Slog;
224import android.util.SparseArray;
225import android.util.TimeUtils;
226import android.util.Xml;
227import android.view.Gravity;
228import android.view.LayoutInflater;
229import android.view.View;
230import android.view.WindowManager;
231
232import dalvik.system.VMRuntime;
233
234import java.io.BufferedInputStream;
235import java.io.BufferedOutputStream;
236import java.io.DataInputStream;
237import java.io.DataOutputStream;
238import java.io.File;
239import java.io.FileDescriptor;
240import java.io.FileInputStream;
241import java.io.FileNotFoundException;
242import java.io.FileOutputStream;
243import java.io.IOException;
244import java.io.InputStreamReader;
245import java.io.PrintWriter;
246import java.io.StringWriter;
247import java.lang.ref.WeakReference;
248import java.nio.charset.StandardCharsets;
249import java.util.ArrayList;
250import java.util.Arrays;
251import java.util.Collections;
252import java.util.Comparator;
253import java.util.HashMap;
254import java.util.HashSet;
255import java.util.Iterator;
256import java.util.List;
257import java.util.Locale;
258import java.util.Map;
259import java.util.Set;
260import java.util.concurrent.atomic.AtomicBoolean;
261import java.util.concurrent.atomic.AtomicLong;
262
263public final class ActivityManagerService extends ActivityManagerNative
264        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
265
266    // File that stores last updated system version and called preboot receivers
267    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
268
269    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
270    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
271    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
272    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
273    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
274    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
275    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
276    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
277    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
278    private static final String TAG_LRU = TAG + POSTFIX_LRU;
279    private static final String TAG_MU = TAG + POSTFIX_MU;
280    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
281    private static final String TAG_POWER = TAG + POSTFIX_POWER;
282    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
283    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
284    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
285    private static final String TAG_PSS = TAG + POSTFIX_PSS;
286    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
287    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
288    private static final String TAG_STACK = TAG + POSTFIX_STACK;
289    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
291    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
292    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
294
295    /** Control over CPU and battery monitoring */
296    // write battery stats every 30 minutes.
297    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
298    static final boolean MONITOR_CPU_USAGE = true;
299    // don't sample cpu less than every 5 seconds.
300    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
301    // wait possibly forever for next cpu sample.
302    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
303    static final boolean MONITOR_THREAD_CPU_USAGE = false;
304
305    // The flags that are set for all calls we make to the package manager.
306    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
307
308    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
309
310    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
311
312    // Amount of time after a call to stopAppSwitches() during which we will
313    // prevent further untrusted switches from happening.
314    static final long APP_SWITCH_DELAY_TIME = 5*1000;
315
316    // How long we wait for a launched process to attach to the activity manager
317    // before we decide it's never going to come up for real.
318    static final int PROC_START_TIMEOUT = 10*1000;
319
320    // How long we wait for a launched process to attach to the activity manager
321    // before we decide it's never going to come up for real, when the process was
322    // started with a wrapper for instrumentation (such as Valgrind) because it
323    // could take much longer than usual.
324    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
325
326    // How long to wait after going idle before forcing apps to GC.
327    static final int GC_TIMEOUT = 5*1000;
328
329    // The minimum amount of time between successive GC requests for a process.
330    static final int GC_MIN_INTERVAL = 60*1000;
331
332    // The minimum amount of time between successive PSS requests for a process.
333    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
334
335    // The minimum amount of time between successive PSS requests for a process
336    // when the request is due to the memory state being lowered.
337    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
338
339    // The rate at which we check for apps using excessive power -- 15 mins.
340    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
341
342    // The minimum sample duration we will allow before deciding we have
343    // enough data on wake locks to start killing things.
344    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
345
346    // The minimum sample duration we will allow before deciding we have
347    // enough data on CPU usage to start killing things.
348    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
349
350    // How long we allow a receiver to run before giving up on it.
351    static final int BROADCAST_FG_TIMEOUT = 10*1000;
352    static final int BROADCAST_BG_TIMEOUT = 60*1000;
353
354    // How long we wait until we timeout on key dispatching.
355    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
356
357    // How long we wait until we timeout on key dispatching during instrumentation.
358    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
359
360    // Amount of time we wait for observers to handle a user switch before
361    // giving up on them and unfreezing the screen.
362    static final int USER_SWITCH_TIMEOUT = 2*1000;
363
364    // This is the amount of time an app needs to be running a foreground service before
365    // we will consider it to be doing interaction for usage stats.
366    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
367
368    // Maximum number of users we allow to be running at a time.
369    static final int MAX_RUNNING_USERS = 3;
370
371    // How long to wait in getAssistContextExtras for the activity and foreground services
372    // to respond with the result.
373    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
374
375    // How long top wait when going through the modern assist (which doesn't need to block
376    // on getting this result before starting to launch its UI).
377    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
378
379    // Maximum number of persisted Uri grants a package is allowed
380    static final int MAX_PERSISTED_URI_GRANTS = 128;
381
382    static final int MY_PID = Process.myPid();
383
384    static final String[] EMPTY_STRING_ARRAY = new String[0];
385
386    // How many bytes to write into the dropbox log before truncating
387    static final int DROPBOX_MAX_SIZE = 256 * 1024;
388
389    // Access modes for handleIncomingUser.
390    static final int ALLOW_NON_FULL = 0;
391    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
392    static final int ALLOW_FULL_ONLY = 2;
393
394    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
395
396    // Delay in notifying task stack change listeners (in millis)
397    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
398
399    // Necessary ApplicationInfo flags to mark an app as persistent
400    private static final int PERSISTENT_MASK =
401            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
402
403    /** All system services */
404    SystemServiceManager mSystemServiceManager;
405
406    private Installer mInstaller;
407
408    /** Run all ActivityStacks through this */
409    ActivityStackSupervisor mStackSupervisor;
410
411    /** Task stack change listeners. */
412    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
413            new RemoteCallbackList<ITaskStackListener>();
414
415    public IntentFirewall mIntentFirewall;
416
417    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
418    // default actuion automatically.  Important for devices without direct input
419    // devices.
420    private boolean mShowDialogs = true;
421
422    BroadcastQueue mFgBroadcastQueue;
423    BroadcastQueue mBgBroadcastQueue;
424    // Convenient for easy iteration over the queues. Foreground is first
425    // so that dispatch of foreground broadcasts gets precedence.
426    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
427
428    BroadcastQueue broadcastQueueForIntent(Intent intent) {
429        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
430        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
431                "Broadcast intent " + intent + " on "
432                + (isFg ? "foreground" : "background") + " queue");
433        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
434    }
435
436    /**
437     * Activity we have told the window manager to have key focus.
438     */
439    ActivityRecord mFocusedActivity = null;
440
441    /**
442     * User id of the last activity mFocusedActivity was set to.
443     */
444    private int mLastFocusedUserId;
445
446    /**
447     * If non-null, we are tracking the time the user spends in the currently focused app.
448     */
449    private AppTimeTracker mCurAppTimeTracker;
450
451    /**
452     * List of intents that were used to start the most recent tasks.
453     */
454    private final RecentTasks mRecentTasks;
455
456    /**
457     * For addAppTask: cached of the last activity component that was added.
458     */
459    ComponentName mLastAddedTaskComponent;
460
461    /**
462     * For addAppTask: cached of the last activity uid that was added.
463     */
464    int mLastAddedTaskUid;
465
466    /**
467     * For addAppTask: cached of the last ActivityInfo that was added.
468     */
469    ActivityInfo mLastAddedTaskActivity;
470
471    /**
472     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
473     */
474    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
475
476    /**
477     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
478     */
479    String mDeviceOwnerName;
480
481    public class PendingAssistExtras extends Binder implements Runnable {
482        public final ActivityRecord activity;
483        public final Bundle extras;
484        public final Intent intent;
485        public final String hint;
486        public final IResultReceiver receiver;
487        public final int userHandle;
488        public boolean haveResult = false;
489        public Bundle result = null;
490        public AssistStructure structure = null;
491        public AssistContent content = null;
492        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
493                String _hint, IResultReceiver _receiver, int _userHandle) {
494            activity = _activity;
495            extras = _extras;
496            intent = _intent;
497            hint = _hint;
498            receiver = _receiver;
499            userHandle = _userHandle;
500        }
501        @Override
502        public void run() {
503            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
504            synchronized (this) {
505                haveResult = true;
506                notifyAll();
507            }
508            pendingAssistExtrasTimedOut(this);
509        }
510    }
511
512    final ArrayList<PendingAssistExtras> mPendingAssistExtras
513            = new ArrayList<PendingAssistExtras>();
514
515    /**
516     * Process management.
517     */
518    final ProcessList mProcessList = new ProcessList();
519
520    /**
521     * All of the applications we currently have running organized by name.
522     * The keys are strings of the application package name (as
523     * returned by the package manager), and the keys are ApplicationRecord
524     * objects.
525     */
526    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
527
528    /**
529     * Tracking long-term execution of processes to look for abuse and other
530     * bad app behavior.
531     */
532    final ProcessStatsService mProcessStats;
533
534    /**
535     * The currently running isolated processes.
536     */
537    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
538
539    /**
540     * Counter for assigning isolated process uids, to avoid frequently reusing the
541     * same ones.
542     */
543    int mNextIsolatedProcessUid = 0;
544
545    /**
546     * The currently running heavy-weight process, if any.
547     */
548    ProcessRecord mHeavyWeightProcess = null;
549
550    /**
551     * The last time that various processes have crashed.
552     */
553    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
554
555    /**
556     * Information about a process that is currently marked as bad.
557     */
558    static final class BadProcessInfo {
559        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
560            this.time = time;
561            this.shortMsg = shortMsg;
562            this.longMsg = longMsg;
563            this.stack = stack;
564        }
565
566        final long time;
567        final String shortMsg;
568        final String longMsg;
569        final String stack;
570    }
571
572    /**
573     * Set of applications that we consider to be bad, and will reject
574     * incoming broadcasts from (which the user has no control over).
575     * Processes are added to this set when they have crashed twice within
576     * a minimum amount of time; they are removed from it when they are
577     * later restarted (hopefully due to some user action).  The value is the
578     * time it was added to the list.
579     */
580    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
581
582    /**
583     * All of the processes we currently have running organized by pid.
584     * The keys are the pid running the application.
585     *
586     * <p>NOTE: This object is protected by its own lock, NOT the global
587     * activity manager lock!
588     */
589    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
590
591    /**
592     * All of the processes that have been forced to be foreground.  The key
593     * is the pid of the caller who requested it (we hold a death
594     * link on it).
595     */
596    abstract class ForegroundToken implements IBinder.DeathRecipient {
597        int pid;
598        IBinder token;
599    }
600    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
601
602    /**
603     * List of records for processes that someone had tried to start before the
604     * system was ready.  We don't start them at that point, but ensure they
605     * are started by the time booting is complete.
606     */
607    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
608
609    /**
610     * List of persistent applications that are in the process
611     * of being started.
612     */
613    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
614
615    /**
616     * Processes that are being forcibly torn down.
617     */
618    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
619
620    /**
621     * List of running applications, sorted by recent usage.
622     * The first entry in the list is the least recently used.
623     */
624    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
625
626    /**
627     * Where in mLruProcesses that the processes hosting activities start.
628     */
629    int mLruProcessActivityStart = 0;
630
631    /**
632     * Where in mLruProcesses that the processes hosting services start.
633     * This is after (lower index) than mLruProcessesActivityStart.
634     */
635    int mLruProcessServiceStart = 0;
636
637    /**
638     * List of processes that should gc as soon as things are idle.
639     */
640    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
641
642    /**
643     * Processes we want to collect PSS data from.
644     */
645    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
646
647    /**
648     * Last time we requested PSS data of all processes.
649     */
650    long mLastFullPssTime = SystemClock.uptimeMillis();
651
652    /**
653     * If set, the next time we collect PSS data we should do a full collection
654     * with data from native processes and the kernel.
655     */
656    boolean mFullPssPending = false;
657
658    /**
659     * This is the process holding what we currently consider to be
660     * the "home" activity.
661     */
662    ProcessRecord mHomeProcess;
663
664    /**
665     * This is the process holding the activity the user last visited that
666     * is in a different process from the one they are currently in.
667     */
668    ProcessRecord mPreviousProcess;
669
670    /**
671     * The time at which the previous process was last visible.
672     */
673    long mPreviousProcessVisibleTime;
674
675    /**
676     * Track all uids that have actively running processes.
677     */
678    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
679
680    /**
681     * Which users have been started, so are allowed to run code.
682     */
683    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
684
685    /**
686     * LRU list of history of current users.  Most recently current is at the end.
687     */
688    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
689
690    /**
691     * Constant array of the users that are currently started.
692     */
693    int[] mStartedUserArray = new int[] { 0 };
694
695    /**
696     * Registered observers of the user switching mechanics.
697     */
698    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
699            = new RemoteCallbackList<IUserSwitchObserver>();
700
701    /**
702     * Currently active user switch.
703     */
704    Object mCurUserSwitchCallback;
705
706    /**
707     * Packages that the user has asked to have run in screen size
708     * compatibility mode instead of filling the screen.
709     */
710    final CompatModePackages mCompatModePackages;
711
712    /**
713     * Set of IntentSenderRecord objects that are currently active.
714     */
715    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
716            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
717
718    /**
719     * Fingerprints (hashCode()) of stack traces that we've
720     * already logged DropBox entries for.  Guarded by itself.  If
721     * something (rogue user app) forces this over
722     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
723     */
724    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
725    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
726
727    /**
728     * Strict Mode background batched logging state.
729     *
730     * The string buffer is guarded by itself, and its lock is also
731     * used to determine if another batched write is already
732     * in-flight.
733     */
734    private final StringBuilder mStrictModeBuffer = new StringBuilder();
735
736    /**
737     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
738     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
739     */
740    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
741
742    /**
743     * Resolver for broadcast intents to registered receivers.
744     * Holds BroadcastFilter (subclass of IntentFilter).
745     */
746    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
747            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
748        @Override
749        protected boolean allowFilterResult(
750                BroadcastFilter filter, List<BroadcastFilter> dest) {
751            IBinder target = filter.receiverList.receiver.asBinder();
752            for (int i = dest.size() - 1; i >= 0; i--) {
753                if (dest.get(i).receiverList.receiver.asBinder() == target) {
754                    return false;
755                }
756            }
757            return true;
758        }
759
760        @Override
761        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
762            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
763                    || userId == filter.owningUserId) {
764                return super.newResult(filter, match, userId);
765            }
766            return null;
767        }
768
769        @Override
770        protected BroadcastFilter[] newArray(int size) {
771            return new BroadcastFilter[size];
772        }
773
774        @Override
775        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
776            return packageName.equals(filter.packageName);
777        }
778    };
779
780    /**
781     * State of all active sticky broadcasts per user.  Keys are the action of the
782     * sticky Intent, values are an ArrayList of all broadcasted intents with
783     * that action (which should usually be one).  The SparseArray is keyed
784     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
785     * for stickies that are sent to all users.
786     */
787    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
788            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
789
790    final ActiveServices mServices;
791
792    final static class Association {
793        final int mSourceUid;
794        final String mSourceProcess;
795        final int mTargetUid;
796        final ComponentName mTargetComponent;
797        final String mTargetProcess;
798
799        int mCount;
800        long mTime;
801
802        int mNesting;
803        long mStartTime;
804
805        Association(int sourceUid, String sourceProcess, int targetUid,
806                ComponentName targetComponent, String targetProcess) {
807            mSourceUid = sourceUid;
808            mSourceProcess = sourceProcess;
809            mTargetUid = targetUid;
810            mTargetComponent = targetComponent;
811            mTargetProcess = targetProcess;
812        }
813    }
814
815    /**
816     * When service association tracking is enabled, this is all of the associations we
817     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
818     * -> association data.
819     */
820    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
821            mAssociations = new SparseArray<>();
822    boolean mTrackingAssociations;
823
824    /**
825     * Backup/restore process management
826     */
827    String mBackupAppName = null;
828    BackupRecord mBackupTarget = null;
829
830    final ProviderMap mProviderMap;
831
832    /**
833     * List of content providers who have clients waiting for them.  The
834     * application is currently being launched and the provider will be
835     * removed from this list once it is published.
836     */
837    final ArrayList<ContentProviderRecord> mLaunchingProviders
838            = new ArrayList<ContentProviderRecord>();
839
840    /**
841     * File storing persisted {@link #mGrantedUriPermissions}.
842     */
843    private final AtomicFile mGrantFile;
844
845    /** XML constants used in {@link #mGrantFile} */
846    private static final String TAG_URI_GRANTS = "uri-grants";
847    private static final String TAG_URI_GRANT = "uri-grant";
848    private static final String ATTR_USER_HANDLE = "userHandle";
849    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
850    private static final String ATTR_TARGET_USER_ID = "targetUserId";
851    private static final String ATTR_SOURCE_PKG = "sourcePkg";
852    private static final String ATTR_TARGET_PKG = "targetPkg";
853    private static final String ATTR_URI = "uri";
854    private static final String ATTR_MODE_FLAGS = "modeFlags";
855    private static final String ATTR_CREATED_TIME = "createdTime";
856    private static final String ATTR_PREFIX = "prefix";
857
858    /**
859     * Global set of specific {@link Uri} permissions that have been granted.
860     * This optimized lookup structure maps from {@link UriPermission#targetUid}
861     * to {@link UriPermission#uri} to {@link UriPermission}.
862     */
863    @GuardedBy("this")
864    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
865            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
866
867    public static class GrantUri {
868        public final int sourceUserId;
869        public final Uri uri;
870        public boolean prefix;
871
872        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
873            this.sourceUserId = sourceUserId;
874            this.uri = uri;
875            this.prefix = prefix;
876        }
877
878        @Override
879        public int hashCode() {
880            int hashCode = 1;
881            hashCode = 31 * hashCode + sourceUserId;
882            hashCode = 31 * hashCode + uri.hashCode();
883            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
884            return hashCode;
885        }
886
887        @Override
888        public boolean equals(Object o) {
889            if (o instanceof GrantUri) {
890                GrantUri other = (GrantUri) o;
891                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
892                        && prefix == other.prefix;
893            }
894            return false;
895        }
896
897        @Override
898        public String toString() {
899            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
900            if (prefix) result += " [prefix]";
901            return result;
902        }
903
904        public String toSafeString() {
905            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
906            if (prefix) result += " [prefix]";
907            return result;
908        }
909
910        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
911            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
912                    ContentProvider.getUriWithoutUserId(uri), false);
913        }
914    }
915
916    CoreSettingsObserver mCoreSettingsObserver;
917
918    /**
919     * Thread-local storage used to carry caller permissions over through
920     * indirect content-provider access.
921     */
922    private class Identity {
923        public final IBinder token;
924        public final int pid;
925        public final int uid;
926
927        Identity(IBinder _token, int _pid, int _uid) {
928            token = _token;
929            pid = _pid;
930            uid = _uid;
931        }
932    }
933
934    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
935
936    /**
937     * All information we have collected about the runtime performance of
938     * any user id that can impact battery performance.
939     */
940    final BatteryStatsService mBatteryStatsService;
941
942    /**
943     * Information about component usage
944     */
945    UsageStatsManagerInternal mUsageStatsService;
946
947    /**
948     * Access to DeviceIdleController service.
949     */
950    DeviceIdleController.LocalService mLocalDeviceIdleController;
951
952    /**
953     * Information about and control over application operations
954     */
955    final AppOpsService mAppOpsService;
956
957    /**
958     * Save recent tasks information across reboots.
959     */
960    final TaskPersister mTaskPersister;
961
962    /**
963     * Current configuration information.  HistoryRecord objects are given
964     * a reference to this object to indicate which configuration they are
965     * currently running in, so this object must be kept immutable.
966     */
967    Configuration mConfiguration = new Configuration();
968
969    /**
970     * Current sequencing integer of the configuration, for skipping old
971     * configurations.
972     */
973    int mConfigurationSeq = 0;
974
975    /**
976     * Hardware-reported OpenGLES version.
977     */
978    final int GL_ES_VERSION;
979
980    /**
981     * List of initialization arguments to pass to all processes when binding applications to them.
982     * For example, references to the commonly used services.
983     */
984    HashMap<String, IBinder> mAppBindArgs;
985
986    /**
987     * Temporary to avoid allocations.  Protected by main lock.
988     */
989    final StringBuilder mStringBuilder = new StringBuilder(256);
990
991    /**
992     * Used to control how we initialize the service.
993     */
994    ComponentName mTopComponent;
995    String mTopAction = Intent.ACTION_MAIN;
996    String mTopData;
997    boolean mProcessesReady = false;
998    boolean mSystemReady = false;
999    boolean mBooting = false;
1000    boolean mCallFinishBooting = false;
1001    boolean mBootAnimationComplete = false;
1002    boolean mWaitingUpdate = false;
1003    boolean mDidUpdate = false;
1004    boolean mOnBattery = false;
1005    boolean mLaunchWarningShown = false;
1006
1007    Context mContext;
1008
1009    int mFactoryTest;
1010
1011    boolean mCheckedForSetup;
1012
1013    /**
1014     * The time at which we will allow normal application switches again,
1015     * after a call to {@link #stopAppSwitches()}.
1016     */
1017    long mAppSwitchesAllowedTime;
1018
1019    /**
1020     * This is set to true after the first switch after mAppSwitchesAllowedTime
1021     * is set; any switches after that will clear the time.
1022     */
1023    boolean mDidAppSwitch;
1024
1025    /**
1026     * Last time (in realtime) at which we checked for power usage.
1027     */
1028    long mLastPowerCheckRealtime;
1029
1030    /**
1031     * Last time (in uptime) at which we checked for power usage.
1032     */
1033    long mLastPowerCheckUptime;
1034
1035    /**
1036     * Set while we are wanting to sleep, to prevent any
1037     * activities from being started/resumed.
1038     */
1039    private boolean mSleeping = false;
1040
1041    /**
1042     * The process state used for processes that are running the top activities.
1043     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1044     */
1045    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1046
1047    /**
1048     * Set while we are running a voice interaction.  This overrides
1049     * sleeping while it is active.
1050     */
1051    private IVoiceInteractionSession mRunningVoice;
1052
1053    /**
1054     * For some direct access we need to power manager.
1055     */
1056    PowerManagerInternal mLocalPowerManager;
1057
1058    /**
1059     * We want to hold a wake lock while running a voice interaction session, since
1060     * this may happen with the screen off and we need to keep the CPU running to
1061     * be able to continue to interact with the user.
1062     */
1063    PowerManager.WakeLock mVoiceWakeLock;
1064
1065    /**
1066     * State of external calls telling us if the device is awake or asleep.
1067     */
1068    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1069
1070    /**
1071     * A list of tokens that cause the top activity to be put to sleep.
1072     * They are used by components that may hide and block interaction with underlying
1073     * activities.
1074     */
1075    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1076
1077    static final int LOCK_SCREEN_HIDDEN = 0;
1078    static final int LOCK_SCREEN_LEAVING = 1;
1079    static final int LOCK_SCREEN_SHOWN = 2;
1080    /**
1081     * State of external call telling us if the lock screen is shown.
1082     */
1083    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1084
1085    /**
1086     * Set if we are shutting down the system, similar to sleeping.
1087     */
1088    boolean mShuttingDown = false;
1089
1090    /**
1091     * Current sequence id for oom_adj computation traversal.
1092     */
1093    int mAdjSeq = 0;
1094
1095    /**
1096     * Current sequence id for process LRU updating.
1097     */
1098    int mLruSeq = 0;
1099
1100    /**
1101     * Keep track of the non-cached/empty process we last found, to help
1102     * determine how to distribute cached/empty processes next time.
1103     */
1104    int mNumNonCachedProcs = 0;
1105
1106    /**
1107     * Keep track of the number of cached hidden procs, to balance oom adj
1108     * distribution between those and empty procs.
1109     */
1110    int mNumCachedHiddenProcs = 0;
1111
1112    /**
1113     * Keep track of the number of service processes we last found, to
1114     * determine on the next iteration which should be B services.
1115     */
1116    int mNumServiceProcs = 0;
1117    int mNewNumAServiceProcs = 0;
1118    int mNewNumServiceProcs = 0;
1119
1120    /**
1121     * Allow the current computed overall memory level of the system to go down?
1122     * This is set to false when we are killing processes for reasons other than
1123     * memory management, so that the now smaller process list will not be taken as
1124     * an indication that memory is tighter.
1125     */
1126    boolean mAllowLowerMemLevel = false;
1127
1128    /**
1129     * The last computed memory level, for holding when we are in a state that
1130     * processes are going away for other reasons.
1131     */
1132    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1133
1134    /**
1135     * The last total number of process we have, to determine if changes actually look
1136     * like a shrinking number of process due to lower RAM.
1137     */
1138    int mLastNumProcesses;
1139
1140    /**
1141     * The uptime of the last time we performed idle maintenance.
1142     */
1143    long mLastIdleTime = SystemClock.uptimeMillis();
1144
1145    /**
1146     * Total time spent with RAM that has been added in the past since the last idle time.
1147     */
1148    long mLowRamTimeSinceLastIdle = 0;
1149
1150    /**
1151     * If RAM is currently low, when that horrible situation started.
1152     */
1153    long mLowRamStartTime = 0;
1154
1155    /**
1156     * For reporting to battery stats the current top application.
1157     */
1158    private String mCurResumedPackage = null;
1159    private int mCurResumedUid = -1;
1160
1161    /**
1162     * For reporting to battery stats the apps currently running foreground
1163     * service.  The ProcessMap is package/uid tuples; each of these contain
1164     * an array of the currently foreground processes.
1165     */
1166    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1167            = new ProcessMap<ArrayList<ProcessRecord>>();
1168
1169    /**
1170     * This is set if we had to do a delayed dexopt of an app before launching
1171     * it, to increase the ANR timeouts in that case.
1172     */
1173    boolean mDidDexOpt;
1174
1175    /**
1176     * Set if the systemServer made a call to enterSafeMode.
1177     */
1178    boolean mSafeMode;
1179
1180    /**
1181     * If true, we are running under a test environment so will sample PSS from processes
1182     * much more rapidly to try to collect better data when the tests are rapidly
1183     * running through apps.
1184     */
1185    boolean mTestPssMode = false;
1186
1187    String mDebugApp = null;
1188    boolean mWaitForDebugger = false;
1189    boolean mDebugTransient = false;
1190    String mOrigDebugApp = null;
1191    boolean mOrigWaitForDebugger = false;
1192    boolean mAlwaysFinishActivities = false;
1193    IActivityController mController = null;
1194    String mProfileApp = null;
1195    ProcessRecord mProfileProc = null;
1196    String mProfileFile;
1197    ParcelFileDescriptor mProfileFd;
1198    int mSamplingInterval = 0;
1199    boolean mAutoStopProfiler = false;
1200    int mProfileType = 0;
1201    String mOpenGlTraceApp = null;
1202    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1203    String mMemWatchDumpProcName;
1204    String mMemWatchDumpFile;
1205    int mMemWatchDumpPid;
1206    int mMemWatchDumpUid;
1207    String mTrackAllocationApp = null;
1208
1209    final long[] mTmpLong = new long[1];
1210
1211    static final class ProcessChangeItem {
1212        static final int CHANGE_ACTIVITIES = 1<<0;
1213        static final int CHANGE_PROCESS_STATE = 1<<1;
1214        int changes;
1215        int uid;
1216        int pid;
1217        int processState;
1218        boolean foregroundActivities;
1219    }
1220
1221    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1222    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1223
1224    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1225    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1226
1227    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1228    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1229
1230    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1231    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1232
1233    /**
1234     * Runtime CPU use collection thread.  This object's lock is used to
1235     * perform synchronization with the thread (notifying it to run).
1236     */
1237    final Thread mProcessCpuThread;
1238
1239    /**
1240     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1241     * Must acquire this object's lock when accessing it.
1242     * NOTE: this lock will be held while doing long operations (trawling
1243     * through all processes in /proc), so it should never be acquired by
1244     * any critical paths such as when holding the main activity manager lock.
1245     */
1246    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1247            MONITOR_THREAD_CPU_USAGE);
1248    final AtomicLong mLastCpuTime = new AtomicLong(0);
1249    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1250
1251    long mLastWriteTime = 0;
1252
1253    /**
1254     * Used to retain an update lock when the foreground activity is in
1255     * immersive mode.
1256     */
1257    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1258
1259    /**
1260     * Set to true after the system has finished booting.
1261     */
1262    boolean mBooted = false;
1263
1264    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1265    int mProcessLimitOverride = -1;
1266
1267    WindowManagerService mWindowManager;
1268
1269    final ActivityThread mSystemThread;
1270
1271    // Holds the current foreground user's id
1272    int mCurrentUserId = 0;
1273    // Holds the target user's id during a user switch
1274    int mTargetUserId = UserHandle.USER_NULL;
1275    // If there are multiple profiles for the current user, their ids are here
1276    // Currently only the primary user can have managed profiles
1277    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1278
1279    /**
1280     * Mapping from each known user ID to the profile group ID it is associated with.
1281     */
1282    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1283
1284    private UserManagerService mUserManager;
1285
1286    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1287        final ProcessRecord mApp;
1288        final int mPid;
1289        final IApplicationThread mAppThread;
1290
1291        AppDeathRecipient(ProcessRecord app, int pid,
1292                IApplicationThread thread) {
1293            if (DEBUG_ALL) Slog.v(
1294                TAG, "New death recipient " + this
1295                + " for thread " + thread.asBinder());
1296            mApp = app;
1297            mPid = pid;
1298            mAppThread = thread;
1299        }
1300
1301        @Override
1302        public void binderDied() {
1303            if (DEBUG_ALL) Slog.v(
1304                TAG, "Death received in " + this
1305                + " for thread " + mAppThread.asBinder());
1306            synchronized(ActivityManagerService.this) {
1307                appDiedLocked(mApp, mPid, mAppThread, true);
1308            }
1309        }
1310    }
1311
1312    static final int SHOW_ERROR_MSG = 1;
1313    static final int SHOW_NOT_RESPONDING_MSG = 2;
1314    static final int SHOW_FACTORY_ERROR_MSG = 3;
1315    static final int UPDATE_CONFIGURATION_MSG = 4;
1316    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1317    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1318    static final int SERVICE_TIMEOUT_MSG = 12;
1319    static final int UPDATE_TIME_ZONE = 13;
1320    static final int SHOW_UID_ERROR_MSG = 14;
1321    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1322    static final int PROC_START_TIMEOUT_MSG = 20;
1323    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1324    static final int KILL_APPLICATION_MSG = 22;
1325    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1326    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1327    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1328    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1329    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1330    static final int CLEAR_DNS_CACHE_MSG = 28;
1331    static final int UPDATE_HTTP_PROXY_MSG = 29;
1332    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1333    static final int DISPATCH_PROCESSES_CHANGED = 31;
1334    static final int DISPATCH_PROCESS_DIED = 32;
1335    static final int REPORT_MEM_USAGE_MSG = 33;
1336    static final int REPORT_USER_SWITCH_MSG = 34;
1337    static final int CONTINUE_USER_SWITCH_MSG = 35;
1338    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1339    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1340    static final int PERSIST_URI_GRANTS_MSG = 38;
1341    static final int REQUEST_ALL_PSS_MSG = 39;
1342    static final int START_PROFILES_MSG = 40;
1343    static final int UPDATE_TIME = 41;
1344    static final int SYSTEM_USER_START_MSG = 42;
1345    static final int SYSTEM_USER_CURRENT_MSG = 43;
1346    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1347    static final int FINISH_BOOTING_MSG = 45;
1348    static final int START_USER_SWITCH_MSG = 46;
1349    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1350    static final int DISMISS_DIALOG_MSG = 48;
1351    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1352    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1353    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1354    static final int DELETE_DUMPHEAP_MSG = 52;
1355    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1356    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1357    static final int REPORT_TIME_TRACKER_MSG = 55;
1358    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1359    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1360
1361    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1362    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1363    static final int FIRST_COMPAT_MODE_MSG = 300;
1364    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1365
1366    CompatModeDialog mCompatModeDialog;
1367    long mLastMemUsageReportTime = 0;
1368
1369    /**
1370     * Flag whether the current user is a "monkey", i.e. whether
1371     * the UI is driven by a UI automation tool.
1372     */
1373    private boolean mUserIsMonkey;
1374
1375    /** Flag whether the device has a Recents UI */
1376    boolean mHasRecents;
1377
1378    /** The dimensions of the thumbnails in the Recents UI. */
1379    int mThumbnailWidth;
1380    int mThumbnailHeight;
1381
1382    final ServiceThread mHandlerThread;
1383    final MainHandler mHandler;
1384    final UiHandler mUiHandler;
1385
1386    final class UiHandler extends Handler {
1387        public UiHandler() {
1388            super(com.android.server.UiThread.get().getLooper(), null, true);
1389        }
1390
1391        @Override
1392        public void handleMessage(Message msg) {
1393            switch (msg.what) {
1394            case SHOW_ERROR_MSG: {
1395                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1396                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1397                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1398                synchronized (ActivityManagerService.this) {
1399                    ProcessRecord proc = (ProcessRecord)data.get("app");
1400                    AppErrorResult res = (AppErrorResult) data.get("result");
1401                    if (proc != null && proc.crashDialog != null) {
1402                        Slog.e(TAG, "App already has crash dialog: " + proc);
1403                        if (res != null) {
1404                            res.set(0);
1405                        }
1406                        return;
1407                    }
1408                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1409                            >= Process.FIRST_APPLICATION_UID
1410                            && proc.pid != MY_PID);
1411                    for (int userId : mCurrentProfileIds) {
1412                        isBackground &= (proc.userId != userId);
1413                    }
1414                    if (isBackground && !showBackground) {
1415                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1416                        if (res != null) {
1417                            res.set(0);
1418                        }
1419                        return;
1420                    }
1421                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1422                        Dialog d = new AppErrorDialog(mContext,
1423                                ActivityManagerService.this, res, proc);
1424                        d.show();
1425                        proc.crashDialog = d;
1426                    } else {
1427                        // The device is asleep, so just pretend that the user
1428                        // saw a crash dialog and hit "force quit".
1429                        if (res != null) {
1430                            res.set(0);
1431                        }
1432                    }
1433                }
1434
1435                ensureBootCompleted();
1436            } break;
1437            case SHOW_NOT_RESPONDING_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1440                    ProcessRecord proc = (ProcessRecord)data.get("app");
1441                    if (proc != null && proc.anrDialog != null) {
1442                        Slog.e(TAG, "App already has anr dialog: " + proc);
1443                        return;
1444                    }
1445
1446                    Intent intent = new Intent("android.intent.action.ANR");
1447                    if (!mProcessesReady) {
1448                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1449                                | Intent.FLAG_RECEIVER_FOREGROUND);
1450                    }
1451                    broadcastIntentLocked(null, null, intent,
1452                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1453                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1454
1455                    if (mShowDialogs) {
1456                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1457                                mContext, proc, (ActivityRecord)data.get("activity"),
1458                                msg.arg1 != 0);
1459                        d.show();
1460                        proc.anrDialog = d;
1461                    } else {
1462                        // Just kill the app if there is no dialog to be shown.
1463                        killAppAtUsersRequest(proc, null);
1464                    }
1465                }
1466
1467                ensureBootCompleted();
1468            } break;
1469            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1470                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1471                synchronized (ActivityManagerService.this) {
1472                    ProcessRecord proc = (ProcessRecord) data.get("app");
1473                    if (proc == null) {
1474                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1475                        break;
1476                    }
1477                    if (proc.crashDialog != null) {
1478                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1479                        return;
1480                    }
1481                    AppErrorResult res = (AppErrorResult) data.get("result");
1482                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1483                        Dialog d = new StrictModeViolationDialog(mContext,
1484                                ActivityManagerService.this, res, proc);
1485                        d.show();
1486                        proc.crashDialog = d;
1487                    } else {
1488                        // The device is asleep, so just pretend that the user
1489                        // saw a crash dialog and hit "force quit".
1490                        res.set(0);
1491                    }
1492                }
1493                ensureBootCompleted();
1494            } break;
1495            case SHOW_FACTORY_ERROR_MSG: {
1496                Dialog d = new FactoryErrorDialog(
1497                    mContext, msg.getData().getCharSequence("msg"));
1498                d.show();
1499                ensureBootCompleted();
1500            } break;
1501            case WAIT_FOR_DEBUGGER_MSG: {
1502                synchronized (ActivityManagerService.this) {
1503                    ProcessRecord app = (ProcessRecord)msg.obj;
1504                    if (msg.arg1 != 0) {
1505                        if (!app.waitedForDebugger) {
1506                            Dialog d = new AppWaitingForDebuggerDialog(
1507                                    ActivityManagerService.this,
1508                                    mContext, app);
1509                            app.waitDialog = d;
1510                            app.waitedForDebugger = true;
1511                            d.show();
1512                        }
1513                    } else {
1514                        if (app.waitDialog != null) {
1515                            app.waitDialog.dismiss();
1516                            app.waitDialog = null;
1517                        }
1518                    }
1519                }
1520            } break;
1521            case SHOW_UID_ERROR_MSG: {
1522                if (mShowDialogs) {
1523                    AlertDialog d = new BaseErrorDialog(mContext);
1524                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1525                    d.setCancelable(false);
1526                    d.setTitle(mContext.getText(R.string.android_system_label));
1527                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1528                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1529                            obtainMessage(DISMISS_DIALOG_MSG, d));
1530                    d.show();
1531                }
1532            } break;
1533            case SHOW_FINGERPRINT_ERROR_MSG: {
1534                if (mShowDialogs) {
1535                    AlertDialog d = new BaseErrorDialog(mContext);
1536                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1537                    d.setCancelable(false);
1538                    d.setTitle(mContext.getText(R.string.android_system_label));
1539                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1540                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1541                            obtainMessage(DISMISS_DIALOG_MSG, d));
1542                    d.show();
1543                }
1544            } break;
1545            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1546                synchronized (ActivityManagerService.this) {
1547                    ActivityRecord ar = (ActivityRecord) msg.obj;
1548                    if (mCompatModeDialog != null) {
1549                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1550                                ar.info.applicationInfo.packageName)) {
1551                            return;
1552                        }
1553                        mCompatModeDialog.dismiss();
1554                        mCompatModeDialog = null;
1555                    }
1556                    if (ar != null && false) {
1557                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1558                                ar.packageName)) {
1559                            int mode = mCompatModePackages.computeCompatModeLocked(
1560                                    ar.info.applicationInfo);
1561                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1562                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1563                                mCompatModeDialog = new CompatModeDialog(
1564                                        ActivityManagerService.this, mContext,
1565                                        ar.info.applicationInfo);
1566                                mCompatModeDialog.show();
1567                            }
1568                        }
1569                    }
1570                }
1571                break;
1572            }
1573            case START_USER_SWITCH_MSG: {
1574                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1575                break;
1576            }
1577            case DISMISS_DIALOG_MSG: {
1578                final Dialog d = (Dialog) msg.obj;
1579                d.dismiss();
1580                break;
1581            }
1582            case DISPATCH_PROCESSES_CHANGED: {
1583                dispatchProcessesChanged();
1584                break;
1585            }
1586            case DISPATCH_PROCESS_DIED: {
1587                final int pid = msg.arg1;
1588                final int uid = msg.arg2;
1589                dispatchProcessDied(pid, uid);
1590                break;
1591            }
1592            case DISPATCH_UIDS_CHANGED_MSG: {
1593                dispatchUidsChanged();
1594            } break;
1595            }
1596        }
1597    }
1598
1599    final class MainHandler extends Handler {
1600        public MainHandler(Looper looper) {
1601            super(looper, null, true);
1602        }
1603
1604        @Override
1605        public void handleMessage(Message msg) {
1606            switch (msg.what) {
1607            case UPDATE_CONFIGURATION_MSG: {
1608                final ContentResolver resolver = mContext.getContentResolver();
1609                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1610            } break;
1611            case GC_BACKGROUND_PROCESSES_MSG: {
1612                synchronized (ActivityManagerService.this) {
1613                    performAppGcsIfAppropriateLocked();
1614                }
1615            } break;
1616            case SERVICE_TIMEOUT_MSG: {
1617                if (mDidDexOpt) {
1618                    mDidDexOpt = false;
1619                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1620                    nmsg.obj = msg.obj;
1621                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1622                    return;
1623                }
1624                mServices.serviceTimeout((ProcessRecord)msg.obj);
1625            } break;
1626            case UPDATE_TIME_ZONE: {
1627                synchronized (ActivityManagerService.this) {
1628                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1629                        ProcessRecord r = mLruProcesses.get(i);
1630                        if (r.thread != null) {
1631                            try {
1632                                r.thread.updateTimeZone();
1633                            } catch (RemoteException ex) {
1634                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1635                            }
1636                        }
1637                    }
1638                }
1639            } break;
1640            case CLEAR_DNS_CACHE_MSG: {
1641                synchronized (ActivityManagerService.this) {
1642                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1643                        ProcessRecord r = mLruProcesses.get(i);
1644                        if (r.thread != null) {
1645                            try {
1646                                r.thread.clearDnsCache();
1647                            } catch (RemoteException ex) {
1648                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1649                            }
1650                        }
1651                    }
1652                }
1653            } break;
1654            case UPDATE_HTTP_PROXY_MSG: {
1655                ProxyInfo proxy = (ProxyInfo)msg.obj;
1656                String host = "";
1657                String port = "";
1658                String exclList = "";
1659                Uri pacFileUrl = Uri.EMPTY;
1660                if (proxy != null) {
1661                    host = proxy.getHost();
1662                    port = Integer.toString(proxy.getPort());
1663                    exclList = proxy.getExclusionListAsString();
1664                    pacFileUrl = proxy.getPacFileUrl();
1665                }
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to update http proxy for: " +
1674                                        r.info.processName);
1675                            }
1676                        }
1677                    }
1678                }
1679            } break;
1680            case PROC_START_TIMEOUT_MSG: {
1681                if (mDidDexOpt) {
1682                    mDidDexOpt = false;
1683                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1684                    nmsg.obj = msg.obj;
1685                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1686                    return;
1687                }
1688                ProcessRecord app = (ProcessRecord)msg.obj;
1689                synchronized (ActivityManagerService.this) {
1690                    processStartTimedOutLocked(app);
1691                }
1692            } break;
1693            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1696                }
1697            } break;
1698            case KILL_APPLICATION_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    int appid = msg.arg1;
1701                    boolean restart = (msg.arg2 == 1);
1702                    Bundle bundle = (Bundle)msg.obj;
1703                    String pkg = bundle.getString("pkg");
1704                    String reason = bundle.getString("reason");
1705                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1706                            false, UserHandle.USER_ALL, reason);
1707                }
1708            } break;
1709            case FINALIZE_PENDING_INTENT_MSG: {
1710                ((PendingIntentRecord)msg.obj).completeFinalize();
1711            } break;
1712            case POST_HEAVY_NOTIFICATION_MSG: {
1713                INotificationManager inm = NotificationManager.getService();
1714                if (inm == null) {
1715                    return;
1716                }
1717
1718                ActivityRecord root = (ActivityRecord)msg.obj;
1719                ProcessRecord process = root.app;
1720                if (process == null) {
1721                    return;
1722                }
1723
1724                try {
1725                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1726                    String text = mContext.getString(R.string.heavy_weight_notification,
1727                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1728                    Notification notification = new Notification.Builder(context)
1729                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1730                            .setWhen(0)
1731                            .setOngoing(true)
1732                            .setTicker(text)
1733                            .setColor(mContext.getColor(
1734                                    com.android.internal.R.color.system_notification_accent_color))
1735                            .setContentTitle(text)
1736                            .setContentText(
1737                                    mContext.getText(R.string.heavy_weight_notification_detail))
1738                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1739                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1740                                    new UserHandle(root.userId)))
1741                            .build();
1742                    try {
1743                        int[] outId = new int[1];
1744                        inm.enqueueNotificationWithTag("android", "android", null,
1745                                R.string.heavy_weight_notification,
1746                                notification, outId, root.userId);
1747                    } catch (RuntimeException e) {
1748                        Slog.w(ActivityManagerService.TAG,
1749                                "Error showing notification for heavy-weight app", e);
1750                    } catch (RemoteException e) {
1751                    }
1752                } catch (NameNotFoundException e) {
1753                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1754                }
1755            } break;
1756            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1757                INotificationManager inm = NotificationManager.getService();
1758                if (inm == null) {
1759                    return;
1760                }
1761                try {
1762                    inm.cancelNotificationWithTag("android", null,
1763                            R.string.heavy_weight_notification,  msg.arg1);
1764                } catch (RuntimeException e) {
1765                    Slog.w(ActivityManagerService.TAG,
1766                            "Error canceling notification for service", e);
1767                } catch (RemoteException e) {
1768                }
1769            } break;
1770            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1771                synchronized (ActivityManagerService.this) {
1772                    checkExcessivePowerUsageLocked(true);
1773                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1775                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1776                }
1777            } break;
1778            case REPORT_MEM_USAGE_MSG: {
1779                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1780                Thread thread = new Thread() {
1781                    @Override public void run() {
1782                        reportMemUsage(memInfos);
1783                    }
1784                };
1785                thread.start();
1786                break;
1787            }
1788            case REPORT_USER_SWITCH_MSG: {
1789                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case CONTINUE_USER_SWITCH_MSG: {
1793                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case USER_SWITCH_TIMEOUT_MSG: {
1797                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case IMMERSIVE_MODE_LOCK_MSG: {
1801                final boolean nextState = (msg.arg1 != 0);
1802                if (mUpdateLock.isHeld() != nextState) {
1803                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1804                            "Applying new update lock state '" + nextState
1805                            + "' for " + (ActivityRecord)msg.obj);
1806                    if (nextState) {
1807                        mUpdateLock.acquire();
1808                    } else {
1809                        mUpdateLock.release();
1810                    }
1811                }
1812                break;
1813            }
1814            case PERSIST_URI_GRANTS_MSG: {
1815                writeGrantedUriPermissions();
1816                break;
1817            }
1818            case REQUEST_ALL_PSS_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1821                }
1822                break;
1823            }
1824            case START_PROFILES_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    startProfilesLocked();
1827                }
1828                break;
1829            }
1830            case UPDATE_TIME: {
1831                synchronized (ActivityManagerService.this) {
1832                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1833                        ProcessRecord r = mLruProcesses.get(i);
1834                        if (r.thread != null) {
1835                            try {
1836                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1837                            } catch (RemoteException ex) {
1838                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1839                            }
1840                        }
1841                    }
1842                }
1843                break;
1844            }
1845            case SYSTEM_USER_START_MSG: {
1846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.startUser(msg.arg1);
1849                break;
1850            }
1851            case SYSTEM_USER_CURRENT_MSG: {
1852                mBatteryStatsService.noteEvent(
1853                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1854                        Integer.toString(msg.arg2), msg.arg2);
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.switchUser(msg.arg1);
1859                break;
1860            }
1861            case ENTER_ANIMATION_COMPLETE_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1864                    if (r != null && r.app != null && r.app.thread != null) {
1865                        try {
1866                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1867                        } catch (RemoteException e) {
1868                        }
1869                    }
1870                }
1871                break;
1872            }
1873            case FINISH_BOOTING_MSG: {
1874                if (msg.arg1 != 0) {
1875                    finishBooting();
1876                }
1877                if (msg.arg2 != 0) {
1878                    enableScreenAfterBoot();
1879                }
1880                break;
1881            }
1882            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1883                try {
1884                    Locale l = (Locale) msg.obj;
1885                    IBinder service = ServiceManager.getService("mount");
1886                    IMountService mountService = IMountService.Stub.asInterface(service);
1887                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1888                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1889                } catch (RemoteException e) {
1890                    Log.e(TAG, "Error storing locale for decryption UI", e);
1891                }
1892                break;
1893            }
1894            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1895                synchronized (ActivityManagerService.this) {
1896                    int i = mTaskStackListeners.beginBroadcast();
1897                    while (i > 0) {
1898                        i--;
1899                        try {
1900                            // Make a one-way callback to the listener
1901                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1902                        } catch (RemoteException e){
1903                            // Handled by the RemoteCallbackList
1904                        }
1905                    }
1906                    mTaskStackListeners.finishBroadcast();
1907                }
1908                break;
1909            }
1910            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1911                final int uid = msg.arg1;
1912                final byte[] firstPacket = (byte[]) msg.obj;
1913
1914                synchronized (mPidsSelfLocked) {
1915                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1916                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1917                        if (p.uid == uid) {
1918                            try {
1919                                p.thread.notifyCleartextNetwork(firstPacket);
1920                            } catch (RemoteException ignored) {
1921                            }
1922                        }
1923                    }
1924                }
1925                break;
1926            }
1927            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1928                final String procName;
1929                final int uid;
1930                final long memLimit;
1931                final String reportPackage;
1932                synchronized (ActivityManagerService.this) {
1933                    procName = mMemWatchDumpProcName;
1934                    uid = mMemWatchDumpUid;
1935                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1936                    if (val == null) {
1937                        val = mMemWatchProcesses.get(procName, 0);
1938                    }
1939                    if (val != null) {
1940                        memLimit = val.first;
1941                        reportPackage = val.second;
1942                    } else {
1943                        memLimit = 0;
1944                        reportPackage = null;
1945                    }
1946                }
1947                if (procName == null) {
1948                    return;
1949                }
1950
1951                if (DEBUG_PSS) Slog.d(TAG_PSS,
1952                        "Showing dump heap notification from " + procName + "/" + uid);
1953
1954                INotificationManager inm = NotificationManager.getService();
1955                if (inm == null) {
1956                    return;
1957                }
1958
1959                String text = mContext.getString(R.string.dump_heap_notification, procName);
1960
1961
1962                Intent deleteIntent = new Intent();
1963                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1964                Intent intent = new Intent();
1965                intent.setClassName("android", DumpHeapActivity.class.getName());
1966                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1967                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1968                if (reportPackage != null) {
1969                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1970                }
1971                int userId = UserHandle.getUserId(uid);
1972                Notification notification = new Notification.Builder(mContext)
1973                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1974                        .setWhen(0)
1975                        .setOngoing(true)
1976                        .setAutoCancel(true)
1977                        .setTicker(text)
1978                        .setColor(mContext.getColor(
1979                                com.android.internal.R.color.system_notification_accent_color))
1980                        .setContentTitle(text)
1981                        .setContentText(
1982                                mContext.getText(R.string.dump_heap_notification_detail))
1983                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1984                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1985                                new UserHandle(userId)))
1986                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1987                                deleteIntent, 0, UserHandle.OWNER))
1988                        .build();
1989
1990                try {
1991                    int[] outId = new int[1];
1992                    inm.enqueueNotificationWithTag("android", "android", null,
1993                            R.string.dump_heap_notification,
1994                            notification, outId, userId);
1995                } catch (RuntimeException e) {
1996                    Slog.w(ActivityManagerService.TAG,
1997                            "Error showing notification for dump heap", e);
1998                } catch (RemoteException e) {
1999                }
2000            } break;
2001            case DELETE_DUMPHEAP_MSG: {
2002                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2003                        DumpHeapActivity.JAVA_URI,
2004                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2005                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2006                        UserHandle.myUserId());
2007                synchronized (ActivityManagerService.this) {
2008                    mMemWatchDumpFile = null;
2009                    mMemWatchDumpProcName = null;
2010                    mMemWatchDumpPid = -1;
2011                    mMemWatchDumpUid = -1;
2012                }
2013            } break;
2014            case FOREGROUND_PROFILE_CHANGED_MSG: {
2015                dispatchForegroundProfileChanged(msg.arg1);
2016            } break;
2017            case REPORT_TIME_TRACKER_MSG: {
2018                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2019                tracker.deliverResult(mContext);
2020            } break;
2021            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2022                dispatchUserSwitchComplete(msg.arg1);
2023            } break;
2024            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2025                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2026                try {
2027                    connection.shutdown();
2028                } catch (RemoteException e) {
2029                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2030                }
2031                // Only a UiAutomation can set this flag and now that
2032                // it is finished we make sure it is reset to its default.
2033                mUserIsMonkey = false;
2034            } break;
2035            }
2036        }
2037    };
2038
2039    static final int COLLECT_PSS_BG_MSG = 1;
2040
2041    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2042        @Override
2043        public void handleMessage(Message msg) {
2044            switch (msg.what) {
2045            case COLLECT_PSS_BG_MSG: {
2046                long start = SystemClock.uptimeMillis();
2047                MemInfoReader memInfo = null;
2048                synchronized (ActivityManagerService.this) {
2049                    if (mFullPssPending) {
2050                        mFullPssPending = false;
2051                        memInfo = new MemInfoReader();
2052                    }
2053                }
2054                if (memInfo != null) {
2055                    updateCpuStatsNow();
2056                    long nativeTotalPss = 0;
2057                    synchronized (mProcessCpuTracker) {
2058                        final int N = mProcessCpuTracker.countStats();
2059                        for (int j=0; j<N; j++) {
2060                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2061                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2062                                // This is definitely an application process; skip it.
2063                                continue;
2064                            }
2065                            synchronized (mPidsSelfLocked) {
2066                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2067                                    // This is one of our own processes; skip it.
2068                                    continue;
2069                                }
2070                            }
2071                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2072                        }
2073                    }
2074                    memInfo.readMemInfo();
2075                    synchronized (ActivityManagerService.this) {
2076                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2077                                + (SystemClock.uptimeMillis()-start) + "ms");
2078                        final long cachedKb = memInfo.getCachedSizeKb();
2079                        final long freeKb = memInfo.getFreeSizeKb();
2080                        final long zramKb = memInfo.getZramTotalSizeKb();
2081                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2082                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2083                                kernelKb*1024, nativeTotalPss*1024);
2084                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2085                                nativeTotalPss);
2086                    }
2087                }
2088
2089                int num = 0;
2090                long[] tmp = new long[1];
2091                do {
2092                    ProcessRecord proc;
2093                    int procState;
2094                    int pid;
2095                    long lastPssTime;
2096                    synchronized (ActivityManagerService.this) {
2097                        if (mPendingPssProcesses.size() <= 0) {
2098                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2099                                    "Collected PSS of " + num + " processes in "
2100                                    + (SystemClock.uptimeMillis() - start) + "ms");
2101                            mPendingPssProcesses.clear();
2102                            return;
2103                        }
2104                        proc = mPendingPssProcesses.remove(0);
2105                        procState = proc.pssProcState;
2106                        lastPssTime = proc.lastPssTime;
2107                        if (proc.thread != null && procState == proc.setProcState
2108                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2109                                        < SystemClock.uptimeMillis()) {
2110                            pid = proc.pid;
2111                        } else {
2112                            proc = null;
2113                            pid = 0;
2114                        }
2115                    }
2116                    if (proc != null) {
2117                        long pss = Debug.getPss(pid, tmp, null);
2118                        synchronized (ActivityManagerService.this) {
2119                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2120                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2121                                num++;
2122                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2123                                        SystemClock.uptimeMillis());
2124                            }
2125                        }
2126                    }
2127                } while (true);
2128            }
2129            }
2130        }
2131    };
2132
2133    public void setSystemProcess() {
2134        try {
2135            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2136            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2137            ServiceManager.addService("meminfo", new MemBinder(this));
2138            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2139            ServiceManager.addService("dbinfo", new DbBinder(this));
2140            if (MONITOR_CPU_USAGE) {
2141                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2142            }
2143            ServiceManager.addService("permission", new PermissionController(this));
2144            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2145
2146            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2147                    "android", STOCK_PM_FLAGS);
2148            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2149
2150            synchronized (this) {
2151                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2152                app.persistent = true;
2153                app.pid = MY_PID;
2154                app.maxAdj = ProcessList.SYSTEM_ADJ;
2155                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2156                synchronized (mPidsSelfLocked) {
2157                    mPidsSelfLocked.put(app.pid, app);
2158                }
2159                updateLruProcessLocked(app, false, null);
2160                updateOomAdjLocked();
2161            }
2162        } catch (PackageManager.NameNotFoundException e) {
2163            throw new RuntimeException(
2164                    "Unable to find android system package", e);
2165        }
2166    }
2167
2168    public void setWindowManager(WindowManagerService wm) {
2169        mWindowManager = wm;
2170        mStackSupervisor.setWindowManager(wm);
2171    }
2172
2173    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2174        mUsageStatsService = usageStatsManager;
2175    }
2176
2177    public void startObservingNativeCrashes() {
2178        final NativeCrashListener ncl = new NativeCrashListener(this);
2179        ncl.start();
2180    }
2181
2182    public IAppOpsService getAppOpsService() {
2183        return mAppOpsService;
2184    }
2185
2186    static class MemBinder extends Binder {
2187        ActivityManagerService mActivityManagerService;
2188        MemBinder(ActivityManagerService activityManagerService) {
2189            mActivityManagerService = activityManagerService;
2190        }
2191
2192        @Override
2193        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2194            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2195                    != PackageManager.PERMISSION_GRANTED) {
2196                pw.println("Permission Denial: can't dump meminfo from from pid="
2197                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2198                        + " without permission " + android.Manifest.permission.DUMP);
2199                return;
2200            }
2201
2202            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2203        }
2204    }
2205
2206    static class GraphicsBinder extends Binder {
2207        ActivityManagerService mActivityManagerService;
2208        GraphicsBinder(ActivityManagerService activityManagerService) {
2209            mActivityManagerService = activityManagerService;
2210        }
2211
2212        @Override
2213        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2214            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2215                    != PackageManager.PERMISSION_GRANTED) {
2216                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2217                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2218                        + " without permission " + android.Manifest.permission.DUMP);
2219                return;
2220            }
2221
2222            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2223        }
2224    }
2225
2226    static class DbBinder extends Binder {
2227        ActivityManagerService mActivityManagerService;
2228        DbBinder(ActivityManagerService activityManagerService) {
2229            mActivityManagerService = activityManagerService;
2230        }
2231
2232        @Override
2233        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2234            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2235                    != PackageManager.PERMISSION_GRANTED) {
2236                pw.println("Permission Denial: can't dump dbinfo from from pid="
2237                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2238                        + " without permission " + android.Manifest.permission.DUMP);
2239                return;
2240            }
2241
2242            mActivityManagerService.dumpDbInfo(fd, pw, args);
2243        }
2244    }
2245
2246    static class CpuBinder extends Binder {
2247        ActivityManagerService mActivityManagerService;
2248        CpuBinder(ActivityManagerService activityManagerService) {
2249            mActivityManagerService = activityManagerService;
2250        }
2251
2252        @Override
2253        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2254            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2255                    != PackageManager.PERMISSION_GRANTED) {
2256                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2257                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2258                        + " without permission " + android.Manifest.permission.DUMP);
2259                return;
2260            }
2261
2262            synchronized (mActivityManagerService.mProcessCpuTracker) {
2263                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2264                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2265                        SystemClock.uptimeMillis()));
2266            }
2267        }
2268    }
2269
2270    public static final class Lifecycle extends SystemService {
2271        private final ActivityManagerService mService;
2272
2273        public Lifecycle(Context context) {
2274            super(context);
2275            mService = new ActivityManagerService(context);
2276        }
2277
2278        @Override
2279        public void onStart() {
2280            mService.start();
2281        }
2282
2283        public ActivityManagerService getService() {
2284            return mService;
2285        }
2286    }
2287
2288    // Note: This method is invoked on the main thread but may need to attach various
2289    // handlers to other threads.  So take care to be explicit about the looper.
2290    public ActivityManagerService(Context systemContext) {
2291        mContext = systemContext;
2292        mFactoryTest = FactoryTest.getMode();
2293        mSystemThread = ActivityThread.currentActivityThread();
2294
2295        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2296
2297        mHandlerThread = new ServiceThread(TAG,
2298                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2299        mHandlerThread.start();
2300        mHandler = new MainHandler(mHandlerThread.getLooper());
2301        mUiHandler = new UiHandler();
2302
2303        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2304                "foreground", BROADCAST_FG_TIMEOUT, false);
2305        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2306                "background", BROADCAST_BG_TIMEOUT, true);
2307        mBroadcastQueues[0] = mFgBroadcastQueue;
2308        mBroadcastQueues[1] = mBgBroadcastQueue;
2309
2310        mServices = new ActiveServices(this);
2311        mProviderMap = new ProviderMap(this);
2312
2313        // TODO: Move creation of battery stats service outside of activity manager service.
2314        File dataDir = Environment.getDataDirectory();
2315        File systemDir = new File(dataDir, "system");
2316        systemDir.mkdirs();
2317        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2318        mBatteryStatsService.getActiveStatistics().readLocked();
2319        mBatteryStatsService.scheduleWriteToDisk();
2320        mOnBattery = DEBUG_POWER ? true
2321                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2322        mBatteryStatsService.getActiveStatistics().setCallback(this);
2323
2324        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2325
2326        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2327
2328        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2329
2330        // User 0 is the first and only user that runs at boot.
2331        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2332        mUserLru.add(UserHandle.USER_OWNER);
2333        updateStartedUserArrayLocked();
2334
2335        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2336            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2337
2338        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2339
2340        mConfiguration.setToDefaults();
2341        mConfiguration.setLocale(Locale.getDefault());
2342
2343        mConfigurationSeq = mConfiguration.seq = 1;
2344        mProcessCpuTracker.init();
2345
2346        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2347        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2348        mRecentTasks = new RecentTasks(this);
2349        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2350        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2351
2352        mProcessCpuThread = new Thread("CpuTracker") {
2353            @Override
2354            public void run() {
2355                while (true) {
2356                    try {
2357                        try {
2358                            synchronized(this) {
2359                                final long now = SystemClock.uptimeMillis();
2360                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2361                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2362                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2363                                //        + ", write delay=" + nextWriteDelay);
2364                                if (nextWriteDelay < nextCpuDelay) {
2365                                    nextCpuDelay = nextWriteDelay;
2366                                }
2367                                if (nextCpuDelay > 0) {
2368                                    mProcessCpuMutexFree.set(true);
2369                                    this.wait(nextCpuDelay);
2370                                }
2371                            }
2372                        } catch (InterruptedException e) {
2373                        }
2374                        updateCpuStatsNow();
2375                    } catch (Exception e) {
2376                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2377                    }
2378                }
2379            }
2380        };
2381
2382        Watchdog.getInstance().addMonitor(this);
2383        Watchdog.getInstance().addThread(mHandler);
2384    }
2385
2386    public void setSystemServiceManager(SystemServiceManager mgr) {
2387        mSystemServiceManager = mgr;
2388    }
2389
2390    public void setInstaller(Installer installer) {
2391        mInstaller = installer;
2392    }
2393
2394    private void start() {
2395        Process.removeAllProcessGroups();
2396        mProcessCpuThread.start();
2397
2398        mBatteryStatsService.publish(mContext);
2399        mAppOpsService.publish(mContext);
2400        Slog.d("AppOps", "AppOpsService published");
2401        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2402    }
2403
2404    public void initPowerManagement() {
2405        mStackSupervisor.initPowerManagement();
2406        mBatteryStatsService.initPowerManagement();
2407        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2408        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2409        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2410        mVoiceWakeLock.setReferenceCounted(false);
2411    }
2412
2413    @Override
2414    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2415            throws RemoteException {
2416        if (code == SYSPROPS_TRANSACTION) {
2417            // We need to tell all apps about the system property change.
2418            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2419            synchronized(this) {
2420                final int NP = mProcessNames.getMap().size();
2421                for (int ip=0; ip<NP; ip++) {
2422                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2423                    final int NA = apps.size();
2424                    for (int ia=0; ia<NA; ia++) {
2425                        ProcessRecord app = apps.valueAt(ia);
2426                        if (app.thread != null) {
2427                            procs.add(app.thread.asBinder());
2428                        }
2429                    }
2430                }
2431            }
2432
2433            int N = procs.size();
2434            for (int i=0; i<N; i++) {
2435                Parcel data2 = Parcel.obtain();
2436                try {
2437                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2438                } catch (RemoteException e) {
2439                }
2440                data2.recycle();
2441            }
2442        }
2443        try {
2444            return super.onTransact(code, data, reply, flags);
2445        } catch (RuntimeException e) {
2446            // The activity manager only throws security exceptions, so let's
2447            // log all others.
2448            if (!(e instanceof SecurityException)) {
2449                Slog.wtf(TAG, "Activity Manager Crash", e);
2450            }
2451            throw e;
2452        }
2453    }
2454
2455    void updateCpuStats() {
2456        final long now = SystemClock.uptimeMillis();
2457        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2458            return;
2459        }
2460        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2461            synchronized (mProcessCpuThread) {
2462                mProcessCpuThread.notify();
2463            }
2464        }
2465    }
2466
2467    void updateCpuStatsNow() {
2468        synchronized (mProcessCpuTracker) {
2469            mProcessCpuMutexFree.set(false);
2470            final long now = SystemClock.uptimeMillis();
2471            boolean haveNewCpuStats = false;
2472
2473            if (MONITOR_CPU_USAGE &&
2474                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2475                mLastCpuTime.set(now);
2476                mProcessCpuTracker.update();
2477                if (mProcessCpuTracker.hasGoodLastStats()) {
2478                    haveNewCpuStats = true;
2479                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2480                    //Slog.i(TAG, "Total CPU usage: "
2481                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2482
2483                    // Slog the cpu usage if the property is set.
2484                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2485                        int user = mProcessCpuTracker.getLastUserTime();
2486                        int system = mProcessCpuTracker.getLastSystemTime();
2487                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2488                        int irq = mProcessCpuTracker.getLastIrqTime();
2489                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2490                        int idle = mProcessCpuTracker.getLastIdleTime();
2491
2492                        int total = user + system + iowait + irq + softIrq + idle;
2493                        if (total == 0) total = 1;
2494
2495                        EventLog.writeEvent(EventLogTags.CPU,
2496                                ((user+system+iowait+irq+softIrq) * 100) / total,
2497                                (user * 100) / total,
2498                                (system * 100) / total,
2499                                (iowait * 100) / total,
2500                                (irq * 100) / total,
2501                                (softIrq * 100) / total);
2502                    }
2503                }
2504            }
2505
2506            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2507            synchronized(bstats) {
2508                synchronized(mPidsSelfLocked) {
2509                    if (haveNewCpuStats) {
2510                        if (bstats.startAddingCpuLocked()) {
2511                            int totalUTime = 0;
2512                            int totalSTime = 0;
2513                            final int N = mProcessCpuTracker.countStats();
2514                            for (int i=0; i<N; i++) {
2515                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2516                                if (!st.working) {
2517                                    continue;
2518                                }
2519                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2520                                totalUTime += st.rel_utime;
2521                                totalSTime += st.rel_stime;
2522                                if (pr != null) {
2523                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2524                                    if (ps == null || !ps.isActive()) {
2525                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2526                                                pr.info.uid, pr.processName);
2527                                    }
2528                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2529                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2530                                } else {
2531                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2532                                    if (ps == null || !ps.isActive()) {
2533                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2534                                                bstats.mapUid(st.uid), st.name);
2535                                    }
2536                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2537                                }
2538                            }
2539                            final int userTime = mProcessCpuTracker.getLastUserTime();
2540                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2541                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2542                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2543                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2544                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2545                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2546                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2547                        }
2548                    }
2549                }
2550
2551                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2552                    mLastWriteTime = now;
2553                    mBatteryStatsService.scheduleWriteToDisk();
2554                }
2555            }
2556        }
2557    }
2558
2559    @Override
2560    public void batteryNeedsCpuUpdate() {
2561        updateCpuStatsNow();
2562    }
2563
2564    @Override
2565    public void batteryPowerChanged(boolean onBattery) {
2566        // When plugging in, update the CPU stats first before changing
2567        // the plug state.
2568        updateCpuStatsNow();
2569        synchronized (this) {
2570            synchronized(mPidsSelfLocked) {
2571                mOnBattery = DEBUG_POWER ? true : onBattery;
2572            }
2573        }
2574    }
2575
2576    @Override
2577    public void batterySendBroadcast(Intent intent) {
2578        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2579                AppOpsManager.OP_NONE, null, false, false,
2580                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2581    }
2582
2583    /**
2584     * Initialize the application bind args. These are passed to each
2585     * process when the bindApplication() IPC is sent to the process. They're
2586     * lazily setup to make sure the services are running when they're asked for.
2587     */
2588    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2589        if (mAppBindArgs == null) {
2590            mAppBindArgs = new HashMap<>();
2591
2592            // Isolated processes won't get this optimization, so that we don't
2593            // violate the rules about which services they have access to.
2594            if (!isolated) {
2595                // Setup the application init args
2596                mAppBindArgs.put("package", ServiceManager.getService("package"));
2597                mAppBindArgs.put("window", ServiceManager.getService("window"));
2598                mAppBindArgs.put(Context.ALARM_SERVICE,
2599                        ServiceManager.getService(Context.ALARM_SERVICE));
2600            }
2601        }
2602        return mAppBindArgs;
2603    }
2604
2605    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2606        if (r != null && mFocusedActivity != r) {
2607            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2608            ActivityRecord last = mFocusedActivity;
2609            mFocusedActivity = r;
2610            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2611                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2612                if (mCurAppTimeTracker != r.appTimeTracker) {
2613                    // We are switching app tracking.  Complete the current one.
2614                    if (mCurAppTimeTracker != null) {
2615                        mCurAppTimeTracker.stop();
2616                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2617                                mCurAppTimeTracker).sendToTarget();
2618                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2619                        mCurAppTimeTracker = null;
2620                    }
2621                    if (r.appTimeTracker != null) {
2622                        mCurAppTimeTracker = r.appTimeTracker;
2623                        startTimeTrackingFocusedActivityLocked();
2624                    }
2625                } else {
2626                    startTimeTrackingFocusedActivityLocked();
2627                }
2628            } else {
2629                r.appTimeTracker = null;
2630            }
2631            if (r.task != null && r.task.voiceInteractor != null) {
2632                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2633            } else {
2634                finishRunningVoiceLocked();
2635                if (last != null && last.task.voiceSession != null) {
2636                    // We had been in a voice interaction session, but now focused has
2637                    // move to something different.  Just finish the session, we can't
2638                    // return to it and retain the proper state and synchronization with
2639                    // the voice interaction service.
2640                    finishVoiceTask(last.task.voiceSession);
2641                }
2642            }
2643            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2644                mWindowManager.setFocusedApp(r.appToken, true);
2645            }
2646            applyUpdateLockStateLocked(r);
2647            if (mFocusedActivity.userId != mLastFocusedUserId) {
2648                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2649                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2650                        mFocusedActivity.userId, 0));
2651                mLastFocusedUserId = mFocusedActivity.userId;
2652            }
2653        }
2654        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2655                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2656                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2657    }
2658
2659    final void clearFocusedActivity(ActivityRecord r) {
2660        if (mFocusedActivity == r) {
2661            ActivityStack stack = mStackSupervisor.getFocusedStack();
2662            if (stack != null) {
2663                ActivityRecord top = stack.topActivity();
2664                if (top != null && top.userId != mLastFocusedUserId) {
2665                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2666                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2667                                    top.userId, 0));
2668                    mLastFocusedUserId = top.userId;
2669                }
2670            }
2671            mFocusedActivity = null;
2672            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2673        }
2674    }
2675
2676    @Override
2677    public void setFocusedStack(int stackId) {
2678        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2679        synchronized (ActivityManagerService.this) {
2680            ActivityStack stack = mStackSupervisor.getStack(stackId);
2681            if (stack != null) {
2682                ActivityRecord r = stack.topRunningActivityLocked(null);
2683                if (r != null) {
2684                    setFocusedActivityLocked(r, "setFocusedStack");
2685                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2686                }
2687            }
2688        }
2689    }
2690
2691    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2692    @Override
2693    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2694        synchronized (ActivityManagerService.this) {
2695            if (listener != null) {
2696                mTaskStackListeners.register(listener);
2697            }
2698        }
2699    }
2700
2701    @Override
2702    public void notifyActivityDrawn(IBinder token) {
2703        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2704        synchronized (this) {
2705            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2706            if (r != null) {
2707                r.task.stack.notifyActivityDrawnLocked(r);
2708            }
2709        }
2710    }
2711
2712    final void applyUpdateLockStateLocked(ActivityRecord r) {
2713        // Modifications to the UpdateLock state are done on our handler, outside
2714        // the activity manager's locks.  The new state is determined based on the
2715        // state *now* of the relevant activity record.  The object is passed to
2716        // the handler solely for logging detail, not to be consulted/modified.
2717        final boolean nextState = r != null && r.immersive;
2718        mHandler.sendMessage(
2719                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2720    }
2721
2722    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2723        Message msg = Message.obtain();
2724        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2725        msg.obj = r.task.askedCompatMode ? null : r;
2726        mUiHandler.sendMessage(msg);
2727    }
2728
2729    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2730            String what, Object obj, ProcessRecord srcApp) {
2731        app.lastActivityTime = now;
2732
2733        if (app.activities.size() > 0) {
2734            // Don't want to touch dependent processes that are hosting activities.
2735            return index;
2736        }
2737
2738        int lrui = mLruProcesses.lastIndexOf(app);
2739        if (lrui < 0) {
2740            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2741                    + what + " " + obj + " from " + srcApp);
2742            return index;
2743        }
2744
2745        if (lrui >= index) {
2746            // Don't want to cause this to move dependent processes *back* in the
2747            // list as if they were less frequently used.
2748            return index;
2749        }
2750
2751        if (lrui >= mLruProcessActivityStart) {
2752            // Don't want to touch dependent processes that are hosting activities.
2753            return index;
2754        }
2755
2756        mLruProcesses.remove(lrui);
2757        if (index > 0) {
2758            index--;
2759        }
2760        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2761                + " in LRU list: " + app);
2762        mLruProcesses.add(index, app);
2763        return index;
2764    }
2765
2766    private static void killProcessGroup(int uid, int pid) {
2767        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2768        Process.killProcessGroup(uid, pid);
2769        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2770    }
2771
2772    final void removeLruProcessLocked(ProcessRecord app) {
2773        int lrui = mLruProcesses.lastIndexOf(app);
2774        if (lrui >= 0) {
2775            if (!app.killed) {
2776                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2777                Process.killProcessQuiet(app.pid);
2778                killProcessGroup(app.info.uid, app.pid);
2779            }
2780            if (lrui <= mLruProcessActivityStart) {
2781                mLruProcessActivityStart--;
2782            }
2783            if (lrui <= mLruProcessServiceStart) {
2784                mLruProcessServiceStart--;
2785            }
2786            mLruProcesses.remove(lrui);
2787        }
2788    }
2789
2790    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2791            ProcessRecord client) {
2792        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2793                || app.treatLikeActivity;
2794        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2795        if (!activityChange && hasActivity) {
2796            // The process has activities, so we are only allowing activity-based adjustments
2797            // to move it.  It should be kept in the front of the list with other
2798            // processes that have activities, and we don't want those to change their
2799            // order except due to activity operations.
2800            return;
2801        }
2802
2803        mLruSeq++;
2804        final long now = SystemClock.uptimeMillis();
2805        app.lastActivityTime = now;
2806
2807        // First a quick reject: if the app is already at the position we will
2808        // put it, then there is nothing to do.
2809        if (hasActivity) {
2810            final int N = mLruProcesses.size();
2811            if (N > 0 && mLruProcesses.get(N-1) == app) {
2812                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2813                return;
2814            }
2815        } else {
2816            if (mLruProcessServiceStart > 0
2817                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2818                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2819                return;
2820            }
2821        }
2822
2823        int lrui = mLruProcesses.lastIndexOf(app);
2824
2825        if (app.persistent && lrui >= 0) {
2826            // We don't care about the position of persistent processes, as long as
2827            // they are in the list.
2828            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2829            return;
2830        }
2831
2832        /* In progress: compute new position first, so we can avoid doing work
2833           if the process is not actually going to move.  Not yet working.
2834        int addIndex;
2835        int nextIndex;
2836        boolean inActivity = false, inService = false;
2837        if (hasActivity) {
2838            // Process has activities, put it at the very tipsy-top.
2839            addIndex = mLruProcesses.size();
2840            nextIndex = mLruProcessServiceStart;
2841            inActivity = true;
2842        } else if (hasService) {
2843            // Process has services, put it at the top of the service list.
2844            addIndex = mLruProcessActivityStart;
2845            nextIndex = mLruProcessServiceStart;
2846            inActivity = true;
2847            inService = true;
2848        } else  {
2849            // Process not otherwise of interest, it goes to the top of the non-service area.
2850            addIndex = mLruProcessServiceStart;
2851            if (client != null) {
2852                int clientIndex = mLruProcesses.lastIndexOf(client);
2853                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2854                        + app);
2855                if (clientIndex >= 0 && addIndex > clientIndex) {
2856                    addIndex = clientIndex;
2857                }
2858            }
2859            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2860        }
2861
2862        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2863                + mLruProcessActivityStart + "): " + app);
2864        */
2865
2866        if (lrui >= 0) {
2867            if (lrui < mLruProcessActivityStart) {
2868                mLruProcessActivityStart--;
2869            }
2870            if (lrui < mLruProcessServiceStart) {
2871                mLruProcessServiceStart--;
2872            }
2873            /*
2874            if (addIndex > lrui) {
2875                addIndex--;
2876            }
2877            if (nextIndex > lrui) {
2878                nextIndex--;
2879            }
2880            */
2881            mLruProcesses.remove(lrui);
2882        }
2883
2884        /*
2885        mLruProcesses.add(addIndex, app);
2886        if (inActivity) {
2887            mLruProcessActivityStart++;
2888        }
2889        if (inService) {
2890            mLruProcessActivityStart++;
2891        }
2892        */
2893
2894        int nextIndex;
2895        if (hasActivity) {
2896            final int N = mLruProcesses.size();
2897            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2898                // Process doesn't have activities, but has clients with
2899                // activities...  move it up, but one below the top (the top
2900                // should always have a real activity).
2901                if (DEBUG_LRU) Slog.d(TAG_LRU,
2902                        "Adding to second-top of LRU activity list: " + app);
2903                mLruProcesses.add(N - 1, app);
2904                // To keep it from spamming the LRU list (by making a bunch of clients),
2905                // we will push down any other entries owned by the app.
2906                final int uid = app.info.uid;
2907                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2908                    ProcessRecord subProc = mLruProcesses.get(i);
2909                    if (subProc.info.uid == uid) {
2910                        // We want to push this one down the list.  If the process after
2911                        // it is for the same uid, however, don't do so, because we don't
2912                        // want them internally to be re-ordered.
2913                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2914                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2915                                    "Pushing uid " + uid + " swapping at " + i + ": "
2916                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2917                            ProcessRecord tmp = mLruProcesses.get(i);
2918                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2919                            mLruProcesses.set(i - 1, tmp);
2920                            i--;
2921                        }
2922                    } else {
2923                        // A gap, we can stop here.
2924                        break;
2925                    }
2926                }
2927            } else {
2928                // Process has activities, put it at the very tipsy-top.
2929                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2930                mLruProcesses.add(app);
2931            }
2932            nextIndex = mLruProcessServiceStart;
2933        } else if (hasService) {
2934            // Process has services, put it at the top of the service list.
2935            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2936            mLruProcesses.add(mLruProcessActivityStart, app);
2937            nextIndex = mLruProcessServiceStart;
2938            mLruProcessActivityStart++;
2939        } else  {
2940            // Process not otherwise of interest, it goes to the top of the non-service area.
2941            int index = mLruProcessServiceStart;
2942            if (client != null) {
2943                // If there is a client, don't allow the process to be moved up higher
2944                // in the list than that client.
2945                int clientIndex = mLruProcesses.lastIndexOf(client);
2946                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2947                        + " when updating " + app);
2948                if (clientIndex <= lrui) {
2949                    // Don't allow the client index restriction to push it down farther in the
2950                    // list than it already is.
2951                    clientIndex = lrui;
2952                }
2953                if (clientIndex >= 0 && index > clientIndex) {
2954                    index = clientIndex;
2955                }
2956            }
2957            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2958            mLruProcesses.add(index, app);
2959            nextIndex = index-1;
2960            mLruProcessActivityStart++;
2961            mLruProcessServiceStart++;
2962        }
2963
2964        // If the app is currently using a content provider or service,
2965        // bump those processes as well.
2966        for (int j=app.connections.size()-1; j>=0; j--) {
2967            ConnectionRecord cr = app.connections.valueAt(j);
2968            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2969                    && cr.binding.service.app != null
2970                    && cr.binding.service.app.lruSeq != mLruSeq
2971                    && !cr.binding.service.app.persistent) {
2972                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2973                        "service connection", cr, app);
2974            }
2975        }
2976        for (int j=app.conProviders.size()-1; j>=0; j--) {
2977            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2978            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2979                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2980                        "provider reference", cpr, app);
2981            }
2982        }
2983    }
2984
2985    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2986        if (uid == Process.SYSTEM_UID) {
2987            // The system gets to run in any process.  If there are multiple
2988            // processes with the same uid, just pick the first (this
2989            // should never happen).
2990            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2991            if (procs == null) return null;
2992            final int procCount = procs.size();
2993            for (int i = 0; i < procCount; i++) {
2994                final int procUid = procs.keyAt(i);
2995                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2996                    // Don't use an app process or different user process for system component.
2997                    continue;
2998                }
2999                return procs.valueAt(i);
3000            }
3001        }
3002        ProcessRecord proc = mProcessNames.get(processName, uid);
3003        if (false && proc != null && !keepIfLarge
3004                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3005                && proc.lastCachedPss >= 4000) {
3006            // Turn this condition on to cause killing to happen regularly, for testing.
3007            if (proc.baseProcessTracker != null) {
3008                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3009            }
3010            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3011        } else if (proc != null && !keepIfLarge
3012                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3013                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3014            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3015            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3016                if (proc.baseProcessTracker != null) {
3017                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3018                }
3019                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3020            }
3021        }
3022        return proc;
3023    }
3024
3025    void ensurePackageDexOpt(String packageName) {
3026        IPackageManager pm = AppGlobals.getPackageManager();
3027        try {
3028            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3029                mDidDexOpt = true;
3030            }
3031        } catch (RemoteException e) {
3032        }
3033    }
3034
3035    boolean isNextTransitionForward() {
3036        int transit = mWindowManager.getPendingAppTransition();
3037        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3038                || transit == AppTransition.TRANSIT_TASK_OPEN
3039                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3040    }
3041
3042    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3043            String processName, String abiOverride, int uid, Runnable crashHandler) {
3044        synchronized(this) {
3045            ApplicationInfo info = new ApplicationInfo();
3046            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3047            // For isolated processes, the former contains the parent's uid and the latter the
3048            // actual uid of the isolated process.
3049            // In the special case introduced by this method (which is, starting an isolated
3050            // process directly from the SystemServer without an actual parent app process) the
3051            // closest thing to a parent's uid is SYSTEM_UID.
3052            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3053            // the |isolated| logic in the ProcessRecord constructor.
3054            info.uid = Process.SYSTEM_UID;
3055            info.processName = processName;
3056            info.className = entryPoint;
3057            info.packageName = "android";
3058            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3059                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3060                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3061                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3062                    crashHandler);
3063            return proc != null ? proc.pid : 0;
3064        }
3065    }
3066
3067    final ProcessRecord startProcessLocked(String processName,
3068            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3069            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3070            boolean isolated, boolean keepIfLarge) {
3071        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3072                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3073                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3074                null /* crashHandler */);
3075    }
3076
3077    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3078            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3079            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3080            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3081        long startTime = SystemClock.elapsedRealtime();
3082        ProcessRecord app;
3083        if (!isolated) {
3084            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3085            checkTime(startTime, "startProcess: after getProcessRecord");
3086
3087            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3088                // If we are in the background, then check to see if this process
3089                // is bad.  If so, we will just silently fail.
3090                if (mBadProcesses.get(info.processName, info.uid) != null) {
3091                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3092                            + "/" + info.processName);
3093                    return null;
3094                }
3095            } else {
3096                // When the user is explicitly starting a process, then clear its
3097                // crash count so that we won't make it bad until they see at
3098                // least one crash dialog again, and make the process good again
3099                // if it had been bad.
3100                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3101                        + "/" + info.processName);
3102                mProcessCrashTimes.remove(info.processName, info.uid);
3103                if (mBadProcesses.get(info.processName, info.uid) != null) {
3104                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3105                            UserHandle.getUserId(info.uid), info.uid,
3106                            info.processName);
3107                    mBadProcesses.remove(info.processName, info.uid);
3108                    if (app != null) {
3109                        app.bad = false;
3110                    }
3111                }
3112            }
3113        } else {
3114            // If this is an isolated process, it can't re-use an existing process.
3115            app = null;
3116        }
3117
3118        // We don't have to do anything more if:
3119        // (1) There is an existing application record; and
3120        // (2) The caller doesn't think it is dead, OR there is no thread
3121        //     object attached to it so we know it couldn't have crashed; and
3122        // (3) There is a pid assigned to it, so it is either starting or
3123        //     already running.
3124        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3125                + " app=" + app + " knownToBeDead=" + knownToBeDead
3126                + " thread=" + (app != null ? app.thread : null)
3127                + " pid=" + (app != null ? app.pid : -1));
3128        if (app != null && app.pid > 0) {
3129            if (!knownToBeDead || app.thread == null) {
3130                // We already have the app running, or are waiting for it to
3131                // come up (we have a pid but not yet its thread), so keep it.
3132                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3133                // If this is a new package in the process, add the package to the list
3134                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3135                checkTime(startTime, "startProcess: done, added package to proc");
3136                return app;
3137            }
3138
3139            // An application record is attached to a previous process,
3140            // clean it up now.
3141            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3142            checkTime(startTime, "startProcess: bad proc running, killing");
3143            killProcessGroup(app.info.uid, app.pid);
3144            handleAppDiedLocked(app, true, true);
3145            checkTime(startTime, "startProcess: done killing old proc");
3146        }
3147
3148        String hostingNameStr = hostingName != null
3149                ? hostingName.flattenToShortString() : null;
3150
3151        if (app == null) {
3152            checkTime(startTime, "startProcess: creating new process record");
3153            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3154            if (app == null) {
3155                Slog.w(TAG, "Failed making new process record for "
3156                        + processName + "/" + info.uid + " isolated=" + isolated);
3157                return null;
3158            }
3159            app.crashHandler = crashHandler;
3160            checkTime(startTime, "startProcess: done creating new process record");
3161        } else {
3162            // If this is a new package in the process, add the package to the list
3163            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3164            checkTime(startTime, "startProcess: added package to existing proc");
3165        }
3166
3167        // If the system is not ready yet, then hold off on starting this
3168        // process until it is.
3169        if (!mProcessesReady
3170                && !isAllowedWhileBooting(info)
3171                && !allowWhileBooting) {
3172            if (!mProcessesOnHold.contains(app)) {
3173                mProcessesOnHold.add(app);
3174            }
3175            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3176                    "System not ready, putting on hold: " + app);
3177            checkTime(startTime, "startProcess: returning with proc on hold");
3178            return app;
3179        }
3180
3181        checkTime(startTime, "startProcess: stepping in to startProcess");
3182        startProcessLocked(
3183                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3184        checkTime(startTime, "startProcess: done starting proc!");
3185        return (app.pid != 0) ? app : null;
3186    }
3187
3188    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3189        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3190    }
3191
3192    private final void startProcessLocked(ProcessRecord app,
3193            String hostingType, String hostingNameStr) {
3194        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3195                null /* entryPoint */, null /* entryPointArgs */);
3196    }
3197
3198    private final void startProcessLocked(ProcessRecord app, String hostingType,
3199            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3200        long startTime = SystemClock.elapsedRealtime();
3201        if (app.pid > 0 && app.pid != MY_PID) {
3202            checkTime(startTime, "startProcess: removing from pids map");
3203            synchronized (mPidsSelfLocked) {
3204                mPidsSelfLocked.remove(app.pid);
3205                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3206            }
3207            checkTime(startTime, "startProcess: done removing from pids map");
3208            app.setPid(0);
3209        }
3210
3211        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3212                "startProcessLocked removing on hold: " + app);
3213        mProcessesOnHold.remove(app);
3214
3215        checkTime(startTime, "startProcess: starting to update cpu stats");
3216        updateCpuStats();
3217        checkTime(startTime, "startProcess: done updating cpu stats");
3218
3219        try {
3220            try {
3221                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3222                    // This is caught below as if we had failed to fork zygote
3223                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3224                }
3225            } catch (RemoteException e) {
3226                throw e.rethrowAsRuntimeException();
3227            }
3228
3229            int uid = app.uid;
3230            int[] gids = null;
3231            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3232            if (!app.isolated) {
3233                int[] permGids = null;
3234                try {
3235                    checkTime(startTime, "startProcess: getting gids from package manager");
3236                    final IPackageManager pm = AppGlobals.getPackageManager();
3237                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3238                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3239                            MountServiceInternal.class);
3240                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3241                            app.info.packageName);
3242                } catch (RemoteException e) {
3243                    throw e.rethrowAsRuntimeException();
3244                }
3245
3246                /*
3247                 * Add shared application and profile GIDs so applications can share some
3248                 * resources like shared libraries and access user-wide resources
3249                 */
3250                if (ArrayUtils.isEmpty(permGids)) {
3251                    gids = new int[2];
3252                } else {
3253                    gids = new int[permGids.length + 2];
3254                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3255                }
3256                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3257                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3258            }
3259            checkTime(startTime, "startProcess: building args");
3260            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3261                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3262                        && mTopComponent != null
3263                        && app.processName.equals(mTopComponent.getPackageName())) {
3264                    uid = 0;
3265                }
3266                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3267                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3268                    uid = 0;
3269                }
3270            }
3271            int debugFlags = 0;
3272            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3273                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3274                // Also turn on CheckJNI for debuggable apps. It's quite
3275                // awkward to turn on otherwise.
3276                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3277            }
3278            // Run the app in safe mode if its manifest requests so or the
3279            // system is booted in safe mode.
3280            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3281                mSafeMode == true) {
3282                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3283            }
3284            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3285                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3286            }
3287            String jitDebugProperty = SystemProperties.get("debug.usejit");
3288            if ("true".equals(jitDebugProperty)) {
3289                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3290            } else if (!"false".equals(jitDebugProperty)) {
3291                // If we didn't force disable by setting false, defer to the dalvik vm options.
3292                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3293                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3294                }
3295            }
3296            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3297            if ("true".equals(genDebugInfoProperty)) {
3298                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3299            }
3300            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3301                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3302            }
3303            if ("1".equals(SystemProperties.get("debug.assert"))) {
3304                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3305            }
3306
3307            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3308            if (requiredAbi == null) {
3309                requiredAbi = Build.SUPPORTED_ABIS[0];
3310            }
3311
3312            String instructionSet = null;
3313            if (app.info.primaryCpuAbi != null) {
3314                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3315            }
3316
3317            app.gids = gids;
3318            app.requiredAbi = requiredAbi;
3319            app.instructionSet = instructionSet;
3320
3321            // Start the process.  It will either succeed and return a result containing
3322            // the PID of the new process, or else throw a RuntimeException.
3323            boolean isActivityProcess = (entryPoint == null);
3324            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3325            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3326                    app.processName);
3327            checkTime(startTime, "startProcess: asking zygote to start proc");
3328            Process.ProcessStartResult startResult = Process.start(entryPoint,
3329                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3330                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3331                    app.info.dataDir, entryPointArgs);
3332            checkTime(startTime, "startProcess: returned from zygote!");
3333            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3334
3335            if (app.isolated) {
3336                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3337            }
3338            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3339            checkTime(startTime, "startProcess: done updating battery stats");
3340
3341            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3342                    UserHandle.getUserId(uid), startResult.pid, uid,
3343                    app.processName, hostingType,
3344                    hostingNameStr != null ? hostingNameStr : "");
3345
3346            if (app.persistent) {
3347                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3348            }
3349
3350            checkTime(startTime, "startProcess: building log message");
3351            StringBuilder buf = mStringBuilder;
3352            buf.setLength(0);
3353            buf.append("Start proc ");
3354            buf.append(startResult.pid);
3355            buf.append(':');
3356            buf.append(app.processName);
3357            buf.append('/');
3358            UserHandle.formatUid(buf, uid);
3359            if (!isActivityProcess) {
3360                buf.append(" [");
3361                buf.append(entryPoint);
3362                buf.append("]");
3363            }
3364            buf.append(" for ");
3365            buf.append(hostingType);
3366            if (hostingNameStr != null) {
3367                buf.append(" ");
3368                buf.append(hostingNameStr);
3369            }
3370            Slog.i(TAG, buf.toString());
3371            app.setPid(startResult.pid);
3372            app.usingWrapper = startResult.usingWrapper;
3373            app.removed = false;
3374            app.killed = false;
3375            app.killedByAm = false;
3376            checkTime(startTime, "startProcess: starting to update pids map");
3377            synchronized (mPidsSelfLocked) {
3378                this.mPidsSelfLocked.put(startResult.pid, app);
3379                if (isActivityProcess) {
3380                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3381                    msg.obj = app;
3382                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3383                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3384                }
3385            }
3386            checkTime(startTime, "startProcess: done updating pids map");
3387        } catch (RuntimeException e) {
3388            // XXX do better error recovery.
3389            app.setPid(0);
3390            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3391            if (app.isolated) {
3392                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3393            }
3394            Slog.e(TAG, "Failure starting process " + app.processName, e);
3395        }
3396    }
3397
3398    void updateUsageStats(ActivityRecord component, boolean resumed) {
3399        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3400                "updateUsageStats: comp=" + component + "res=" + resumed);
3401        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3402        if (resumed) {
3403            if (mUsageStatsService != null) {
3404                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3405                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3406            }
3407            synchronized (stats) {
3408                stats.noteActivityResumedLocked(component.app.uid);
3409            }
3410        } else {
3411            if (mUsageStatsService != null) {
3412                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3413                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3414            }
3415            synchronized (stats) {
3416                stats.noteActivityPausedLocked(component.app.uid);
3417            }
3418        }
3419    }
3420
3421    Intent getHomeIntent() {
3422        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3423        intent.setComponent(mTopComponent);
3424        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3425            intent.addCategory(Intent.CATEGORY_HOME);
3426        }
3427        return intent;
3428    }
3429
3430    boolean startHomeActivityLocked(int userId, String reason) {
3431        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3432                && mTopAction == null) {
3433            // We are running in factory test mode, but unable to find
3434            // the factory test app, so just sit around displaying the
3435            // error message and don't try to start anything.
3436            return false;
3437        }
3438        Intent intent = getHomeIntent();
3439        ActivityInfo aInfo =
3440            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3441        if (aInfo != null) {
3442            intent.setComponent(new ComponentName(
3443                    aInfo.applicationInfo.packageName, aInfo.name));
3444            // Don't do this if the home app is currently being
3445            // instrumented.
3446            aInfo = new ActivityInfo(aInfo);
3447            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3448            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3449                    aInfo.applicationInfo.uid, true);
3450            if (app == null || app.instrumentationClass == null) {
3451                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3452                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3453            }
3454        }
3455
3456        return true;
3457    }
3458
3459    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3460        ActivityInfo ai = null;
3461        ComponentName comp = intent.getComponent();
3462        try {
3463            if (comp != null) {
3464                // Factory test.
3465                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3466            } else {
3467                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3468                        intent,
3469                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3470                        flags, userId);
3471
3472                if (info != null) {
3473                    ai = info.activityInfo;
3474                }
3475            }
3476        } catch (RemoteException e) {
3477            // ignore
3478        }
3479
3480        return ai;
3481    }
3482
3483    /**
3484     * Starts the "new version setup screen" if appropriate.
3485     */
3486    void startSetupActivityLocked() {
3487        // Only do this once per boot.
3488        if (mCheckedForSetup) {
3489            return;
3490        }
3491
3492        // We will show this screen if the current one is a different
3493        // version than the last one shown, and we are not running in
3494        // low-level factory test mode.
3495        final ContentResolver resolver = mContext.getContentResolver();
3496        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3497                Settings.Global.getInt(resolver,
3498                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3499            mCheckedForSetup = true;
3500
3501            // See if we should be showing the platform update setup UI.
3502            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3503            List<ResolveInfo> ris = mContext.getPackageManager()
3504                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3505
3506            // We don't allow third party apps to replace this.
3507            ResolveInfo ri = null;
3508            for (int i=0; ris != null && i<ris.size(); i++) {
3509                if ((ris.get(i).activityInfo.applicationInfo.flags
3510                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3511                    ri = ris.get(i);
3512                    break;
3513                }
3514            }
3515
3516            if (ri != null) {
3517                String vers = ri.activityInfo.metaData != null
3518                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3519                        : null;
3520                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3521                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3522                            Intent.METADATA_SETUP_VERSION);
3523                }
3524                String lastVers = Settings.Secure.getString(
3525                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3526                if (vers != null && !vers.equals(lastVers)) {
3527                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3528                    intent.setComponent(new ComponentName(
3529                            ri.activityInfo.packageName, ri.activityInfo.name));
3530                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3531                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3532                            null, null, null);
3533                }
3534            }
3535        }
3536    }
3537
3538    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3539        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3540    }
3541
3542    void enforceNotIsolatedCaller(String caller) {
3543        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3544            throw new SecurityException("Isolated process not allowed to call " + caller);
3545        }
3546    }
3547
3548    void enforceShellRestriction(String restriction, int userHandle) {
3549        if (Binder.getCallingUid() == Process.SHELL_UID) {
3550            if (userHandle < 0
3551                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3552                throw new SecurityException("Shell does not have permission to access user "
3553                        + userHandle);
3554            }
3555        }
3556    }
3557
3558    @Override
3559    public int getFrontActivityScreenCompatMode() {
3560        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3561        synchronized (this) {
3562            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3563        }
3564    }
3565
3566    @Override
3567    public void setFrontActivityScreenCompatMode(int mode) {
3568        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3569                "setFrontActivityScreenCompatMode");
3570        synchronized (this) {
3571            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3572        }
3573    }
3574
3575    @Override
3576    public int getPackageScreenCompatMode(String packageName) {
3577        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3578        synchronized (this) {
3579            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3580        }
3581    }
3582
3583    @Override
3584    public void setPackageScreenCompatMode(String packageName, int mode) {
3585        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3586                "setPackageScreenCompatMode");
3587        synchronized (this) {
3588            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3589        }
3590    }
3591
3592    @Override
3593    public boolean getPackageAskScreenCompat(String packageName) {
3594        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3595        synchronized (this) {
3596            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3597        }
3598    }
3599
3600    @Override
3601    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3602        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3603                "setPackageAskScreenCompat");
3604        synchronized (this) {
3605            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3606        }
3607    }
3608
3609    private boolean hasUsageStatsPermission(String callingPackage) {
3610        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3611                Binder.getCallingUid(), callingPackage);
3612        if (mode == AppOpsManager.MODE_DEFAULT) {
3613            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3614                    == PackageManager.PERMISSION_GRANTED;
3615        }
3616        return mode == AppOpsManager.MODE_ALLOWED;
3617    }
3618
3619    @Override
3620    public int getPackageProcessState(String packageName, String callingPackage) {
3621        if (!hasUsageStatsPermission(callingPackage)) {
3622            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3623                    "getPackageProcessState");
3624        }
3625
3626        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3627        synchronized (this) {
3628            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3629                final ProcessRecord proc = mLruProcesses.get(i);
3630                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3631                        || procState > proc.setProcState) {
3632                    boolean found = false;
3633                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3634                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3635                            procState = proc.setProcState;
3636                            found = true;
3637                        }
3638                    }
3639                    if (proc.pkgDeps != null && !found) {
3640                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3641                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3642                                procState = proc.setProcState;
3643                                break;
3644                            }
3645                        }
3646                    }
3647                }
3648            }
3649        }
3650        return procState;
3651    }
3652
3653    @Override
3654    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3655        synchronized (this) {
3656            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3657            if (app == null) {
3658                return false;
3659            }
3660            if (app.trimMemoryLevel < level && app.thread != null &&
3661                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3662                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3663                try {
3664                    app.thread.scheduleTrimMemory(level);
3665                    app.trimMemoryLevel = level;
3666                    return true;
3667                } catch (RemoteException e) {
3668                    // Fallthrough to failure case.
3669                }
3670            }
3671        }
3672        return false;
3673    }
3674
3675    private void dispatchProcessesChanged() {
3676        int N;
3677        synchronized (this) {
3678            N = mPendingProcessChanges.size();
3679            if (mActiveProcessChanges.length < N) {
3680                mActiveProcessChanges = new ProcessChangeItem[N];
3681            }
3682            mPendingProcessChanges.toArray(mActiveProcessChanges);
3683            mPendingProcessChanges.clear();
3684            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3685                    "*** Delivering " + N + " process changes");
3686        }
3687
3688        int i = mProcessObservers.beginBroadcast();
3689        while (i > 0) {
3690            i--;
3691            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3692            if (observer != null) {
3693                try {
3694                    for (int j=0; j<N; j++) {
3695                        ProcessChangeItem item = mActiveProcessChanges[j];
3696                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3697                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3698                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3699                                    + item.uid + ": " + item.foregroundActivities);
3700                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3701                                    item.foregroundActivities);
3702                        }
3703                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3704                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3705                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3706                                    + ": " + item.processState);
3707                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3708                        }
3709                    }
3710                } catch (RemoteException e) {
3711                }
3712            }
3713        }
3714        mProcessObservers.finishBroadcast();
3715
3716        synchronized (this) {
3717            for (int j=0; j<N; j++) {
3718                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3719            }
3720        }
3721    }
3722
3723    private void dispatchProcessDied(int pid, int uid) {
3724        int i = mProcessObservers.beginBroadcast();
3725        while (i > 0) {
3726            i--;
3727            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3728            if (observer != null) {
3729                try {
3730                    observer.onProcessDied(pid, uid);
3731                } catch (RemoteException e) {
3732                }
3733            }
3734        }
3735        mProcessObservers.finishBroadcast();
3736    }
3737
3738    private void dispatchUidsChanged() {
3739        int N;
3740        synchronized (this) {
3741            N = mPendingUidChanges.size();
3742            if (mActiveUidChanges.length < N) {
3743                mActiveUidChanges = new UidRecord.ChangeItem[N];
3744            }
3745            for (int i=0; i<N; i++) {
3746                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3747                mActiveUidChanges[i] = change;
3748                change.uidRecord.pendingChange = null;
3749                change.uidRecord = null;
3750            }
3751            mPendingUidChanges.clear();
3752            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3753                    "*** Delivering " + N + " uid changes");
3754        }
3755
3756        if (mLocalPowerManager != null) {
3757            for (int j=0; j<N; j++) {
3758                UidRecord.ChangeItem item = mActiveUidChanges[j];
3759                if (item.gone) {
3760                    mLocalPowerManager.uidGone(item.uid);
3761                } else {
3762                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3763                }
3764            }
3765        }
3766
3767        int i = mUidObservers.beginBroadcast();
3768        while (i > 0) {
3769            i--;
3770            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3771            if (observer != null) {
3772                try {
3773                    for (int j=0; j<N; j++) {
3774                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3775                        if (item.gone) {
3776                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3777                                    "UID gone uid=" + item.uid);
3778                            observer.onUidGone(item.uid);
3779                        } else {
3780                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3781                                    "UID CHANGED uid=" + item.uid
3782                                    + ": " + item.processState);
3783                            observer.onUidStateChanged(item.uid, item.processState);
3784                        }
3785                    }
3786                } catch (RemoteException e) {
3787                }
3788            }
3789        }
3790        mUidObservers.finishBroadcast();
3791
3792        synchronized (this) {
3793            for (int j=0; j<N; j++) {
3794                mAvailUidChanges.add(mActiveUidChanges[j]);
3795            }
3796        }
3797    }
3798
3799    @Override
3800    public final int startActivity(IApplicationThread caller, String callingPackage,
3801            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3802            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3803        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3804            resultWho, requestCode, startFlags, profilerInfo, options,
3805            UserHandle.getCallingUserId());
3806    }
3807
3808    @Override
3809    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3810            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3811            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3812        enforceNotIsolatedCaller("startActivity");
3813        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3814                false, ALLOW_FULL_ONLY, "startActivity", null);
3815        // TODO: Switch to user app stacks here.
3816        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3817                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3818                profilerInfo, null, null, options, false, userId, null, null);
3819    }
3820
3821    @Override
3822    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3823            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3824            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3825            int userId) {
3826
3827        // This is very dangerous -- it allows you to perform a start activity (including
3828        // permission grants) as any app that may launch one of your own activities.  So
3829        // we will only allow this to be done from activities that are part of the core framework,
3830        // and then only when they are running as the system.
3831        final ActivityRecord sourceRecord;
3832        final int targetUid;
3833        final String targetPackage;
3834        synchronized (this) {
3835            if (resultTo == null) {
3836                throw new SecurityException("Must be called from an activity");
3837            }
3838            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3839            if (sourceRecord == null) {
3840                throw new SecurityException("Called with bad activity token: " + resultTo);
3841            }
3842            if (!sourceRecord.info.packageName.equals("android")) {
3843                throw new SecurityException(
3844                        "Must be called from an activity that is declared in the android package");
3845            }
3846            if (sourceRecord.app == null) {
3847                throw new SecurityException("Called without a process attached to activity");
3848            }
3849            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3850                // This is still okay, as long as this activity is running under the
3851                // uid of the original calling activity.
3852                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3853                    throw new SecurityException(
3854                            "Calling activity in uid " + sourceRecord.app.uid
3855                                    + " must be system uid or original calling uid "
3856                                    + sourceRecord.launchedFromUid);
3857                }
3858            }
3859            if (ignoreTargetSecurity) {
3860                if (intent.getComponent() == null) {
3861                    throw new SecurityException(
3862                            "Component must be specified with ignoreTargetSecurity");
3863                }
3864                if (intent.getSelector() != null) {
3865                    throw new SecurityException(
3866                            "Selector not allowed with ignoreTargetSecurity");
3867                }
3868            }
3869            targetUid = sourceRecord.launchedFromUid;
3870            targetPackage = sourceRecord.launchedFromPackage;
3871        }
3872
3873        if (userId == UserHandle.USER_NULL) {
3874            userId = UserHandle.getUserId(sourceRecord.app.uid);
3875        }
3876
3877        // TODO: Switch to user app stacks here.
3878        try {
3879            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3880                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3881                    null, null, options, ignoreTargetSecurity, userId, null, null);
3882            return ret;
3883        } catch (SecurityException e) {
3884            // XXX need to figure out how to propagate to original app.
3885            // A SecurityException here is generally actually a fault of the original
3886            // calling activity (such as a fairly granting permissions), so propagate it
3887            // back to them.
3888            /*
3889            StringBuilder msg = new StringBuilder();
3890            msg.append("While launching");
3891            msg.append(intent.toString());
3892            msg.append(": ");
3893            msg.append(e.getMessage());
3894            */
3895            throw e;
3896        }
3897    }
3898
3899    @Override
3900    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3901            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3902            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3903        enforceNotIsolatedCaller("startActivityAndWait");
3904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3905                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3906        WaitResult res = new WaitResult();
3907        // TODO: Switch to user app stacks here.
3908        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3909                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3910                options, false, userId, null, null);
3911        return res;
3912    }
3913
3914    @Override
3915    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3916            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3917            int startFlags, Configuration config, Bundle options, int userId) {
3918        enforceNotIsolatedCaller("startActivityWithConfig");
3919        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3920                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3921        // TODO: Switch to user app stacks here.
3922        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3923                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3924                null, null, config, options, false, userId, null, null);
3925        return ret;
3926    }
3927
3928    @Override
3929    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3930            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3931            int requestCode, int flagsMask, int flagsValues, Bundle options)
3932            throws TransactionTooLargeException {
3933        enforceNotIsolatedCaller("startActivityIntentSender");
3934        // Refuse possible leaked file descriptors
3935        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3936            throw new IllegalArgumentException("File descriptors passed in Intent");
3937        }
3938
3939        IIntentSender sender = intent.getTarget();
3940        if (!(sender instanceof PendingIntentRecord)) {
3941            throw new IllegalArgumentException("Bad PendingIntent object");
3942        }
3943
3944        PendingIntentRecord pir = (PendingIntentRecord)sender;
3945
3946        synchronized (this) {
3947            // If this is coming from the currently resumed activity, it is
3948            // effectively saying that app switches are allowed at this point.
3949            final ActivityStack stack = getFocusedStack();
3950            if (stack.mResumedActivity != null &&
3951                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3952                mAppSwitchesAllowedTime = 0;
3953            }
3954        }
3955        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3956                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3957        return ret;
3958    }
3959
3960    @Override
3961    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3962            Intent intent, String resolvedType, IVoiceInteractionSession session,
3963            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3964            Bundle options, int userId) {
3965        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3966                != PackageManager.PERMISSION_GRANTED) {
3967            String msg = "Permission Denial: startVoiceActivity() from pid="
3968                    + Binder.getCallingPid()
3969                    + ", uid=" + Binder.getCallingUid()
3970                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3971            Slog.w(TAG, msg);
3972            throw new SecurityException(msg);
3973        }
3974        if (session == null || interactor == null) {
3975            throw new NullPointerException("null session or interactor");
3976        }
3977        userId = handleIncomingUser(callingPid, callingUid, userId,
3978                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3979        // TODO: Switch to user app stacks here.
3980        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3981                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3982                null, options, false, userId, null, null);
3983    }
3984
3985    @Override
3986    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3987        synchronized (this) {
3988            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3989                if (keepAwake) {
3990                    mVoiceWakeLock.acquire();
3991                } else {
3992                    mVoiceWakeLock.release();
3993                }
3994            }
3995        }
3996    }
3997
3998    @Override
3999    public boolean startNextMatchingActivity(IBinder callingActivity,
4000            Intent intent, Bundle options) {
4001        // Refuse possible leaked file descriptors
4002        if (intent != null && intent.hasFileDescriptors() == true) {
4003            throw new IllegalArgumentException("File descriptors passed in Intent");
4004        }
4005
4006        synchronized (this) {
4007            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4008            if (r == null) {
4009                ActivityOptions.abort(options);
4010                return false;
4011            }
4012            if (r.app == null || r.app.thread == null) {
4013                // The caller is not running...  d'oh!
4014                ActivityOptions.abort(options);
4015                return false;
4016            }
4017            intent = new Intent(intent);
4018            // The caller is not allowed to change the data.
4019            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4020            // And we are resetting to find the next component...
4021            intent.setComponent(null);
4022
4023            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4024
4025            ActivityInfo aInfo = null;
4026            try {
4027                List<ResolveInfo> resolves =
4028                    AppGlobals.getPackageManager().queryIntentActivities(
4029                            intent, r.resolvedType,
4030                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4031                            UserHandle.getCallingUserId());
4032
4033                // Look for the original activity in the list...
4034                final int N = resolves != null ? resolves.size() : 0;
4035                for (int i=0; i<N; i++) {
4036                    ResolveInfo rInfo = resolves.get(i);
4037                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4038                            && rInfo.activityInfo.name.equals(r.info.name)) {
4039                        // We found the current one...  the next matching is
4040                        // after it.
4041                        i++;
4042                        if (i<N) {
4043                            aInfo = resolves.get(i).activityInfo;
4044                        }
4045                        if (debug) {
4046                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4047                                    + "/" + r.info.name);
4048                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4049                                    + "/" + aInfo.name);
4050                        }
4051                        break;
4052                    }
4053                }
4054            } catch (RemoteException e) {
4055            }
4056
4057            if (aInfo == null) {
4058                // Nobody who is next!
4059                ActivityOptions.abort(options);
4060                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4061                return false;
4062            }
4063
4064            intent.setComponent(new ComponentName(
4065                    aInfo.applicationInfo.packageName, aInfo.name));
4066            intent.setFlags(intent.getFlags()&~(
4067                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4068                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4069                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4070                    Intent.FLAG_ACTIVITY_NEW_TASK));
4071
4072            // Okay now we need to start the new activity, replacing the
4073            // currently running activity.  This is a little tricky because
4074            // we want to start the new one as if the current one is finished,
4075            // but not finish the current one first so that there is no flicker.
4076            // And thus...
4077            final boolean wasFinishing = r.finishing;
4078            r.finishing = true;
4079
4080            // Propagate reply information over to the new activity.
4081            final ActivityRecord resultTo = r.resultTo;
4082            final String resultWho = r.resultWho;
4083            final int requestCode = r.requestCode;
4084            r.resultTo = null;
4085            if (resultTo != null) {
4086                resultTo.removeResultsLocked(r, resultWho, requestCode);
4087            }
4088
4089            final long origId = Binder.clearCallingIdentity();
4090            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4091                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4092                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4093                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4094            Binder.restoreCallingIdentity(origId);
4095
4096            r.finishing = wasFinishing;
4097            if (res != ActivityManager.START_SUCCESS) {
4098                return false;
4099            }
4100            return true;
4101        }
4102    }
4103
4104    @Override
4105    public final int startActivityFromRecents(int taskId, Bundle options) {
4106        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4107            String msg = "Permission Denial: startActivityFromRecents called without " +
4108                    START_TASKS_FROM_RECENTS;
4109            Slog.w(TAG, msg);
4110            throw new SecurityException(msg);
4111        }
4112        return startActivityFromRecentsInner(taskId, options);
4113    }
4114
4115    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4116        final TaskRecord task;
4117        final int callingUid;
4118        final String callingPackage;
4119        final Intent intent;
4120        final int userId;
4121        synchronized (this) {
4122            task = mRecentTasks.taskForIdLocked(taskId);
4123            if (task == null) {
4124                throw new IllegalArgumentException("Task " + taskId + " not found.");
4125            }
4126            if (task.getRootActivity() != null) {
4127                moveTaskToFrontLocked(task.taskId, 0, null);
4128                return ActivityManager.START_TASK_TO_FRONT;
4129            }
4130            callingUid = task.mCallingUid;
4131            callingPackage = task.mCallingPackage;
4132            intent = task.intent;
4133            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4134            userId = task.userId;
4135        }
4136        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4137                options, userId, null, task);
4138    }
4139
4140    final int startActivityInPackage(int uid, String callingPackage,
4141            Intent intent, String resolvedType, IBinder resultTo,
4142            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4143            IActivityContainer container, TaskRecord inTask) {
4144
4145        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4146                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4147
4148        // TODO: Switch to user app stacks here.
4149        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4150                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4151                null, null, null, options, false, userId, container, inTask);
4152        return ret;
4153    }
4154
4155    @Override
4156    public final int startActivities(IApplicationThread caller, String callingPackage,
4157            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4158            int userId) {
4159        enforceNotIsolatedCaller("startActivities");
4160        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4161                false, ALLOW_FULL_ONLY, "startActivity", null);
4162        // TODO: Switch to user app stacks here.
4163        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4164                resolvedTypes, resultTo, options, userId);
4165        return ret;
4166    }
4167
4168    final int startActivitiesInPackage(int uid, String callingPackage,
4169            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4170            Bundle options, int userId) {
4171
4172        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4173                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4174        // TODO: Switch to user app stacks here.
4175        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4176                resultTo, options, userId);
4177        return ret;
4178    }
4179
4180    @Override
4181    public void reportActivityFullyDrawn(IBinder token) {
4182        synchronized (this) {
4183            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4184            if (r == null) {
4185                return;
4186            }
4187            r.reportFullyDrawnLocked();
4188        }
4189    }
4190
4191    @Override
4192    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4193        synchronized (this) {
4194            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4195            if (r == null) {
4196                return;
4197            }
4198            if (r.task != null && r.task.mResizeable) {
4199                // Fixed screen orientation isn't supported with resizeable activities.
4200                return;
4201            }
4202            final long origId = Binder.clearCallingIdentity();
4203            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4204            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4205                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4206            if (config != null) {
4207                r.frozenBeforeDestroy = true;
4208                if (!updateConfigurationLocked(config, r, false, false)) {
4209                    mStackSupervisor.resumeTopActivitiesLocked();
4210                }
4211            }
4212            Binder.restoreCallingIdentity(origId);
4213        }
4214    }
4215
4216    @Override
4217    public int getRequestedOrientation(IBinder token) {
4218        synchronized (this) {
4219            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220            if (r == null) {
4221                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4222            }
4223            return mWindowManager.getAppOrientation(r.appToken);
4224        }
4225    }
4226
4227    /**
4228     * This is the internal entry point for handling Activity.finish().
4229     *
4230     * @param token The Binder token referencing the Activity we want to finish.
4231     * @param resultCode Result code, if any, from this Activity.
4232     * @param resultData Result data (Intent), if any, from this Activity.
4233     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4234     *            the root Activity in the task.
4235     *
4236     * @return Returns true if the activity successfully finished, or false if it is still running.
4237     */
4238    @Override
4239    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4240            boolean finishTask) {
4241        // Refuse possible leaked file descriptors
4242        if (resultData != null && resultData.hasFileDescriptors() == true) {
4243            throw new IllegalArgumentException("File descriptors passed in Intent");
4244        }
4245
4246        synchronized(this) {
4247            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4248            if (r == null) {
4249                return true;
4250            }
4251            // Keep track of the root activity of the task before we finish it
4252            TaskRecord tr = r.task;
4253            ActivityRecord rootR = tr.getRootActivity();
4254            if (rootR == null) {
4255                Slog.w(TAG, "Finishing task with all activities already finished");
4256            }
4257            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4258            // finish.
4259            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4260                    mStackSupervisor.isLastLockedTask(tr)) {
4261                Slog.i(TAG, "Not finishing task in lock task mode");
4262                mStackSupervisor.showLockTaskToast();
4263                return false;
4264            }
4265            if (mController != null) {
4266                // Find the first activity that is not finishing.
4267                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4268                if (next != null) {
4269                    // ask watcher if this is allowed
4270                    boolean resumeOK = true;
4271                    try {
4272                        resumeOK = mController.activityResuming(next.packageName);
4273                    } catch (RemoteException e) {
4274                        mController = null;
4275                        Watchdog.getInstance().setActivityController(null);
4276                    }
4277
4278                    if (!resumeOK) {
4279                        Slog.i(TAG, "Not finishing activity because controller resumed");
4280                        return false;
4281                    }
4282                }
4283            }
4284            final long origId = Binder.clearCallingIdentity();
4285            try {
4286                boolean res;
4287                if (finishTask && r == rootR) {
4288                    // If requested, remove the task that is associated to this activity only if it
4289                    // was the root activity in the task. The result code and data is ignored
4290                    // because we don't support returning them across task boundaries.
4291                    res = removeTaskByIdLocked(tr.taskId, false);
4292                    if (!res) {
4293                        Slog.i(TAG, "Removing task failed to finish activity");
4294                    }
4295                } else {
4296                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4297                            resultData, "app-request", true);
4298                    if (!res) {
4299                        Slog.i(TAG, "Failed to finish by app-request");
4300                    }
4301                }
4302                return res;
4303            } finally {
4304                Binder.restoreCallingIdentity(origId);
4305            }
4306        }
4307    }
4308
4309    @Override
4310    public final void finishHeavyWeightApp() {
4311        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4312                != PackageManager.PERMISSION_GRANTED) {
4313            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4314                    + Binder.getCallingPid()
4315                    + ", uid=" + Binder.getCallingUid()
4316                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4317            Slog.w(TAG, msg);
4318            throw new SecurityException(msg);
4319        }
4320
4321        synchronized(this) {
4322            if (mHeavyWeightProcess == null) {
4323                return;
4324            }
4325
4326            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4327            for (int i = 0; i < activities.size(); i++) {
4328                ActivityRecord r = activities.get(i);
4329                if (!r.finishing && r.isInStackLocked()) {
4330                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4331                            null, "finish-heavy", true);
4332                }
4333            }
4334
4335            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4336                    mHeavyWeightProcess.userId, 0));
4337            mHeavyWeightProcess = null;
4338        }
4339    }
4340
4341    @Override
4342    public void crashApplication(int uid, int initialPid, String packageName,
4343            String message) {
4344        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4345                != PackageManager.PERMISSION_GRANTED) {
4346            String msg = "Permission Denial: crashApplication() from pid="
4347                    + Binder.getCallingPid()
4348                    + ", uid=" + Binder.getCallingUid()
4349                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4350            Slog.w(TAG, msg);
4351            throw new SecurityException(msg);
4352        }
4353
4354        synchronized(this) {
4355            ProcessRecord proc = null;
4356
4357            // Figure out which process to kill.  We don't trust that initialPid
4358            // still has any relation to current pids, so must scan through the
4359            // list.
4360            synchronized (mPidsSelfLocked) {
4361                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4362                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4363                    if (p.uid != uid) {
4364                        continue;
4365                    }
4366                    if (p.pid == initialPid) {
4367                        proc = p;
4368                        break;
4369                    }
4370                    if (p.pkgList.containsKey(packageName)) {
4371                        proc = p;
4372                    }
4373                }
4374            }
4375
4376            if (proc == null) {
4377                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4378                        + " initialPid=" + initialPid
4379                        + " packageName=" + packageName);
4380                return;
4381            }
4382
4383            if (proc.thread != null) {
4384                if (proc.pid == Process.myPid()) {
4385                    Log.w(TAG, "crashApplication: trying to crash self!");
4386                    return;
4387                }
4388                long ident = Binder.clearCallingIdentity();
4389                try {
4390                    proc.thread.scheduleCrash(message);
4391                } catch (RemoteException e) {
4392                }
4393                Binder.restoreCallingIdentity(ident);
4394            }
4395        }
4396    }
4397
4398    @Override
4399    public final void finishSubActivity(IBinder token, String resultWho,
4400            int requestCode) {
4401        synchronized(this) {
4402            final long origId = Binder.clearCallingIdentity();
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r != null) {
4405                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4406            }
4407            Binder.restoreCallingIdentity(origId);
4408        }
4409    }
4410
4411    @Override
4412    public boolean finishActivityAffinity(IBinder token) {
4413        synchronized(this) {
4414            final long origId = Binder.clearCallingIdentity();
4415            try {
4416                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4417                if (r == null) {
4418                    return false;
4419                }
4420
4421                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4422                // can finish.
4423                final TaskRecord task = r.task;
4424                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4425                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4426                    mStackSupervisor.showLockTaskToast();
4427                    return false;
4428                }
4429                return task.stack.finishActivityAffinityLocked(r);
4430            } finally {
4431                Binder.restoreCallingIdentity(origId);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public void finishVoiceTask(IVoiceInteractionSession session) {
4438        synchronized(this) {
4439            final long origId = Binder.clearCallingIdentity();
4440            try {
4441                mStackSupervisor.finishVoiceTask(session);
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446
4447    }
4448
4449    @Override
4450    public boolean releaseActivityInstance(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455                if (r == null) {
4456                    return false;
4457                }
4458                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4459            } finally {
4460                Binder.restoreCallingIdentity(origId);
4461            }
4462        }
4463    }
4464
4465    @Override
4466    public void releaseSomeActivities(IApplicationThread appInt) {
4467        synchronized(this) {
4468            final long origId = Binder.clearCallingIdentity();
4469            try {
4470                ProcessRecord app = getRecordForAppLocked(appInt);
4471                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4472            } finally {
4473                Binder.restoreCallingIdentity(origId);
4474            }
4475        }
4476    }
4477
4478    @Override
4479    public boolean willActivityBeVisible(IBinder token) {
4480        synchronized(this) {
4481            ActivityStack stack = ActivityRecord.getStackLocked(token);
4482            if (stack != null) {
4483                return stack.willActivityBeVisibleLocked(token);
4484            }
4485            return false;
4486        }
4487    }
4488
4489    @Override
4490    public void overridePendingTransition(IBinder token, String packageName,
4491            int enterAnim, int exitAnim) {
4492        synchronized(this) {
4493            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4494            if (self == null) {
4495                return;
4496            }
4497
4498            final long origId = Binder.clearCallingIdentity();
4499
4500            if (self.state == ActivityState.RESUMED
4501                    || self.state == ActivityState.PAUSING) {
4502                mWindowManager.overridePendingAppTransition(packageName,
4503                        enterAnim, exitAnim, null);
4504            }
4505
4506            Binder.restoreCallingIdentity(origId);
4507        }
4508    }
4509
4510    /**
4511     * Main function for removing an existing process from the activity manager
4512     * as a result of that process going away.  Clears out all connections
4513     * to the process.
4514     */
4515    private final void handleAppDiedLocked(ProcessRecord app,
4516            boolean restarting, boolean allowRestart) {
4517        int pid = app.pid;
4518        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4519        if (!kept && !restarting) {
4520            removeLruProcessLocked(app);
4521            if (pid > 0) {
4522                ProcessList.remove(pid);
4523            }
4524        }
4525
4526        if (mProfileProc == app) {
4527            clearProfilerLocked();
4528        }
4529
4530        // Remove this application's activities from active lists.
4531        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4532
4533        app.activities.clear();
4534
4535        if (app.instrumentationClass != null) {
4536            Slog.w(TAG, "Crash of app " + app.processName
4537                  + " running instrumentation " + app.instrumentationClass);
4538            Bundle info = new Bundle();
4539            info.putString("shortMsg", "Process crashed.");
4540            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4541        }
4542
4543        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4544            // If there was nothing to resume, and we are not already
4545            // restarting this process, but there is a visible activity that
4546            // is hosted by the process...  then make sure all visible
4547            // activities are running, taking care of restarting this
4548            // process.
4549            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4550        }
4551    }
4552
4553    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4554        IBinder threadBinder = thread.asBinder();
4555        // Find the application record.
4556        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4557            ProcessRecord rec = mLruProcesses.get(i);
4558            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4559                return i;
4560            }
4561        }
4562        return -1;
4563    }
4564
4565    final ProcessRecord getRecordForAppLocked(
4566            IApplicationThread thread) {
4567        if (thread == null) {
4568            return null;
4569        }
4570
4571        int appIndex = getLRURecordIndexForAppLocked(thread);
4572        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4573    }
4574
4575    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4576        // If there are no longer any background processes running,
4577        // and the app that died was not running instrumentation,
4578        // then tell everyone we are now low on memory.
4579        boolean haveBg = false;
4580        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4581            ProcessRecord rec = mLruProcesses.get(i);
4582            if (rec.thread != null
4583                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4584                haveBg = true;
4585                break;
4586            }
4587        }
4588
4589        if (!haveBg) {
4590            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4591            if (doReport) {
4592                long now = SystemClock.uptimeMillis();
4593                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4594                    doReport = false;
4595                } else {
4596                    mLastMemUsageReportTime = now;
4597                }
4598            }
4599            final ArrayList<ProcessMemInfo> memInfos
4600                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4601            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4602            long now = SystemClock.uptimeMillis();
4603            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4604                ProcessRecord rec = mLruProcesses.get(i);
4605                if (rec == dyingProc || rec.thread == null) {
4606                    continue;
4607                }
4608                if (doReport) {
4609                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4610                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4611                }
4612                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4613                    // The low memory report is overriding any current
4614                    // state for a GC request.  Make sure to do
4615                    // heavy/important/visible/foreground processes first.
4616                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4617                        rec.lastRequestedGc = 0;
4618                    } else {
4619                        rec.lastRequestedGc = rec.lastLowMemory;
4620                    }
4621                    rec.reportLowMemory = true;
4622                    rec.lastLowMemory = now;
4623                    mProcessesToGc.remove(rec);
4624                    addProcessToGcListLocked(rec);
4625                }
4626            }
4627            if (doReport) {
4628                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4629                mHandler.sendMessage(msg);
4630            }
4631            scheduleAppGcsLocked();
4632        }
4633    }
4634
4635    final void appDiedLocked(ProcessRecord app) {
4636       appDiedLocked(app, app.pid, app.thread, false);
4637    }
4638
4639    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4640            boolean fromBinderDied) {
4641        // First check if this ProcessRecord is actually active for the pid.
4642        synchronized (mPidsSelfLocked) {
4643            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4644            if (curProc != app) {
4645                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4646                return;
4647            }
4648        }
4649
4650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4651        synchronized (stats) {
4652            stats.noteProcessDiedLocked(app.info.uid, pid);
4653        }
4654
4655        if (!app.killed) {
4656            if (!fromBinderDied) {
4657                Process.killProcessQuiet(pid);
4658            }
4659            killProcessGroup(app.info.uid, pid);
4660            app.killed = true;
4661        }
4662
4663        // Clean up already done if the process has been re-started.
4664        if (app.pid == pid && app.thread != null &&
4665                app.thread.asBinder() == thread.asBinder()) {
4666            boolean doLowMem = app.instrumentationClass == null;
4667            boolean doOomAdj = doLowMem;
4668            if (!app.killedByAm) {
4669                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4670                        + ") has died");
4671                mAllowLowerMemLevel = true;
4672            } else {
4673                // Note that we always want to do oom adj to update our state with the
4674                // new number of procs.
4675                mAllowLowerMemLevel = false;
4676                doLowMem = false;
4677            }
4678            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4679            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4680                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4681            handleAppDiedLocked(app, false, true);
4682
4683            if (doOomAdj) {
4684                updateOomAdjLocked();
4685            }
4686            if (doLowMem) {
4687                doLowMemReportIfNeededLocked(app);
4688            }
4689        } else if (app.pid != pid) {
4690            // A new process has already been started.
4691            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4692                    + ") has died and restarted (pid " + app.pid + ").");
4693            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4694        } else if (DEBUG_PROCESSES) {
4695            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4696                    + thread.asBinder());
4697        }
4698    }
4699
4700    /**
4701     * If a stack trace dump file is configured, dump process stack traces.
4702     * @param clearTraces causes the dump file to be erased prior to the new
4703     *    traces being written, if true; when false, the new traces will be
4704     *    appended to any existing file content.
4705     * @param firstPids of dalvik VM processes to dump stack traces for first
4706     * @param lastPids of dalvik VM processes to dump stack traces for last
4707     * @param nativeProcs optional list of native process names to dump stack crawls
4708     * @return file containing stack traces, or null if no dump file is configured
4709     */
4710    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4711            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4712        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4713        if (tracesPath == null || tracesPath.length() == 0) {
4714            return null;
4715        }
4716
4717        File tracesFile = new File(tracesPath);
4718        try {
4719            File tracesDir = tracesFile.getParentFile();
4720            if (!tracesDir.exists()) {
4721                tracesDir.mkdirs();
4722                if (!SELinux.restorecon(tracesDir)) {
4723                    return null;
4724                }
4725            }
4726            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4727
4728            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4729            tracesFile.createNewFile();
4730            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4731        } catch (IOException e) {
4732            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4733            return null;
4734        }
4735
4736        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4737        return tracesFile;
4738    }
4739
4740    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4741            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4742        // Use a FileObserver to detect when traces finish writing.
4743        // The order of traces is considered important to maintain for legibility.
4744        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4745            @Override
4746            public synchronized void onEvent(int event, String path) { notify(); }
4747        };
4748
4749        try {
4750            observer.startWatching();
4751
4752            // First collect all of the stacks of the most important pids.
4753            if (firstPids != null) {
4754                try {
4755                    int num = firstPids.size();
4756                    for (int i = 0; i < num; i++) {
4757                        synchronized (observer) {
4758                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4759                            observer.wait(200);  // Wait for write-close, give up after 200msec
4760                        }
4761                    }
4762                } catch (InterruptedException e) {
4763                    Slog.wtf(TAG, e);
4764                }
4765            }
4766
4767            // Next collect the stacks of the native pids
4768            if (nativeProcs != null) {
4769                int[] pids = Process.getPidsForCommands(nativeProcs);
4770                if (pids != null) {
4771                    for (int pid : pids) {
4772                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4773                    }
4774                }
4775            }
4776
4777            // Lastly, measure CPU usage.
4778            if (processCpuTracker != null) {
4779                processCpuTracker.init();
4780                System.gc();
4781                processCpuTracker.update();
4782                try {
4783                    synchronized (processCpuTracker) {
4784                        processCpuTracker.wait(500); // measure over 1/2 second.
4785                    }
4786                } catch (InterruptedException e) {
4787                }
4788                processCpuTracker.update();
4789
4790                // We'll take the stack crawls of just the top apps using CPU.
4791                final int N = processCpuTracker.countWorkingStats();
4792                int numProcs = 0;
4793                for (int i=0; i<N && numProcs<5; i++) {
4794                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4795                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4796                        numProcs++;
4797                        try {
4798                            synchronized (observer) {
4799                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4800                                observer.wait(200);  // Wait for write-close, give up after 200msec
4801                            }
4802                        } catch (InterruptedException e) {
4803                            Slog.wtf(TAG, e);
4804                        }
4805
4806                    }
4807                }
4808            }
4809        } finally {
4810            observer.stopWatching();
4811        }
4812    }
4813
4814    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4815        if (true || IS_USER_BUILD) {
4816            return;
4817        }
4818        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4819        if (tracesPath == null || tracesPath.length() == 0) {
4820            return;
4821        }
4822
4823        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4824        StrictMode.allowThreadDiskWrites();
4825        try {
4826            final File tracesFile = new File(tracesPath);
4827            final File tracesDir = tracesFile.getParentFile();
4828            final File tracesTmp = new File(tracesDir, "__tmp__");
4829            try {
4830                if (!tracesDir.exists()) {
4831                    tracesDir.mkdirs();
4832                    if (!SELinux.restorecon(tracesDir.getPath())) {
4833                        return;
4834                    }
4835                }
4836                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4837
4838                if (tracesFile.exists()) {
4839                    tracesTmp.delete();
4840                    tracesFile.renameTo(tracesTmp);
4841                }
4842                StringBuilder sb = new StringBuilder();
4843                Time tobj = new Time();
4844                tobj.set(System.currentTimeMillis());
4845                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4846                sb.append(": ");
4847                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4848                sb.append(" since ");
4849                sb.append(msg);
4850                FileOutputStream fos = new FileOutputStream(tracesFile);
4851                fos.write(sb.toString().getBytes());
4852                if (app == null) {
4853                    fos.write("\n*** No application process!".getBytes());
4854                }
4855                fos.close();
4856                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4857            } catch (IOException e) {
4858                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4859                return;
4860            }
4861
4862            if (app != null) {
4863                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4864                firstPids.add(app.pid);
4865                dumpStackTraces(tracesPath, firstPids, null, null, null);
4866            }
4867
4868            File lastTracesFile = null;
4869            File curTracesFile = null;
4870            for (int i=9; i>=0; i--) {
4871                String name = String.format(Locale.US, "slow%02d.txt", i);
4872                curTracesFile = new File(tracesDir, name);
4873                if (curTracesFile.exists()) {
4874                    if (lastTracesFile != null) {
4875                        curTracesFile.renameTo(lastTracesFile);
4876                    } else {
4877                        curTracesFile.delete();
4878                    }
4879                }
4880                lastTracesFile = curTracesFile;
4881            }
4882            tracesFile.renameTo(curTracesFile);
4883            if (tracesTmp.exists()) {
4884                tracesTmp.renameTo(tracesFile);
4885            }
4886        } finally {
4887            StrictMode.setThreadPolicy(oldPolicy);
4888        }
4889    }
4890
4891    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4892            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4893        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4894        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4895
4896        if (mController != null) {
4897            try {
4898                // 0 == continue, -1 = kill process immediately
4899                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4900                if (res < 0 && app.pid != MY_PID) {
4901                    app.kill("anr", true);
4902                }
4903            } catch (RemoteException e) {
4904                mController = null;
4905                Watchdog.getInstance().setActivityController(null);
4906            }
4907        }
4908
4909        long anrTime = SystemClock.uptimeMillis();
4910        if (MONITOR_CPU_USAGE) {
4911            updateCpuStatsNow();
4912        }
4913
4914        synchronized (this) {
4915            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4916            if (mShuttingDown) {
4917                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4918                return;
4919            } else if (app.notResponding) {
4920                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4921                return;
4922            } else if (app.crashing) {
4923                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4924                return;
4925            }
4926
4927            // In case we come through here for the same app before completing
4928            // this one, mark as anring now so we will bail out.
4929            app.notResponding = true;
4930
4931            // Log the ANR to the event log.
4932            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4933                    app.processName, app.info.flags, annotation);
4934
4935            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4936            firstPids.add(app.pid);
4937
4938            int parentPid = app.pid;
4939            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4940            if (parentPid != app.pid) firstPids.add(parentPid);
4941
4942            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4943
4944            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4945                ProcessRecord r = mLruProcesses.get(i);
4946                if (r != null && r.thread != null) {
4947                    int pid = r.pid;
4948                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4949                        if (r.persistent) {
4950                            firstPids.add(pid);
4951                        } else {
4952                            lastPids.put(pid, Boolean.TRUE);
4953                        }
4954                    }
4955                }
4956            }
4957        }
4958
4959        // Log the ANR to the main log.
4960        StringBuilder info = new StringBuilder();
4961        info.setLength(0);
4962        info.append("ANR in ").append(app.processName);
4963        if (activity != null && activity.shortComponentName != null) {
4964            info.append(" (").append(activity.shortComponentName).append(")");
4965        }
4966        info.append("\n");
4967        info.append("PID: ").append(app.pid).append("\n");
4968        if (annotation != null) {
4969            info.append("Reason: ").append(annotation).append("\n");
4970        }
4971        if (parent != null && parent != activity) {
4972            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4973        }
4974
4975        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4976
4977        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4978                NATIVE_STACKS_OF_INTEREST);
4979
4980        String cpuInfo = null;
4981        if (MONITOR_CPU_USAGE) {
4982            updateCpuStatsNow();
4983            synchronized (mProcessCpuTracker) {
4984                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4985            }
4986            info.append(processCpuTracker.printCurrentLoad());
4987            info.append(cpuInfo);
4988        }
4989
4990        info.append(processCpuTracker.printCurrentState(anrTime));
4991
4992        Slog.e(TAG, info.toString());
4993        if (tracesFile == null) {
4994            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4995            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4996        }
4997
4998        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4999                cpuInfo, tracesFile, null);
5000
5001        if (mController != null) {
5002            try {
5003                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5004                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5005                if (res != 0) {
5006                    if (res < 0 && app.pid != MY_PID) {
5007                        app.kill("anr", true);
5008                    } else {
5009                        synchronized (this) {
5010                            mServices.scheduleServiceTimeoutLocked(app);
5011                        }
5012                    }
5013                    return;
5014                }
5015            } catch (RemoteException e) {
5016                mController = null;
5017                Watchdog.getInstance().setActivityController(null);
5018            }
5019        }
5020
5021        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5022        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5023                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5024
5025        synchronized (this) {
5026            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5027
5028            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5029                app.kill("bg anr", true);
5030                return;
5031            }
5032
5033            // Set the app's notResponding state, and look up the errorReportReceiver
5034            makeAppNotRespondingLocked(app,
5035                    activity != null ? activity.shortComponentName : null,
5036                    annotation != null ? "ANR " + annotation : "ANR",
5037                    info.toString());
5038
5039            // Bring up the infamous App Not Responding dialog
5040            Message msg = Message.obtain();
5041            HashMap<String, Object> map = new HashMap<String, Object>();
5042            msg.what = SHOW_NOT_RESPONDING_MSG;
5043            msg.obj = map;
5044            msg.arg1 = aboveSystem ? 1 : 0;
5045            map.put("app", app);
5046            if (activity != null) {
5047                map.put("activity", activity);
5048            }
5049
5050            mUiHandler.sendMessage(msg);
5051        }
5052    }
5053
5054    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5055        if (!mLaunchWarningShown) {
5056            mLaunchWarningShown = true;
5057            mUiHandler.post(new Runnable() {
5058                @Override
5059                public void run() {
5060                    synchronized (ActivityManagerService.this) {
5061                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5062                        d.show();
5063                        mUiHandler.postDelayed(new Runnable() {
5064                            @Override
5065                            public void run() {
5066                                synchronized (ActivityManagerService.this) {
5067                                    d.dismiss();
5068                                    mLaunchWarningShown = false;
5069                                }
5070                            }
5071                        }, 4000);
5072                    }
5073                }
5074            });
5075        }
5076    }
5077
5078    @Override
5079    public boolean clearApplicationUserData(final String packageName,
5080            final IPackageDataObserver observer, int userId) {
5081        enforceNotIsolatedCaller("clearApplicationUserData");
5082        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5083            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5084        }
5085        int uid = Binder.getCallingUid();
5086        int pid = Binder.getCallingPid();
5087        userId = handleIncomingUser(pid, uid,
5088                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5089        long callingId = Binder.clearCallingIdentity();
5090        try {
5091            IPackageManager pm = AppGlobals.getPackageManager();
5092            int pkgUid = -1;
5093            synchronized(this) {
5094                try {
5095                    pkgUid = pm.getPackageUid(packageName, userId);
5096                } catch (RemoteException e) {
5097                }
5098                if (pkgUid == -1) {
5099                    Slog.w(TAG, "Invalid packageName: " + packageName);
5100                    if (observer != null) {
5101                        try {
5102                            observer.onRemoveCompleted(packageName, false);
5103                        } catch (RemoteException e) {
5104                            Slog.i(TAG, "Observer no longer exists.");
5105                        }
5106                    }
5107                    return false;
5108                }
5109                if (uid == pkgUid || checkComponentPermission(
5110                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5111                        pid, uid, -1, true)
5112                        == PackageManager.PERMISSION_GRANTED) {
5113                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5114                } else {
5115                    throw new SecurityException("PID " + pid + " does not have permission "
5116                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5117                                    + " of package " + packageName);
5118                }
5119
5120                // Remove all tasks match the cleared application package and user
5121                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5122                    final TaskRecord tr = mRecentTasks.get(i);
5123                    final String taskPackageName =
5124                            tr.getBaseIntent().getComponent().getPackageName();
5125                    if (tr.userId != userId) continue;
5126                    if (!taskPackageName.equals(packageName)) continue;
5127                    removeTaskByIdLocked(tr.taskId, false);
5128                }
5129            }
5130
5131            try {
5132                // Clear application user data
5133                pm.clearApplicationUserData(packageName, observer, userId);
5134
5135                synchronized(this) {
5136                    // Remove all permissions granted from/to this package
5137                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5138                }
5139
5140                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5141                        Uri.fromParts("package", packageName, null));
5142                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5143                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5144                        null, null, 0, null, null, null, null, false, false, userId);
5145            } catch (RemoteException e) {
5146            }
5147        } finally {
5148            Binder.restoreCallingIdentity(callingId);
5149        }
5150        return true;
5151    }
5152
5153    @Override
5154    public void killBackgroundProcesses(final String packageName, int userId) {
5155        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5156                != PackageManager.PERMISSION_GRANTED &&
5157                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5158                        != PackageManager.PERMISSION_GRANTED) {
5159            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5160                    + Binder.getCallingPid()
5161                    + ", uid=" + Binder.getCallingUid()
5162                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5163            Slog.w(TAG, msg);
5164            throw new SecurityException(msg);
5165        }
5166
5167        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5168                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5169        long callingId = Binder.clearCallingIdentity();
5170        try {
5171            IPackageManager pm = AppGlobals.getPackageManager();
5172            synchronized(this) {
5173                int appId = -1;
5174                try {
5175                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5176                } catch (RemoteException e) {
5177                }
5178                if (appId == -1) {
5179                    Slog.w(TAG, "Invalid packageName: " + packageName);
5180                    return;
5181                }
5182                killPackageProcessesLocked(packageName, appId, userId,
5183                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5184            }
5185        } finally {
5186            Binder.restoreCallingIdentity(callingId);
5187        }
5188    }
5189
5190    @Override
5191    public void killAllBackgroundProcesses() {
5192        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5193                != PackageManager.PERMISSION_GRANTED) {
5194            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5195                    + Binder.getCallingPid()
5196                    + ", uid=" + Binder.getCallingUid()
5197                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5198            Slog.w(TAG, msg);
5199            throw new SecurityException(msg);
5200        }
5201
5202        long callingId = Binder.clearCallingIdentity();
5203        try {
5204            synchronized(this) {
5205                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5206                final int NP = mProcessNames.getMap().size();
5207                for (int ip=0; ip<NP; ip++) {
5208                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5209                    final int NA = apps.size();
5210                    for (int ia=0; ia<NA; ia++) {
5211                        ProcessRecord app = apps.valueAt(ia);
5212                        if (app.persistent) {
5213                            // we don't kill persistent processes
5214                            continue;
5215                        }
5216                        if (app.removed) {
5217                            procs.add(app);
5218                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5219                            app.removed = true;
5220                            procs.add(app);
5221                        }
5222                    }
5223                }
5224
5225                int N = procs.size();
5226                for (int i=0; i<N; i++) {
5227                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5228                }
5229                mAllowLowerMemLevel = true;
5230                updateOomAdjLocked();
5231                doLowMemReportIfNeededLocked(null);
5232            }
5233        } finally {
5234            Binder.restoreCallingIdentity(callingId);
5235        }
5236    }
5237
5238    @Override
5239    public void forceStopPackage(final String packageName, int userId) {
5240        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5241                != PackageManager.PERMISSION_GRANTED) {
5242            String msg = "Permission Denial: forceStopPackage() from pid="
5243                    + Binder.getCallingPid()
5244                    + ", uid=" + Binder.getCallingUid()
5245                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5246            Slog.w(TAG, msg);
5247            throw new SecurityException(msg);
5248        }
5249        final int callingPid = Binder.getCallingPid();
5250        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5251                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5252        long callingId = Binder.clearCallingIdentity();
5253        try {
5254            IPackageManager pm = AppGlobals.getPackageManager();
5255            synchronized(this) {
5256                int[] users = userId == UserHandle.USER_ALL
5257                        ? getUsersLocked() : new int[] { userId };
5258                for (int user : users) {
5259                    int pkgUid = -1;
5260                    try {
5261                        pkgUid = pm.getPackageUid(packageName, user);
5262                    } catch (RemoteException e) {
5263                    }
5264                    if (pkgUid == -1) {
5265                        Slog.w(TAG, "Invalid packageName: " + packageName);
5266                        continue;
5267                    }
5268                    try {
5269                        pm.setPackageStoppedState(packageName, true, user);
5270                    } catch (RemoteException e) {
5271                    } catch (IllegalArgumentException e) {
5272                        Slog.w(TAG, "Failed trying to unstop package "
5273                                + packageName + ": " + e);
5274                    }
5275                    if (isUserRunningLocked(user, false)) {
5276                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5277                    }
5278                }
5279            }
5280        } finally {
5281            Binder.restoreCallingIdentity(callingId);
5282        }
5283    }
5284
5285    @Override
5286    public void addPackageDependency(String packageName) {
5287        synchronized (this) {
5288            int callingPid = Binder.getCallingPid();
5289            if (callingPid == Process.myPid()) {
5290                //  Yeah, um, no.
5291                return;
5292            }
5293            ProcessRecord proc;
5294            synchronized (mPidsSelfLocked) {
5295                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5296            }
5297            if (proc != null) {
5298                if (proc.pkgDeps == null) {
5299                    proc.pkgDeps = new ArraySet<String>(1);
5300                }
5301                proc.pkgDeps.add(packageName);
5302            }
5303        }
5304    }
5305
5306    /*
5307     * The pkg name and app id have to be specified.
5308     */
5309    @Override
5310    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5311        if (pkg == null) {
5312            return;
5313        }
5314        // Make sure the uid is valid.
5315        if (appid < 0) {
5316            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5317            return;
5318        }
5319        int callerUid = Binder.getCallingUid();
5320        // Only the system server can kill an application
5321        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5322            // Post an aysnc message to kill the application
5323            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5324            msg.arg1 = appid;
5325            msg.arg2 = 0;
5326            Bundle bundle = new Bundle();
5327            bundle.putString("pkg", pkg);
5328            bundle.putString("reason", reason);
5329            msg.obj = bundle;
5330            mHandler.sendMessage(msg);
5331        } else {
5332            throw new SecurityException(callerUid + " cannot kill pkg: " +
5333                    pkg);
5334        }
5335    }
5336
5337    @Override
5338    public void closeSystemDialogs(String reason) {
5339        enforceNotIsolatedCaller("closeSystemDialogs");
5340
5341        final int pid = Binder.getCallingPid();
5342        final int uid = Binder.getCallingUid();
5343        final long origId = Binder.clearCallingIdentity();
5344        try {
5345            synchronized (this) {
5346                // Only allow this from foreground processes, so that background
5347                // applications can't abuse it to prevent system UI from being shown.
5348                if (uid >= Process.FIRST_APPLICATION_UID) {
5349                    ProcessRecord proc;
5350                    synchronized (mPidsSelfLocked) {
5351                        proc = mPidsSelfLocked.get(pid);
5352                    }
5353                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5354                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5355                                + " from background process " + proc);
5356                        return;
5357                    }
5358                }
5359                closeSystemDialogsLocked(reason);
5360            }
5361        } finally {
5362            Binder.restoreCallingIdentity(origId);
5363        }
5364    }
5365
5366    void closeSystemDialogsLocked(String reason) {
5367        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5368        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5369                | Intent.FLAG_RECEIVER_FOREGROUND);
5370        if (reason != null) {
5371            intent.putExtra("reason", reason);
5372        }
5373        mWindowManager.closeSystemDialogs(reason);
5374
5375        mStackSupervisor.closeSystemDialogsLocked();
5376
5377        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5378                AppOpsManager.OP_NONE, null, false, false,
5379                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5380    }
5381
5382    @Override
5383    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5384        enforceNotIsolatedCaller("getProcessMemoryInfo");
5385        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5386        for (int i=pids.length-1; i>=0; i--) {
5387            ProcessRecord proc;
5388            int oomAdj;
5389            synchronized (this) {
5390                synchronized (mPidsSelfLocked) {
5391                    proc = mPidsSelfLocked.get(pids[i]);
5392                    oomAdj = proc != null ? proc.setAdj : 0;
5393                }
5394            }
5395            infos[i] = new Debug.MemoryInfo();
5396            Debug.getMemoryInfo(pids[i], infos[i]);
5397            if (proc != null) {
5398                synchronized (this) {
5399                    if (proc.thread != null && proc.setAdj == oomAdj) {
5400                        // Record this for posterity if the process has been stable.
5401                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5402                                infos[i].getTotalUss(), false, proc.pkgList);
5403                    }
5404                }
5405            }
5406        }
5407        return infos;
5408    }
5409
5410    @Override
5411    public long[] getProcessPss(int[] pids) {
5412        enforceNotIsolatedCaller("getProcessPss");
5413        long[] pss = new long[pids.length];
5414        for (int i=pids.length-1; i>=0; i--) {
5415            ProcessRecord proc;
5416            int oomAdj;
5417            synchronized (this) {
5418                synchronized (mPidsSelfLocked) {
5419                    proc = mPidsSelfLocked.get(pids[i]);
5420                    oomAdj = proc != null ? proc.setAdj : 0;
5421                }
5422            }
5423            long[] tmpUss = new long[1];
5424            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5425            if (proc != null) {
5426                synchronized (this) {
5427                    if (proc.thread != null && proc.setAdj == oomAdj) {
5428                        // Record this for posterity if the process has been stable.
5429                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5430                    }
5431                }
5432            }
5433        }
5434        return pss;
5435    }
5436
5437    @Override
5438    public void killApplicationProcess(String processName, int uid) {
5439        if (processName == null) {
5440            return;
5441        }
5442
5443        int callerUid = Binder.getCallingUid();
5444        // Only the system server can kill an application
5445        if (callerUid == Process.SYSTEM_UID) {
5446            synchronized (this) {
5447                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5448                if (app != null && app.thread != null) {
5449                    try {
5450                        app.thread.scheduleSuicide();
5451                    } catch (RemoteException e) {
5452                        // If the other end already died, then our work here is done.
5453                    }
5454                } else {
5455                    Slog.w(TAG, "Process/uid not found attempting kill of "
5456                            + processName + " / " + uid);
5457                }
5458            }
5459        } else {
5460            throw new SecurityException(callerUid + " cannot kill app process: " +
5461                    processName);
5462        }
5463    }
5464
5465    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5466        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5467                false, true, false, false, UserHandle.getUserId(uid), reason);
5468        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5469                Uri.fromParts("package", packageName, null));
5470        if (!mProcessesReady) {
5471            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5472                    | Intent.FLAG_RECEIVER_FOREGROUND);
5473        }
5474        intent.putExtra(Intent.EXTRA_UID, uid);
5475        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5476        broadcastIntentLocked(null, null, intent,
5477                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5478                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5479    }
5480
5481    private void forceStopUserLocked(int userId, String reason) {
5482        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5483        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5484        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5485                | Intent.FLAG_RECEIVER_FOREGROUND);
5486        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5487        broadcastIntentLocked(null, null, intent,
5488                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5489                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5490    }
5491
5492    private final boolean killPackageProcessesLocked(String packageName, int appId,
5493            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5494            boolean doit, boolean evenPersistent, String reason) {
5495        ArrayList<ProcessRecord> procs = new ArrayList<>();
5496
5497        // Remove all processes this package may have touched: all with the
5498        // same UID (except for the system or root user), and all whose name
5499        // matches the package name.
5500        final int NP = mProcessNames.getMap().size();
5501        for (int ip=0; ip<NP; ip++) {
5502            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5503            final int NA = apps.size();
5504            for (int ia=0; ia<NA; ia++) {
5505                ProcessRecord app = apps.valueAt(ia);
5506                if (app.persistent && !evenPersistent) {
5507                    // we don't kill persistent processes
5508                    continue;
5509                }
5510                if (app.removed) {
5511                    if (doit) {
5512                        procs.add(app);
5513                    }
5514                    continue;
5515                }
5516
5517                // Skip process if it doesn't meet our oom adj requirement.
5518                if (app.setAdj < minOomAdj) {
5519                    continue;
5520                }
5521
5522                // If no package is specified, we call all processes under the
5523                // give user id.
5524                if (packageName == null) {
5525                    if (app.userId != userId) {
5526                        continue;
5527                    }
5528                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5529                        continue;
5530                    }
5531                // Package has been specified, we want to hit all processes
5532                // that match it.  We need to qualify this by the processes
5533                // that are running under the specified app and user ID.
5534                } else {
5535                    final boolean isDep = app.pkgDeps != null
5536                            && app.pkgDeps.contains(packageName);
5537                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5538                        continue;
5539                    }
5540                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5541                        continue;
5542                    }
5543                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5544                        continue;
5545                    }
5546                }
5547
5548                // Process has passed all conditions, kill it!
5549                if (!doit) {
5550                    return true;
5551                }
5552                app.removed = true;
5553                procs.add(app);
5554            }
5555        }
5556
5557        int N = procs.size();
5558        for (int i=0; i<N; i++) {
5559            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5560        }
5561        updateOomAdjLocked();
5562        return N > 0;
5563    }
5564
5565    private void cleanupDisabledPackageComponentsLocked(
5566            String packageName, int userId, String[] changedClasses) {
5567
5568        Set<String> disabledClasses = null;
5569        boolean packageDisabled = false;
5570        IPackageManager pm = AppGlobals.getPackageManager();
5571
5572        if (changedClasses == null) {
5573            // Nothing changed...
5574            return;
5575        }
5576
5577        // Determine enable/disable state of the package and its components.
5578        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5579        for (int i = changedClasses.length - 1; i >= 0; i--) {
5580            final String changedClass = changedClasses[i];
5581
5582            if (changedClass.equals(packageName)) {
5583                try {
5584                    // Entire package setting changed
5585                    enabled = pm.getApplicationEnabledSetting(packageName,
5586                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5587                } catch (Exception e) {
5588                    // No such package/component; probably racing with uninstall.  In any
5589                    // event it means we have nothing further to do here.
5590                    return;
5591                }
5592                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5593                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5594                if (packageDisabled) {
5595                    // Entire package is disabled.
5596                    // No need to continue to check component states.
5597                    disabledClasses = null;
5598                    break;
5599                }
5600            } else {
5601                try {
5602                    enabled = pm.getComponentEnabledSetting(
5603                            new ComponentName(packageName, changedClass),
5604                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5605                } catch (Exception e) {
5606                    // As above, probably racing with uninstall.
5607                    return;
5608                }
5609                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5610                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5611                    if (disabledClasses == null) {
5612                        disabledClasses = new ArraySet<>(changedClasses.length);
5613                    }
5614                    disabledClasses.add(changedClass);
5615                }
5616            }
5617        }
5618
5619        if (!packageDisabled && disabledClasses == null) {
5620            // Nothing to do here...
5621            return;
5622        }
5623
5624        // Clean-up disabled activities.
5625        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5626                packageName, disabledClasses, true, false, userId) && mBooted) {
5627            mStackSupervisor.resumeTopActivitiesLocked();
5628            mStackSupervisor.scheduleIdleLocked();
5629        }
5630
5631        // Clean-up disabled tasks
5632        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5633
5634        // Clean-up disabled services.
5635        mServices.bringDownDisabledPackageServicesLocked(
5636                packageName, disabledClasses, userId, false, true);
5637
5638        // Clean-up disabled providers.
5639        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5640        mProviderMap.collectPackageProvidersLocked(
5641                packageName, disabledClasses, true, false, userId, providers);
5642        for (int i = providers.size() - 1; i >= 0; i--) {
5643            removeDyingProviderLocked(null, providers.get(i), true);
5644        }
5645
5646        // Clean-up disabled broadcast receivers.
5647        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5648            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5649                    packageName, disabledClasses, userId, true);
5650        }
5651
5652    }
5653
5654    private final boolean forceStopPackageLocked(String packageName, int appId,
5655            boolean callerWillRestart, boolean purgeCache, boolean doit,
5656            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5657        int i;
5658
5659        if (userId == UserHandle.USER_ALL && packageName == null) {
5660            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5661        }
5662
5663        if (appId < 0 && packageName != null) {
5664            try {
5665                appId = UserHandle.getAppId(
5666                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5667            } catch (RemoteException e) {
5668            }
5669        }
5670
5671        if (doit) {
5672            if (packageName != null) {
5673                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5674                        + " user=" + userId + ": " + reason);
5675            } else {
5676                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5677            }
5678
5679            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5680            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5681                SparseArray<Long> ba = pmap.valueAt(ip);
5682                for (i = ba.size() - 1; i >= 0; i--) {
5683                    boolean remove = false;
5684                    final int entUid = ba.keyAt(i);
5685                    if (packageName != null) {
5686                        if (userId == UserHandle.USER_ALL) {
5687                            if (UserHandle.getAppId(entUid) == appId) {
5688                                remove = true;
5689                            }
5690                        } else {
5691                            if (entUid == UserHandle.getUid(userId, appId)) {
5692                                remove = true;
5693                            }
5694                        }
5695                    } else if (UserHandle.getUserId(entUid) == userId) {
5696                        remove = true;
5697                    }
5698                    if (remove) {
5699                        ba.removeAt(i);
5700                    }
5701                }
5702                if (ba.size() == 0) {
5703                    pmap.removeAt(ip);
5704                }
5705            }
5706        }
5707
5708        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5709                -100, callerWillRestart, true, doit, evenPersistent,
5710                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5711
5712        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5713                packageName, null, doit, evenPersistent, userId)) {
5714            if (!doit) {
5715                return true;
5716            }
5717            didSomething = true;
5718        }
5719
5720        if (mServices.bringDownDisabledPackageServicesLocked(
5721                packageName, null, userId, evenPersistent, doit)) {
5722            if (!doit) {
5723                return true;
5724            }
5725            didSomething = true;
5726        }
5727
5728        if (packageName == null) {
5729            // Remove all sticky broadcasts from this user.
5730            mStickyBroadcasts.remove(userId);
5731        }
5732
5733        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5734        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5735                userId, providers)) {
5736            if (!doit) {
5737                return true;
5738            }
5739            didSomething = true;
5740        }
5741        for (i = providers.size() - 1; i >= 0; i--) {
5742            removeDyingProviderLocked(null, providers.get(i), true);
5743        }
5744
5745        // Remove transient permissions granted from/to this package/user
5746        removeUriPermissionsForPackageLocked(packageName, userId, false);
5747
5748        if (doit) {
5749            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5750                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5751                        packageName, null, userId, doit);
5752            }
5753        }
5754
5755        if (packageName == null || uninstalling) {
5756            // Remove pending intents.  For now we only do this when force
5757            // stopping users, because we have some problems when doing this
5758            // for packages -- app widgets are not currently cleaned up for
5759            // such packages, so they can be left with bad pending intents.
5760            if (mIntentSenderRecords.size() > 0) {
5761                Iterator<WeakReference<PendingIntentRecord>> it
5762                        = mIntentSenderRecords.values().iterator();
5763                while (it.hasNext()) {
5764                    WeakReference<PendingIntentRecord> wpir = it.next();
5765                    if (wpir == null) {
5766                        it.remove();
5767                        continue;
5768                    }
5769                    PendingIntentRecord pir = wpir.get();
5770                    if (pir == null) {
5771                        it.remove();
5772                        continue;
5773                    }
5774                    if (packageName == null) {
5775                        // Stopping user, remove all objects for the user.
5776                        if (pir.key.userId != userId) {
5777                            // Not the same user, skip it.
5778                            continue;
5779                        }
5780                    } else {
5781                        if (UserHandle.getAppId(pir.uid) != appId) {
5782                            // Different app id, skip it.
5783                            continue;
5784                        }
5785                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5786                            // Different user, skip it.
5787                            continue;
5788                        }
5789                        if (!pir.key.packageName.equals(packageName)) {
5790                            // Different package, skip it.
5791                            continue;
5792                        }
5793                    }
5794                    if (!doit) {
5795                        return true;
5796                    }
5797                    didSomething = true;
5798                    it.remove();
5799                    pir.canceled = true;
5800                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5801                        pir.key.activity.pendingResults.remove(pir.ref);
5802                    }
5803                }
5804            }
5805        }
5806
5807        if (doit) {
5808            if (purgeCache && packageName != null) {
5809                AttributeCache ac = AttributeCache.instance();
5810                if (ac != null) {
5811                    ac.removePackage(packageName);
5812                }
5813            }
5814            if (mBooted) {
5815                mStackSupervisor.resumeTopActivitiesLocked();
5816                mStackSupervisor.scheduleIdleLocked();
5817            }
5818        }
5819
5820        return didSomething;
5821    }
5822
5823    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5824        ProcessRecord old = mProcessNames.remove(name, uid);
5825        if (old != null) {
5826            old.uidRecord.numProcs--;
5827            if (old.uidRecord.numProcs == 0) {
5828                // No more processes using this uid, tell clients it is gone.
5829                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5830                        "No more processes in " + old.uidRecord);
5831                enqueueUidChangeLocked(old.uidRecord, true);
5832                mActiveUids.remove(uid);
5833            }
5834            old.uidRecord = null;
5835        }
5836        mIsolatedProcesses.remove(uid);
5837        return old;
5838    }
5839
5840    private final void addProcessNameLocked(ProcessRecord proc) {
5841        // We shouldn't already have a process under this name, but just in case we
5842        // need to clean up whatever may be there now.
5843        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5844        if (old != null) {
5845            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5846        }
5847        UidRecord uidRec = mActiveUids.get(proc.uid);
5848        if (uidRec == null) {
5849            uidRec = new UidRecord(proc.uid);
5850            // This is the first appearance of the uid, report it now!
5851            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5852                    "Creating new process uid: " + uidRec);
5853            mActiveUids.put(proc.uid, uidRec);
5854            enqueueUidChangeLocked(uidRec, false);
5855        }
5856        proc.uidRecord = uidRec;
5857        uidRec.numProcs++;
5858        mProcessNames.put(proc.processName, proc.uid, proc);
5859        if (proc.isolated) {
5860            mIsolatedProcesses.put(proc.uid, proc);
5861        }
5862    }
5863
5864    private final boolean removeProcessLocked(ProcessRecord app,
5865            boolean callerWillRestart, boolean allowRestart, String reason) {
5866        final String name = app.processName;
5867        final int uid = app.uid;
5868        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5869            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5870
5871        removeProcessNameLocked(name, uid);
5872        if (mHeavyWeightProcess == app) {
5873            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5874                    mHeavyWeightProcess.userId, 0));
5875            mHeavyWeightProcess = null;
5876        }
5877        boolean needRestart = false;
5878        if (app.pid > 0 && app.pid != MY_PID) {
5879            int pid = app.pid;
5880            synchronized (mPidsSelfLocked) {
5881                mPidsSelfLocked.remove(pid);
5882                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5883            }
5884            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5885            if (app.isolated) {
5886                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5887            }
5888            boolean willRestart = false;
5889            if (app.persistent && !app.isolated) {
5890                if (!callerWillRestart) {
5891                    willRestart = true;
5892                } else {
5893                    needRestart = true;
5894                }
5895            }
5896            app.kill(reason, true);
5897            handleAppDiedLocked(app, willRestart, allowRestart);
5898            if (willRestart) {
5899                removeLruProcessLocked(app);
5900                addAppLocked(app.info, false, null /* ABI override */);
5901            }
5902        } else {
5903            mRemovedProcesses.add(app);
5904        }
5905
5906        return needRestart;
5907    }
5908
5909    private final void processStartTimedOutLocked(ProcessRecord app) {
5910        final int pid = app.pid;
5911        boolean gone = false;
5912        synchronized (mPidsSelfLocked) {
5913            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5914            if (knownApp != null && knownApp.thread == null) {
5915                mPidsSelfLocked.remove(pid);
5916                gone = true;
5917            }
5918        }
5919
5920        if (gone) {
5921            Slog.w(TAG, "Process " + app + " failed to attach");
5922            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5923                    pid, app.uid, app.processName);
5924            removeProcessNameLocked(app.processName, app.uid);
5925            if (mHeavyWeightProcess == app) {
5926                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5927                        mHeavyWeightProcess.userId, 0));
5928                mHeavyWeightProcess = null;
5929            }
5930            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5931            if (app.isolated) {
5932                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5933            }
5934            // Take care of any launching providers waiting for this process.
5935            checkAppInLaunchingProvidersLocked(app, true);
5936            // Take care of any services that are waiting for the process.
5937            mServices.processStartTimedOutLocked(app);
5938            app.kill("start timeout", true);
5939            removeLruProcessLocked(app);
5940            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5941                Slog.w(TAG, "Unattached app died before backup, skipping");
5942                try {
5943                    IBackupManager bm = IBackupManager.Stub.asInterface(
5944                            ServiceManager.getService(Context.BACKUP_SERVICE));
5945                    bm.agentDisconnected(app.info.packageName);
5946                } catch (RemoteException e) {
5947                    // Can't happen; the backup manager is local
5948                }
5949            }
5950            if (isPendingBroadcastProcessLocked(pid)) {
5951                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5952                skipPendingBroadcastLocked(pid);
5953            }
5954        } else {
5955            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5956        }
5957    }
5958
5959    private final boolean attachApplicationLocked(IApplicationThread thread,
5960            int pid) {
5961
5962        // Find the application record that is being attached...  either via
5963        // the pid if we are running in multiple processes, or just pull the
5964        // next app record if we are emulating process with anonymous threads.
5965        ProcessRecord app;
5966        if (pid != MY_PID && pid >= 0) {
5967            synchronized (mPidsSelfLocked) {
5968                app = mPidsSelfLocked.get(pid);
5969            }
5970        } else {
5971            app = null;
5972        }
5973
5974        if (app == null) {
5975            Slog.w(TAG, "No pending application record for pid " + pid
5976                    + " (IApplicationThread " + thread + "); dropping process");
5977            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5978            if (pid > 0 && pid != MY_PID) {
5979                Process.killProcessQuiet(pid);
5980                //TODO: killProcessGroup(app.info.uid, pid);
5981            } else {
5982                try {
5983                    thread.scheduleExit();
5984                } catch (Exception e) {
5985                    // Ignore exceptions.
5986                }
5987            }
5988            return false;
5989        }
5990
5991        // If this application record is still attached to a previous
5992        // process, clean it up now.
5993        if (app.thread != null) {
5994            handleAppDiedLocked(app, true, true);
5995        }
5996
5997        // Tell the process all about itself.
5998
5999        if (DEBUG_ALL) Slog.v(
6000                TAG, "Binding process pid " + pid + " to record " + app);
6001
6002        final String processName = app.processName;
6003        try {
6004            AppDeathRecipient adr = new AppDeathRecipient(
6005                    app, pid, thread);
6006            thread.asBinder().linkToDeath(adr, 0);
6007            app.deathRecipient = adr;
6008        } catch (RemoteException e) {
6009            app.resetPackageList(mProcessStats);
6010            startProcessLocked(app, "link fail", processName);
6011            return false;
6012        }
6013
6014        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6015
6016        app.makeActive(thread, mProcessStats);
6017        app.curAdj = app.setAdj = -100;
6018        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6019        app.forcingToForeground = null;
6020        updateProcessForegroundLocked(app, false, false);
6021        app.hasShownUi = false;
6022        app.debugging = false;
6023        app.cached = false;
6024        app.killedByAm = false;
6025
6026        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6027
6028        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6029        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6030
6031        if (!normalMode) {
6032            Slog.i(TAG, "Launching preboot mode app: " + app);
6033        }
6034
6035        if (DEBUG_ALL) Slog.v(
6036            TAG, "New app record " + app
6037            + " thread=" + thread.asBinder() + " pid=" + pid);
6038        try {
6039            int testMode = IApplicationThread.DEBUG_OFF;
6040            if (mDebugApp != null && mDebugApp.equals(processName)) {
6041                testMode = mWaitForDebugger
6042                    ? IApplicationThread.DEBUG_WAIT
6043                    : IApplicationThread.DEBUG_ON;
6044                app.debugging = true;
6045                if (mDebugTransient) {
6046                    mDebugApp = mOrigDebugApp;
6047                    mWaitForDebugger = mOrigWaitForDebugger;
6048                }
6049            }
6050            String profileFile = app.instrumentationProfileFile;
6051            ParcelFileDescriptor profileFd = null;
6052            int samplingInterval = 0;
6053            boolean profileAutoStop = false;
6054            if (mProfileApp != null && mProfileApp.equals(processName)) {
6055                mProfileProc = app;
6056                profileFile = mProfileFile;
6057                profileFd = mProfileFd;
6058                samplingInterval = mSamplingInterval;
6059                profileAutoStop = mAutoStopProfiler;
6060            }
6061            boolean enableOpenGlTrace = false;
6062            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6063                enableOpenGlTrace = true;
6064                mOpenGlTraceApp = null;
6065            }
6066            boolean enableTrackAllocation = false;
6067            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6068                enableTrackAllocation = true;
6069                mTrackAllocationApp = null;
6070            }
6071
6072            // If the app is being launched for restore or full backup, set it up specially
6073            boolean isRestrictedBackupMode = false;
6074            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6075                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6076                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6077                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6078            }
6079
6080            ensurePackageDexOpt(app.instrumentationInfo != null
6081                    ? app.instrumentationInfo.packageName
6082                    : app.info.packageName);
6083            if (app.instrumentationClass != null) {
6084                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6085            }
6086            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6087                    + processName + " with config " + mConfiguration);
6088            ApplicationInfo appInfo = app.instrumentationInfo != null
6089                    ? app.instrumentationInfo : app.info;
6090            app.compat = compatibilityInfoForPackageLocked(appInfo);
6091            if (profileFd != null) {
6092                profileFd = profileFd.dup();
6093            }
6094            ProfilerInfo profilerInfo = profileFile == null ? null
6095                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6096            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6097                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6098                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6099                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
6100                    new Configuration(mConfiguration), app.compat,
6101                    getCommonServicesLocked(app.isolated),
6102                    mCoreSettingsObserver.getCoreSettingsLocked());
6103            updateLruProcessLocked(app, false, null);
6104            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6105        } catch (Exception e) {
6106            // todo: Yikes!  What should we do?  For now we will try to
6107            // start another process, but that could easily get us in
6108            // an infinite loop of restarting processes...
6109            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6110
6111            app.resetPackageList(mProcessStats);
6112            app.unlinkDeathRecipient();
6113            startProcessLocked(app, "bind fail", processName);
6114            return false;
6115        }
6116
6117        // Remove this record from the list of starting applications.
6118        mPersistentStartingProcesses.remove(app);
6119        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6120                "Attach application locked removing on hold: " + app);
6121        mProcessesOnHold.remove(app);
6122
6123        boolean badApp = false;
6124        boolean didSomething = false;
6125
6126        // See if the top visible activity is waiting to run in this process...
6127        if (normalMode) {
6128            try {
6129                if (mStackSupervisor.attachApplicationLocked(app)) {
6130                    didSomething = true;
6131                }
6132            } catch (Exception e) {
6133                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6134                badApp = true;
6135            }
6136        }
6137
6138        // Find any services that should be running in this process...
6139        if (!badApp) {
6140            try {
6141                didSomething |= mServices.attachApplicationLocked(app, processName);
6142            } catch (Exception e) {
6143                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6144                badApp = true;
6145            }
6146        }
6147
6148        // Check if a next-broadcast receiver is in this process...
6149        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6150            try {
6151                didSomething |= sendPendingBroadcastsLocked(app);
6152            } catch (Exception e) {
6153                // If the app died trying to launch the receiver we declare it 'bad'
6154                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6155                badApp = true;
6156            }
6157        }
6158
6159        // Check whether the next backup agent is in this process...
6160        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6161            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6162                    "New app is backup target, launching agent for " + app);
6163            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6164            try {
6165                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6166                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6167                        mBackupTarget.backupMode);
6168            } catch (Exception e) {
6169                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6170                badApp = true;
6171            }
6172        }
6173
6174        if (badApp) {
6175            app.kill("error during init", true);
6176            handleAppDiedLocked(app, false, true);
6177            return false;
6178        }
6179
6180        if (!didSomething) {
6181            updateOomAdjLocked();
6182        }
6183
6184        return true;
6185    }
6186
6187    @Override
6188    public final void attachApplication(IApplicationThread thread) {
6189        synchronized (this) {
6190            int callingPid = Binder.getCallingPid();
6191            final long origId = Binder.clearCallingIdentity();
6192            attachApplicationLocked(thread, callingPid);
6193            Binder.restoreCallingIdentity(origId);
6194        }
6195    }
6196
6197    @Override
6198    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6199        final long origId = Binder.clearCallingIdentity();
6200        synchronized (this) {
6201            ActivityStack stack = ActivityRecord.getStackLocked(token);
6202            if (stack != null) {
6203                ActivityRecord r =
6204                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6205                if (stopProfiling) {
6206                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6207                        try {
6208                            mProfileFd.close();
6209                        } catch (IOException e) {
6210                        }
6211                        clearProfilerLocked();
6212                    }
6213                }
6214            }
6215        }
6216        Binder.restoreCallingIdentity(origId);
6217    }
6218
6219    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6220        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6221                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6222    }
6223
6224    void enableScreenAfterBoot() {
6225        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6226                SystemClock.uptimeMillis());
6227        mWindowManager.enableScreenAfterBoot();
6228
6229        synchronized (this) {
6230            updateEventDispatchingLocked();
6231        }
6232    }
6233
6234    @Override
6235    public void showBootMessage(final CharSequence msg, final boolean always) {
6236        if (Binder.getCallingUid() != Process.myUid()) {
6237            // These days only the core system can call this, so apps can't get in
6238            // the way of what we show about running them.
6239        }
6240        mWindowManager.showBootMessage(msg, always);
6241    }
6242
6243    @Override
6244    public void keyguardWaitingForActivityDrawn() {
6245        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6246        final long token = Binder.clearCallingIdentity();
6247        try {
6248            synchronized (this) {
6249                if (DEBUG_LOCKSCREEN) logLockScreen("");
6250                mWindowManager.keyguardWaitingForActivityDrawn();
6251                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6252                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6253                    updateSleepIfNeededLocked();
6254                }
6255            }
6256        } finally {
6257            Binder.restoreCallingIdentity(token);
6258        }
6259    }
6260
6261    @Override
6262    public void keyguardGoingAway(boolean disableWindowAnimations,
6263            boolean keyguardGoingToNotificationShade) {
6264        enforceNotIsolatedCaller("keyguardGoingAway");
6265        final long token = Binder.clearCallingIdentity();
6266        try {
6267            synchronized (this) {
6268                if (DEBUG_LOCKSCREEN) logLockScreen("");
6269                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6270                        keyguardGoingToNotificationShade);
6271                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6272                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6273                    updateSleepIfNeededLocked();
6274                }
6275            }
6276        } finally {
6277            Binder.restoreCallingIdentity(token);
6278        }
6279    }
6280
6281    final void finishBooting() {
6282        synchronized (this) {
6283            if (!mBootAnimationComplete) {
6284                mCallFinishBooting = true;
6285                return;
6286            }
6287            mCallFinishBooting = false;
6288        }
6289
6290        ArraySet<String> completedIsas = new ArraySet<String>();
6291        for (String abi : Build.SUPPORTED_ABIS) {
6292            Process.establishZygoteConnectionForAbi(abi);
6293            final String instructionSet = VMRuntime.getInstructionSet(abi);
6294            if (!completedIsas.contains(instructionSet)) {
6295                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6296                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6297                }
6298                completedIsas.add(instructionSet);
6299            }
6300        }
6301
6302        IntentFilter pkgFilter = new IntentFilter();
6303        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6304        pkgFilter.addDataScheme("package");
6305        mContext.registerReceiver(new BroadcastReceiver() {
6306            @Override
6307            public void onReceive(Context context, Intent intent) {
6308                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6309                if (pkgs != null) {
6310                    for (String pkg : pkgs) {
6311                        synchronized (ActivityManagerService.this) {
6312                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6313                                    0, "query restart")) {
6314                                setResultCode(Activity.RESULT_OK);
6315                                return;
6316                            }
6317                        }
6318                    }
6319                }
6320            }
6321        }, pkgFilter);
6322
6323        IntentFilter dumpheapFilter = new IntentFilter();
6324        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6325        mContext.registerReceiver(new BroadcastReceiver() {
6326            @Override
6327            public void onReceive(Context context, Intent intent) {
6328                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6329                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6330                } else {
6331                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6332                }
6333            }
6334        }, dumpheapFilter);
6335
6336        // Let system services know.
6337        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6338
6339        synchronized (this) {
6340            // Ensure that any processes we had put on hold are now started
6341            // up.
6342            final int NP = mProcessesOnHold.size();
6343            if (NP > 0) {
6344                ArrayList<ProcessRecord> procs =
6345                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6346                for (int ip=0; ip<NP; ip++) {
6347                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6348                            + procs.get(ip));
6349                    startProcessLocked(procs.get(ip), "on-hold", null);
6350                }
6351            }
6352
6353            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6354                // Start looking for apps that are abusing wake locks.
6355                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6356                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6357                // Tell anyone interested that we are done booting!
6358                SystemProperties.set("sys.boot_completed", "1");
6359
6360                // And trigger dev.bootcomplete if we are not showing encryption progress
6361                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6362                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6363                    SystemProperties.set("dev.bootcomplete", "1");
6364                }
6365                for (int i=0; i<mStartedUsers.size(); i++) {
6366                    UserState uss = mStartedUsers.valueAt(i);
6367                    if (uss.mState == UserState.STATE_BOOTING) {
6368                        uss.mState = UserState.STATE_RUNNING;
6369                        final int userId = mStartedUsers.keyAt(i);
6370                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6371                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6372                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6373                        broadcastIntentLocked(null, null, intent, null,
6374                                new IIntentReceiver.Stub() {
6375                                    @Override
6376                                    public void performReceive(Intent intent, int resultCode,
6377                                            String data, Bundle extras, boolean ordered,
6378                                            boolean sticky, int sendingUser) {
6379                                        synchronized (ActivityManagerService.this) {
6380                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6381                                                    true, false);
6382                                        }
6383                                    }
6384                                },
6385                                0, null, null,
6386                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6387                                AppOpsManager.OP_NONE, null, true, false,
6388                                MY_PID, Process.SYSTEM_UID, userId);
6389                    }
6390                }
6391                scheduleStartProfilesLocked();
6392            }
6393        }
6394    }
6395
6396    @Override
6397    public void bootAnimationComplete() {
6398        final boolean callFinishBooting;
6399        synchronized (this) {
6400            callFinishBooting = mCallFinishBooting;
6401            mBootAnimationComplete = true;
6402        }
6403        if (callFinishBooting) {
6404            finishBooting();
6405        }
6406    }
6407
6408    final void ensureBootCompleted() {
6409        boolean booting;
6410        boolean enableScreen;
6411        synchronized (this) {
6412            booting = mBooting;
6413            mBooting = false;
6414            enableScreen = !mBooted;
6415            mBooted = true;
6416        }
6417
6418        if (booting) {
6419            finishBooting();
6420        }
6421
6422        if (enableScreen) {
6423            enableScreenAfterBoot();
6424        }
6425    }
6426
6427    @Override
6428    public final void activityResumed(IBinder token) {
6429        final long origId = Binder.clearCallingIdentity();
6430        synchronized(this) {
6431            ActivityStack stack = ActivityRecord.getStackLocked(token);
6432            if (stack != null) {
6433                ActivityRecord.activityResumedLocked(token);
6434            }
6435        }
6436        Binder.restoreCallingIdentity(origId);
6437    }
6438
6439    @Override
6440    public final void activityPaused(IBinder token) {
6441        final long origId = Binder.clearCallingIdentity();
6442        synchronized(this) {
6443            ActivityStack stack = ActivityRecord.getStackLocked(token);
6444            if (stack != null) {
6445                stack.activityPausedLocked(token, false);
6446            }
6447        }
6448        Binder.restoreCallingIdentity(origId);
6449    }
6450
6451    @Override
6452    public final void activityStopped(IBinder token, Bundle icicle,
6453            PersistableBundle persistentState, CharSequence description) {
6454        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6455
6456        // Refuse possible leaked file descriptors
6457        if (icicle != null && icicle.hasFileDescriptors()) {
6458            throw new IllegalArgumentException("File descriptors passed in Bundle");
6459        }
6460
6461        final long origId = Binder.clearCallingIdentity();
6462
6463        synchronized (this) {
6464            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6465            if (r != null) {
6466                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6467            }
6468        }
6469
6470        trimApplications();
6471
6472        Binder.restoreCallingIdentity(origId);
6473    }
6474
6475    @Override
6476    public final void activityDestroyed(IBinder token) {
6477        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6478        synchronized (this) {
6479            ActivityStack stack = ActivityRecord.getStackLocked(token);
6480            if (stack != null) {
6481                stack.activityDestroyedLocked(token, "activityDestroyed");
6482            }
6483        }
6484    }
6485
6486    @Override
6487    public final void backgroundResourcesReleased(IBinder token) {
6488        final long origId = Binder.clearCallingIdentity();
6489        try {
6490            synchronized (this) {
6491                ActivityStack stack = ActivityRecord.getStackLocked(token);
6492                if (stack != null) {
6493                    stack.backgroundResourcesReleased();
6494                }
6495            }
6496        } finally {
6497            Binder.restoreCallingIdentity(origId);
6498        }
6499    }
6500
6501    @Override
6502    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6503        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6504    }
6505
6506    @Override
6507    public final void notifyEnterAnimationComplete(IBinder token) {
6508        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6509    }
6510
6511    @Override
6512    public String getCallingPackage(IBinder token) {
6513        synchronized (this) {
6514            ActivityRecord r = getCallingRecordLocked(token);
6515            return r != null ? r.info.packageName : null;
6516        }
6517    }
6518
6519    @Override
6520    public ComponentName getCallingActivity(IBinder token) {
6521        synchronized (this) {
6522            ActivityRecord r = getCallingRecordLocked(token);
6523            return r != null ? r.intent.getComponent() : null;
6524        }
6525    }
6526
6527    private ActivityRecord getCallingRecordLocked(IBinder token) {
6528        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6529        if (r == null) {
6530            return null;
6531        }
6532        return r.resultTo;
6533    }
6534
6535    @Override
6536    public ComponentName getActivityClassForToken(IBinder token) {
6537        synchronized(this) {
6538            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6539            if (r == null) {
6540                return null;
6541            }
6542            return r.intent.getComponent();
6543        }
6544    }
6545
6546    @Override
6547    public String getPackageForToken(IBinder token) {
6548        synchronized(this) {
6549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6550            if (r == null) {
6551                return null;
6552            }
6553            return r.packageName;
6554        }
6555    }
6556
6557    @Override
6558    public IIntentSender getIntentSender(int type,
6559            String packageName, IBinder token, String resultWho,
6560            int requestCode, Intent[] intents, String[] resolvedTypes,
6561            int flags, Bundle options, int userId) {
6562        enforceNotIsolatedCaller("getIntentSender");
6563        // Refuse possible leaked file descriptors
6564        if (intents != null) {
6565            if (intents.length < 1) {
6566                throw new IllegalArgumentException("Intents array length must be >= 1");
6567            }
6568            for (int i=0; i<intents.length; i++) {
6569                Intent intent = intents[i];
6570                if (intent != null) {
6571                    if (intent.hasFileDescriptors()) {
6572                        throw new IllegalArgumentException("File descriptors passed in Intent");
6573                    }
6574                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6575                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6576                        throw new IllegalArgumentException(
6577                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6578                    }
6579                    intents[i] = new Intent(intent);
6580                }
6581            }
6582            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6583                throw new IllegalArgumentException(
6584                        "Intent array length does not match resolvedTypes length");
6585            }
6586        }
6587        if (options != null) {
6588            if (options.hasFileDescriptors()) {
6589                throw new IllegalArgumentException("File descriptors passed in options");
6590            }
6591        }
6592
6593        synchronized(this) {
6594            int callingUid = Binder.getCallingUid();
6595            int origUserId = userId;
6596            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6597                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6598                    ALLOW_NON_FULL, "getIntentSender", null);
6599            if (origUserId == UserHandle.USER_CURRENT) {
6600                // We don't want to evaluate this until the pending intent is
6601                // actually executed.  However, we do want to always do the
6602                // security checking for it above.
6603                userId = UserHandle.USER_CURRENT;
6604            }
6605            try {
6606                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6607                    int uid = AppGlobals.getPackageManager()
6608                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6609                    if (!UserHandle.isSameApp(callingUid, uid)) {
6610                        String msg = "Permission Denial: getIntentSender() from pid="
6611                            + Binder.getCallingPid()
6612                            + ", uid=" + Binder.getCallingUid()
6613                            + ", (need uid=" + uid + ")"
6614                            + " is not allowed to send as package " + packageName;
6615                        Slog.w(TAG, msg);
6616                        throw new SecurityException(msg);
6617                    }
6618                }
6619
6620                return getIntentSenderLocked(type, packageName, callingUid, userId,
6621                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6622
6623            } catch (RemoteException e) {
6624                throw new SecurityException(e);
6625            }
6626        }
6627    }
6628
6629    IIntentSender getIntentSenderLocked(int type, String packageName,
6630            int callingUid, int userId, IBinder token, String resultWho,
6631            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6632            Bundle options) {
6633        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6634        ActivityRecord activity = null;
6635        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6636            activity = ActivityRecord.isInStackLocked(token);
6637            if (activity == null) {
6638                return null;
6639            }
6640            if (activity.finishing) {
6641                return null;
6642            }
6643        }
6644
6645        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6646        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6647        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6648        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6649                |PendingIntent.FLAG_UPDATE_CURRENT);
6650
6651        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6652                type, packageName, activity, resultWho,
6653                requestCode, intents, resolvedTypes, flags, options, userId);
6654        WeakReference<PendingIntentRecord> ref;
6655        ref = mIntentSenderRecords.get(key);
6656        PendingIntentRecord rec = ref != null ? ref.get() : null;
6657        if (rec != null) {
6658            if (!cancelCurrent) {
6659                if (updateCurrent) {
6660                    if (rec.key.requestIntent != null) {
6661                        rec.key.requestIntent.replaceExtras(intents != null ?
6662                                intents[intents.length - 1] : null);
6663                    }
6664                    if (intents != null) {
6665                        intents[intents.length-1] = rec.key.requestIntent;
6666                        rec.key.allIntents = intents;
6667                        rec.key.allResolvedTypes = resolvedTypes;
6668                    } else {
6669                        rec.key.allIntents = null;
6670                        rec.key.allResolvedTypes = null;
6671                    }
6672                }
6673                return rec;
6674            }
6675            rec.canceled = true;
6676            mIntentSenderRecords.remove(key);
6677        }
6678        if (noCreate) {
6679            return rec;
6680        }
6681        rec = new PendingIntentRecord(this, key, callingUid);
6682        mIntentSenderRecords.put(key, rec.ref);
6683        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6684            if (activity.pendingResults == null) {
6685                activity.pendingResults
6686                        = new HashSet<WeakReference<PendingIntentRecord>>();
6687            }
6688            activity.pendingResults.add(rec.ref);
6689        }
6690        return rec;
6691    }
6692
6693    @Override
6694    public void cancelIntentSender(IIntentSender sender) {
6695        if (!(sender instanceof PendingIntentRecord)) {
6696            return;
6697        }
6698        synchronized(this) {
6699            PendingIntentRecord rec = (PendingIntentRecord)sender;
6700            try {
6701                int uid = AppGlobals.getPackageManager()
6702                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6703                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6704                    String msg = "Permission Denial: cancelIntentSender() from pid="
6705                        + Binder.getCallingPid()
6706                        + ", uid=" + Binder.getCallingUid()
6707                        + " is not allowed to cancel packges "
6708                        + rec.key.packageName;
6709                    Slog.w(TAG, msg);
6710                    throw new SecurityException(msg);
6711                }
6712            } catch (RemoteException e) {
6713                throw new SecurityException(e);
6714            }
6715            cancelIntentSenderLocked(rec, true);
6716        }
6717    }
6718
6719    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6720        rec.canceled = true;
6721        mIntentSenderRecords.remove(rec.key);
6722        if (cleanActivity && rec.key.activity != null) {
6723            rec.key.activity.pendingResults.remove(rec.ref);
6724        }
6725    }
6726
6727    @Override
6728    public String getPackageForIntentSender(IIntentSender pendingResult) {
6729        if (!(pendingResult instanceof PendingIntentRecord)) {
6730            return null;
6731        }
6732        try {
6733            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6734            return res.key.packageName;
6735        } catch (ClassCastException e) {
6736        }
6737        return null;
6738    }
6739
6740    @Override
6741    public int getUidForIntentSender(IIntentSender sender) {
6742        if (sender instanceof PendingIntentRecord) {
6743            try {
6744                PendingIntentRecord res = (PendingIntentRecord)sender;
6745                return res.uid;
6746            } catch (ClassCastException e) {
6747            }
6748        }
6749        return -1;
6750    }
6751
6752    @Override
6753    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6754        if (!(pendingResult instanceof PendingIntentRecord)) {
6755            return false;
6756        }
6757        try {
6758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6759            if (res.key.allIntents == null) {
6760                return false;
6761            }
6762            for (int i=0; i<res.key.allIntents.length; i++) {
6763                Intent intent = res.key.allIntents[i];
6764                if (intent.getPackage() != null && intent.getComponent() != null) {
6765                    return false;
6766                }
6767            }
6768            return true;
6769        } catch (ClassCastException e) {
6770        }
6771        return false;
6772    }
6773
6774    @Override
6775    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6776        if (!(pendingResult instanceof PendingIntentRecord)) {
6777            return false;
6778        }
6779        try {
6780            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6781            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6782                return true;
6783            }
6784            return false;
6785        } catch (ClassCastException e) {
6786        }
6787        return false;
6788    }
6789
6790    @Override
6791    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6792        if (!(pendingResult instanceof PendingIntentRecord)) {
6793            return null;
6794        }
6795        try {
6796            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6797            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6798        } catch (ClassCastException e) {
6799        }
6800        return null;
6801    }
6802
6803    @Override
6804    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6805        if (!(pendingResult instanceof PendingIntentRecord)) {
6806            return null;
6807        }
6808        try {
6809            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6810            synchronized (this) {
6811                return getTagForIntentSenderLocked(res, prefix);
6812            }
6813        } catch (ClassCastException e) {
6814        }
6815        return null;
6816    }
6817
6818    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6819        final Intent intent = res.key.requestIntent;
6820        if (intent != null) {
6821            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6822                    || res.lastTagPrefix.equals(prefix))) {
6823                return res.lastTag;
6824            }
6825            res.lastTagPrefix = prefix;
6826            final StringBuilder sb = new StringBuilder(128);
6827            if (prefix != null) {
6828                sb.append(prefix);
6829            }
6830            if (intent.getAction() != null) {
6831                sb.append(intent.getAction());
6832            } else if (intent.getComponent() != null) {
6833                intent.getComponent().appendShortString(sb);
6834            } else {
6835                sb.append("?");
6836            }
6837            return res.lastTag = sb.toString();
6838        }
6839        return null;
6840    }
6841
6842    @Override
6843    public void setProcessLimit(int max) {
6844        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6845                "setProcessLimit()");
6846        synchronized (this) {
6847            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6848            mProcessLimitOverride = max;
6849        }
6850        trimApplications();
6851    }
6852
6853    @Override
6854    public int getProcessLimit() {
6855        synchronized (this) {
6856            return mProcessLimitOverride;
6857        }
6858    }
6859
6860    void foregroundTokenDied(ForegroundToken token) {
6861        synchronized (ActivityManagerService.this) {
6862            synchronized (mPidsSelfLocked) {
6863                ForegroundToken cur
6864                    = mForegroundProcesses.get(token.pid);
6865                if (cur != token) {
6866                    return;
6867                }
6868                mForegroundProcesses.remove(token.pid);
6869                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6870                if (pr == null) {
6871                    return;
6872                }
6873                pr.forcingToForeground = null;
6874                updateProcessForegroundLocked(pr, false, false);
6875            }
6876            updateOomAdjLocked();
6877        }
6878    }
6879
6880    @Override
6881    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6882        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6883                "setProcessForeground()");
6884        synchronized(this) {
6885            boolean changed = false;
6886
6887            synchronized (mPidsSelfLocked) {
6888                ProcessRecord pr = mPidsSelfLocked.get(pid);
6889                if (pr == null && isForeground) {
6890                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6891                    return;
6892                }
6893                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6894                if (oldToken != null) {
6895                    oldToken.token.unlinkToDeath(oldToken, 0);
6896                    mForegroundProcesses.remove(pid);
6897                    if (pr != null) {
6898                        pr.forcingToForeground = null;
6899                    }
6900                    changed = true;
6901                }
6902                if (isForeground && token != null) {
6903                    ForegroundToken newToken = new ForegroundToken() {
6904                        @Override
6905                        public void binderDied() {
6906                            foregroundTokenDied(this);
6907                        }
6908                    };
6909                    newToken.pid = pid;
6910                    newToken.token = token;
6911                    try {
6912                        token.linkToDeath(newToken, 0);
6913                        mForegroundProcesses.put(pid, newToken);
6914                        pr.forcingToForeground = token;
6915                        changed = true;
6916                    } catch (RemoteException e) {
6917                        // If the process died while doing this, we will later
6918                        // do the cleanup with the process death link.
6919                    }
6920                }
6921            }
6922
6923            if (changed) {
6924                updateOomAdjLocked();
6925            }
6926        }
6927    }
6928
6929    // =========================================================
6930    // PROCESS INFO
6931    // =========================================================
6932
6933    static class ProcessInfoService extends IProcessInfoService.Stub {
6934        final ActivityManagerService mActivityManagerService;
6935        ProcessInfoService(ActivityManagerService activityManagerService) {
6936            mActivityManagerService = activityManagerService;
6937        }
6938
6939        @Override
6940        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6941            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6942        }
6943    }
6944
6945    /**
6946     * For each PID in the given input array, write the current process state
6947     * for that process into the output array, or -1 to indicate that no
6948     * process with the given PID exists.
6949     */
6950    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6951        if (pids == null) {
6952            throw new NullPointerException("pids");
6953        } else if (states == null) {
6954            throw new NullPointerException("states");
6955        } else if (pids.length != states.length) {
6956            throw new IllegalArgumentException("input and output arrays have different lengths!");
6957        }
6958
6959        synchronized (mPidsSelfLocked) {
6960            for (int i = 0; i < pids.length; i++) {
6961                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6962                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6963                        pr.curProcState;
6964            }
6965        }
6966    }
6967
6968    // =========================================================
6969    // PERMISSIONS
6970    // =========================================================
6971
6972    static class PermissionController extends IPermissionController.Stub {
6973        ActivityManagerService mActivityManagerService;
6974        PermissionController(ActivityManagerService activityManagerService) {
6975            mActivityManagerService = activityManagerService;
6976        }
6977
6978        @Override
6979        public boolean checkPermission(String permission, int pid, int uid) {
6980            return mActivityManagerService.checkPermission(permission, pid,
6981                    uid) == PackageManager.PERMISSION_GRANTED;
6982        }
6983
6984        @Override
6985        public String[] getPackagesForUid(int uid) {
6986            return mActivityManagerService.mContext.getPackageManager()
6987                    .getPackagesForUid(uid);
6988        }
6989
6990        @Override
6991        public boolean isRuntimePermission(String permission) {
6992            try {
6993                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6994                        .getPermissionInfo(permission, 0);
6995                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6996            } catch (NameNotFoundException nnfe) {
6997                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6998            }
6999            return false;
7000        }
7001    }
7002
7003    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7004        @Override
7005        public int checkComponentPermission(String permission, int pid, int uid,
7006                int owningUid, boolean exported) {
7007            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7008                    owningUid, exported);
7009        }
7010
7011        @Override
7012        public Object getAMSLock() {
7013            return ActivityManagerService.this;
7014        }
7015    }
7016
7017    /**
7018     * This can be called with or without the global lock held.
7019     */
7020    int checkComponentPermission(String permission, int pid, int uid,
7021            int owningUid, boolean exported) {
7022        if (pid == MY_PID) {
7023            return PackageManager.PERMISSION_GRANTED;
7024        }
7025        return ActivityManager.checkComponentPermission(permission, uid,
7026                owningUid, exported);
7027    }
7028
7029    /**
7030     * As the only public entry point for permissions checking, this method
7031     * can enforce the semantic that requesting a check on a null global
7032     * permission is automatically denied.  (Internally a null permission
7033     * string is used when calling {@link #checkComponentPermission} in cases
7034     * when only uid-based security is needed.)
7035     *
7036     * This can be called with or without the global lock held.
7037     */
7038    @Override
7039    public int checkPermission(String permission, int pid, int uid) {
7040        if (permission == null) {
7041            return PackageManager.PERMISSION_DENIED;
7042        }
7043        return checkComponentPermission(permission, pid, uid, -1, true);
7044    }
7045
7046    @Override
7047    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7048        if (permission == null) {
7049            return PackageManager.PERMISSION_DENIED;
7050        }
7051
7052        // We might be performing an operation on behalf of an indirect binder
7053        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7054        // client identity accordingly before proceeding.
7055        Identity tlsIdentity = sCallerIdentity.get();
7056        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7057            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7058                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7059            uid = tlsIdentity.uid;
7060            pid = tlsIdentity.pid;
7061        }
7062
7063        return checkComponentPermission(permission, pid, uid, -1, true);
7064    }
7065
7066    /**
7067     * Binder IPC calls go through the public entry point.
7068     * This can be called with or without the global lock held.
7069     */
7070    int checkCallingPermission(String permission) {
7071        return checkPermission(permission,
7072                Binder.getCallingPid(),
7073                UserHandle.getAppId(Binder.getCallingUid()));
7074    }
7075
7076    /**
7077     * This can be called with or without the global lock held.
7078     */
7079    void enforceCallingPermission(String permission, String func) {
7080        if (checkCallingPermission(permission)
7081                == PackageManager.PERMISSION_GRANTED) {
7082            return;
7083        }
7084
7085        String msg = "Permission Denial: " + func + " from pid="
7086                + Binder.getCallingPid()
7087                + ", uid=" + Binder.getCallingUid()
7088                + " requires " + permission;
7089        Slog.w(TAG, msg);
7090        throw new SecurityException(msg);
7091    }
7092
7093    /**
7094     * Determine if UID is holding permissions required to access {@link Uri} in
7095     * the given {@link ProviderInfo}. Final permission checking is always done
7096     * in {@link ContentProvider}.
7097     */
7098    private final boolean checkHoldingPermissionsLocked(
7099            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7100        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7101                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7102        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7103            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7104                    != PERMISSION_GRANTED) {
7105                return false;
7106            }
7107        }
7108        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7109    }
7110
7111    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7112            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7113        if (pi.applicationInfo.uid == uid) {
7114            return true;
7115        } else if (!pi.exported) {
7116            return false;
7117        }
7118
7119        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7120        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7121        try {
7122            // check if target holds top-level <provider> permissions
7123            if (!readMet && pi.readPermission != null && considerUidPermissions
7124                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7125                readMet = true;
7126            }
7127            if (!writeMet && pi.writePermission != null && considerUidPermissions
7128                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7129                writeMet = true;
7130            }
7131
7132            // track if unprotected read/write is allowed; any denied
7133            // <path-permission> below removes this ability
7134            boolean allowDefaultRead = pi.readPermission == null;
7135            boolean allowDefaultWrite = pi.writePermission == null;
7136
7137            // check if target holds any <path-permission> that match uri
7138            final PathPermission[] pps = pi.pathPermissions;
7139            if (pps != null) {
7140                final String path = grantUri.uri.getPath();
7141                int i = pps.length;
7142                while (i > 0 && (!readMet || !writeMet)) {
7143                    i--;
7144                    PathPermission pp = pps[i];
7145                    if (pp.match(path)) {
7146                        if (!readMet) {
7147                            final String pprperm = pp.getReadPermission();
7148                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7149                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7150                                    + ": match=" + pp.match(path)
7151                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7152                            if (pprperm != null) {
7153                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7154                                        == PERMISSION_GRANTED) {
7155                                    readMet = true;
7156                                } else {
7157                                    allowDefaultRead = false;
7158                                }
7159                            }
7160                        }
7161                        if (!writeMet) {
7162                            final String ppwperm = pp.getWritePermission();
7163                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7164                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7165                                    + ": match=" + pp.match(path)
7166                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7167                            if (ppwperm != null) {
7168                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7169                                        == PERMISSION_GRANTED) {
7170                                    writeMet = true;
7171                                } else {
7172                                    allowDefaultWrite = false;
7173                                }
7174                            }
7175                        }
7176                    }
7177                }
7178            }
7179
7180            // grant unprotected <provider> read/write, if not blocked by
7181            // <path-permission> above
7182            if (allowDefaultRead) readMet = true;
7183            if (allowDefaultWrite) writeMet = true;
7184
7185        } catch (RemoteException e) {
7186            return false;
7187        }
7188
7189        return readMet && writeMet;
7190    }
7191
7192    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7193        ProviderInfo pi = null;
7194        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7195        if (cpr != null) {
7196            pi = cpr.info;
7197        } else {
7198            try {
7199                pi = AppGlobals.getPackageManager().resolveContentProvider(
7200                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7201            } catch (RemoteException ex) {
7202            }
7203        }
7204        return pi;
7205    }
7206
7207    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7208        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7209        if (targetUris != null) {
7210            return targetUris.get(grantUri);
7211        }
7212        return null;
7213    }
7214
7215    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7216            String targetPkg, int targetUid, GrantUri grantUri) {
7217        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7218        if (targetUris == null) {
7219            targetUris = Maps.newArrayMap();
7220            mGrantedUriPermissions.put(targetUid, targetUris);
7221        }
7222
7223        UriPermission perm = targetUris.get(grantUri);
7224        if (perm == null) {
7225            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7226            targetUris.put(grantUri, perm);
7227        }
7228
7229        return perm;
7230    }
7231
7232    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7233            final int modeFlags) {
7234        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7235        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7236                : UriPermission.STRENGTH_OWNED;
7237
7238        // Root gets to do everything.
7239        if (uid == 0) {
7240            return true;
7241        }
7242
7243        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7244        if (perms == null) return false;
7245
7246        // First look for exact match
7247        final UriPermission exactPerm = perms.get(grantUri);
7248        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7249            return true;
7250        }
7251
7252        // No exact match, look for prefixes
7253        final int N = perms.size();
7254        for (int i = 0; i < N; i++) {
7255            final UriPermission perm = perms.valueAt(i);
7256            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7257                    && perm.getStrength(modeFlags) >= minStrength) {
7258                return true;
7259            }
7260        }
7261
7262        return false;
7263    }
7264
7265    /**
7266     * @param uri This uri must NOT contain an embedded userId.
7267     * @param userId The userId in which the uri is to be resolved.
7268     */
7269    @Override
7270    public int checkUriPermission(Uri uri, int pid, int uid,
7271            final int modeFlags, int userId, IBinder callerToken) {
7272        enforceNotIsolatedCaller("checkUriPermission");
7273
7274        // Another redirected-binder-call permissions check as in
7275        // {@link checkPermissionWithToken}.
7276        Identity tlsIdentity = sCallerIdentity.get();
7277        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7278            uid = tlsIdentity.uid;
7279            pid = tlsIdentity.pid;
7280        }
7281
7282        // Our own process gets to do everything.
7283        if (pid == MY_PID) {
7284            return PackageManager.PERMISSION_GRANTED;
7285        }
7286        synchronized (this) {
7287            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7288                    ? PackageManager.PERMISSION_GRANTED
7289                    : PackageManager.PERMISSION_DENIED;
7290        }
7291    }
7292
7293    /**
7294     * Check if the targetPkg can be granted permission to access uri by
7295     * the callingUid using the given modeFlags.  Throws a security exception
7296     * if callingUid is not allowed to do this.  Returns the uid of the target
7297     * if the URI permission grant should be performed; returns -1 if it is not
7298     * needed (for example targetPkg already has permission to access the URI).
7299     * If you already know the uid of the target, you can supply it in
7300     * lastTargetUid else set that to -1.
7301     */
7302    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7303            final int modeFlags, int lastTargetUid) {
7304        if (!Intent.isAccessUriMode(modeFlags)) {
7305            return -1;
7306        }
7307
7308        if (targetPkg != null) {
7309            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7310                    "Checking grant " + targetPkg + " permission to " + grantUri);
7311        }
7312
7313        final IPackageManager pm = AppGlobals.getPackageManager();
7314
7315        // If this is not a content: uri, we can't do anything with it.
7316        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7317            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7318                    "Can't grant URI permission for non-content URI: " + grantUri);
7319            return -1;
7320        }
7321
7322        final String authority = grantUri.uri.getAuthority();
7323        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7324        if (pi == null) {
7325            Slog.w(TAG, "No content provider found for permission check: " +
7326                    grantUri.uri.toSafeString());
7327            return -1;
7328        }
7329
7330        int targetUid = lastTargetUid;
7331        if (targetUid < 0 && targetPkg != null) {
7332            try {
7333                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7334                if (targetUid < 0) {
7335                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7336                            "Can't grant URI permission no uid for: " + targetPkg);
7337                    return -1;
7338                }
7339            } catch (RemoteException ex) {
7340                return -1;
7341            }
7342        }
7343
7344        if (targetUid >= 0) {
7345            // First...  does the target actually need this permission?
7346            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7347                // No need to grant the target this permission.
7348                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7349                        "Target " + targetPkg + " already has full permission to " + grantUri);
7350                return -1;
7351            }
7352        } else {
7353            // First...  there is no target package, so can anyone access it?
7354            boolean allowed = pi.exported;
7355            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7356                if (pi.readPermission != null) {
7357                    allowed = false;
7358                }
7359            }
7360            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7361                if (pi.writePermission != null) {
7362                    allowed = false;
7363                }
7364            }
7365            if (allowed) {
7366                return -1;
7367            }
7368        }
7369
7370        /* There is a special cross user grant if:
7371         * - The target is on another user.
7372         * - Apps on the current user can access the uri without any uid permissions.
7373         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7374         * grant uri permissions.
7375         */
7376        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7377                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7378                modeFlags, false /*without considering the uid permissions*/);
7379
7380        // Second...  is the provider allowing granting of URI permissions?
7381        if (!specialCrossUserGrant) {
7382            if (!pi.grantUriPermissions) {
7383                throw new SecurityException("Provider " + pi.packageName
7384                        + "/" + pi.name
7385                        + " does not allow granting of Uri permissions (uri "
7386                        + grantUri + ")");
7387            }
7388            if (pi.uriPermissionPatterns != null) {
7389                final int N = pi.uriPermissionPatterns.length;
7390                boolean allowed = false;
7391                for (int i=0; i<N; i++) {
7392                    if (pi.uriPermissionPatterns[i] != null
7393                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7394                        allowed = true;
7395                        break;
7396                    }
7397                }
7398                if (!allowed) {
7399                    throw new SecurityException("Provider " + pi.packageName
7400                            + "/" + pi.name
7401                            + " does not allow granting of permission to path of Uri "
7402                            + grantUri);
7403                }
7404            }
7405        }
7406
7407        // Third...  does the caller itself have permission to access
7408        // this uri?
7409        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7410            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7411                // Require they hold a strong enough Uri permission
7412                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7413                    throw new SecurityException("Uid " + callingUid
7414                            + " does not have permission to uri " + grantUri);
7415                }
7416            }
7417        }
7418        return targetUid;
7419    }
7420
7421    /**
7422     * @param uri This uri must NOT contain an embedded userId.
7423     * @param userId The userId in which the uri is to be resolved.
7424     */
7425    @Override
7426    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7427            final int modeFlags, int userId) {
7428        enforceNotIsolatedCaller("checkGrantUriPermission");
7429        synchronized(this) {
7430            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7431                    new GrantUri(userId, uri, false), modeFlags, -1);
7432        }
7433    }
7434
7435    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7436            final int modeFlags, UriPermissionOwner owner) {
7437        if (!Intent.isAccessUriMode(modeFlags)) {
7438            return;
7439        }
7440
7441        // So here we are: the caller has the assumed permission
7442        // to the uri, and the target doesn't.  Let's now give this to
7443        // the target.
7444
7445        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7446                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7447
7448        final String authority = grantUri.uri.getAuthority();
7449        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7450        if (pi == null) {
7451            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7452            return;
7453        }
7454
7455        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7456            grantUri.prefix = true;
7457        }
7458        final UriPermission perm = findOrCreateUriPermissionLocked(
7459                pi.packageName, targetPkg, targetUid, grantUri);
7460        perm.grantModes(modeFlags, owner);
7461    }
7462
7463    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7464            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7465        if (targetPkg == null) {
7466            throw new NullPointerException("targetPkg");
7467        }
7468        int targetUid;
7469        final IPackageManager pm = AppGlobals.getPackageManager();
7470        try {
7471            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7472        } catch (RemoteException ex) {
7473            return;
7474        }
7475
7476        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7477                targetUid);
7478        if (targetUid < 0) {
7479            return;
7480        }
7481
7482        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7483                owner);
7484    }
7485
7486    static class NeededUriGrants extends ArrayList<GrantUri> {
7487        final String targetPkg;
7488        final int targetUid;
7489        final int flags;
7490
7491        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7492            this.targetPkg = targetPkg;
7493            this.targetUid = targetUid;
7494            this.flags = flags;
7495        }
7496    }
7497
7498    /**
7499     * Like checkGrantUriPermissionLocked, but takes an Intent.
7500     */
7501    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7502            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7503        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7504                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7505                + " clip=" + (intent != null ? intent.getClipData() : null)
7506                + " from " + intent + "; flags=0x"
7507                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7508
7509        if (targetPkg == null) {
7510            throw new NullPointerException("targetPkg");
7511        }
7512
7513        if (intent == null) {
7514            return null;
7515        }
7516        Uri data = intent.getData();
7517        ClipData clip = intent.getClipData();
7518        if (data == null && clip == null) {
7519            return null;
7520        }
7521        // Default userId for uris in the intent (if they don't specify it themselves)
7522        int contentUserHint = intent.getContentUserHint();
7523        if (contentUserHint == UserHandle.USER_CURRENT) {
7524            contentUserHint = UserHandle.getUserId(callingUid);
7525        }
7526        final IPackageManager pm = AppGlobals.getPackageManager();
7527        int targetUid;
7528        if (needed != null) {
7529            targetUid = needed.targetUid;
7530        } else {
7531            try {
7532                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7533            } catch (RemoteException ex) {
7534                return null;
7535            }
7536            if (targetUid < 0) {
7537                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7538                        "Can't grant URI permission no uid for: " + targetPkg
7539                        + " on user " + targetUserId);
7540                return null;
7541            }
7542        }
7543        if (data != null) {
7544            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7545            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7546                    targetUid);
7547            if (targetUid > 0) {
7548                if (needed == null) {
7549                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7550                }
7551                needed.add(grantUri);
7552            }
7553        }
7554        if (clip != null) {
7555            for (int i=0; i<clip.getItemCount(); i++) {
7556                Uri uri = clip.getItemAt(i).getUri();
7557                if (uri != null) {
7558                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7559                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7560                            targetUid);
7561                    if (targetUid > 0) {
7562                        if (needed == null) {
7563                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7564                        }
7565                        needed.add(grantUri);
7566                    }
7567                } else {
7568                    Intent clipIntent = clip.getItemAt(i).getIntent();
7569                    if (clipIntent != null) {
7570                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7571                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7572                        if (newNeeded != null) {
7573                            needed = newNeeded;
7574                        }
7575                    }
7576                }
7577            }
7578        }
7579
7580        return needed;
7581    }
7582
7583    /**
7584     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7585     */
7586    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7587            UriPermissionOwner owner) {
7588        if (needed != null) {
7589            for (int i=0; i<needed.size(); i++) {
7590                GrantUri grantUri = needed.get(i);
7591                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7592                        grantUri, needed.flags, owner);
7593            }
7594        }
7595    }
7596
7597    void grantUriPermissionFromIntentLocked(int callingUid,
7598            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7599        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7600                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7601        if (needed == null) {
7602            return;
7603        }
7604
7605        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7606    }
7607
7608    /**
7609     * @param uri This uri must NOT contain an embedded userId.
7610     * @param userId The userId in which the uri is to be resolved.
7611     */
7612    @Override
7613    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7614            final int modeFlags, int userId) {
7615        enforceNotIsolatedCaller("grantUriPermission");
7616        GrantUri grantUri = new GrantUri(userId, uri, false);
7617        synchronized(this) {
7618            final ProcessRecord r = getRecordForAppLocked(caller);
7619            if (r == null) {
7620                throw new SecurityException("Unable to find app for caller "
7621                        + caller
7622                        + " when granting permission to uri " + grantUri);
7623            }
7624            if (targetPkg == null) {
7625                throw new IllegalArgumentException("null target");
7626            }
7627            if (grantUri == null) {
7628                throw new IllegalArgumentException("null uri");
7629            }
7630
7631            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7632                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7633                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7634                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7635
7636            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7637                    UserHandle.getUserId(r.uid));
7638        }
7639    }
7640
7641    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7642        if (perm.modeFlags == 0) {
7643            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7644                    perm.targetUid);
7645            if (perms != null) {
7646                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7647                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7648
7649                perms.remove(perm.uri);
7650                if (perms.isEmpty()) {
7651                    mGrantedUriPermissions.remove(perm.targetUid);
7652                }
7653            }
7654        }
7655    }
7656
7657    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7658        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7659                "Revoking all granted permissions to " + grantUri);
7660
7661        final IPackageManager pm = AppGlobals.getPackageManager();
7662        final String authority = grantUri.uri.getAuthority();
7663        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7664        if (pi == null) {
7665            Slog.w(TAG, "No content provider found for permission revoke: "
7666                    + grantUri.toSafeString());
7667            return;
7668        }
7669
7670        // Does the caller have this permission on the URI?
7671        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7672            // If they don't have direct access to the URI, then revoke any
7673            // ownerless URI permissions that have been granted to them.
7674            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7675            if (perms != null) {
7676                boolean persistChanged = false;
7677                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7678                    final UriPermission perm = it.next();
7679                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7680                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7681                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7682                                "Revoking non-owned " + perm.targetUid
7683                                + " permission to " + perm.uri);
7684                        persistChanged |= perm.revokeModes(
7685                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7686                        if (perm.modeFlags == 0) {
7687                            it.remove();
7688                        }
7689                    }
7690                }
7691                if (perms.isEmpty()) {
7692                    mGrantedUriPermissions.remove(callingUid);
7693                }
7694                if (persistChanged) {
7695                    schedulePersistUriGrants();
7696                }
7697            }
7698            return;
7699        }
7700
7701        boolean persistChanged = false;
7702
7703        // Go through all of the permissions and remove any that match.
7704        int N = mGrantedUriPermissions.size();
7705        for (int i = 0; i < N; i++) {
7706            final int targetUid = mGrantedUriPermissions.keyAt(i);
7707            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7708
7709            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7710                final UriPermission perm = it.next();
7711                if (perm.uri.sourceUserId == grantUri.sourceUserId
7712                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7713                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7714                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7715                    persistChanged |= perm.revokeModes(
7716                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7717                    if (perm.modeFlags == 0) {
7718                        it.remove();
7719                    }
7720                }
7721            }
7722
7723            if (perms.isEmpty()) {
7724                mGrantedUriPermissions.remove(targetUid);
7725                N--;
7726                i--;
7727            }
7728        }
7729
7730        if (persistChanged) {
7731            schedulePersistUriGrants();
7732        }
7733    }
7734
7735    /**
7736     * @param uri This uri must NOT contain an embedded userId.
7737     * @param userId The userId in which the uri is to be resolved.
7738     */
7739    @Override
7740    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7741            int userId) {
7742        enforceNotIsolatedCaller("revokeUriPermission");
7743        synchronized(this) {
7744            final ProcessRecord r = getRecordForAppLocked(caller);
7745            if (r == null) {
7746                throw new SecurityException("Unable to find app for caller "
7747                        + caller
7748                        + " when revoking permission to uri " + uri);
7749            }
7750            if (uri == null) {
7751                Slog.w(TAG, "revokeUriPermission: null uri");
7752                return;
7753            }
7754
7755            if (!Intent.isAccessUriMode(modeFlags)) {
7756                return;
7757            }
7758
7759            final String authority = uri.getAuthority();
7760            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7761            if (pi == null) {
7762                Slog.w(TAG, "No content provider found for permission revoke: "
7763                        + uri.toSafeString());
7764                return;
7765            }
7766
7767            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7768        }
7769    }
7770
7771    /**
7772     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7773     * given package.
7774     *
7775     * @param packageName Package name to match, or {@code null} to apply to all
7776     *            packages.
7777     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7778     *            to all users.
7779     * @param persistable If persistable grants should be removed.
7780     */
7781    private void removeUriPermissionsForPackageLocked(
7782            String packageName, int userHandle, boolean persistable) {
7783        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7784            throw new IllegalArgumentException("Must narrow by either package or user");
7785        }
7786
7787        boolean persistChanged = false;
7788
7789        int N = mGrantedUriPermissions.size();
7790        for (int i = 0; i < N; i++) {
7791            final int targetUid = mGrantedUriPermissions.keyAt(i);
7792            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7793
7794            // Only inspect grants matching user
7795            if (userHandle == UserHandle.USER_ALL
7796                    || userHandle == UserHandle.getUserId(targetUid)) {
7797                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7798                    final UriPermission perm = it.next();
7799
7800                    // Only inspect grants matching package
7801                    if (packageName == null || perm.sourcePkg.equals(packageName)
7802                            || perm.targetPkg.equals(packageName)) {
7803                        persistChanged |= perm.revokeModes(persistable
7804                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7805
7806                        // Only remove when no modes remain; any persisted grants
7807                        // will keep this alive.
7808                        if (perm.modeFlags == 0) {
7809                            it.remove();
7810                        }
7811                    }
7812                }
7813
7814                if (perms.isEmpty()) {
7815                    mGrantedUriPermissions.remove(targetUid);
7816                    N--;
7817                    i--;
7818                }
7819            }
7820        }
7821
7822        if (persistChanged) {
7823            schedulePersistUriGrants();
7824        }
7825    }
7826
7827    @Override
7828    public IBinder newUriPermissionOwner(String name) {
7829        enforceNotIsolatedCaller("newUriPermissionOwner");
7830        synchronized(this) {
7831            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7832            return owner.getExternalTokenLocked();
7833        }
7834    }
7835
7836    /**
7837     * @param uri This uri must NOT contain an embedded userId.
7838     * @param sourceUserId The userId in which the uri is to be resolved.
7839     * @param targetUserId The userId of the app that receives the grant.
7840     */
7841    @Override
7842    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7843            final int modeFlags, int sourceUserId, int targetUserId) {
7844        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7845                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7846        synchronized(this) {
7847            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7848            if (owner == null) {
7849                throw new IllegalArgumentException("Unknown owner: " + token);
7850            }
7851            if (fromUid != Binder.getCallingUid()) {
7852                if (Binder.getCallingUid() != Process.myUid()) {
7853                    // Only system code can grant URI permissions on behalf
7854                    // of other users.
7855                    throw new SecurityException("nice try");
7856                }
7857            }
7858            if (targetPkg == null) {
7859                throw new IllegalArgumentException("null target");
7860            }
7861            if (uri == null) {
7862                throw new IllegalArgumentException("null uri");
7863            }
7864
7865            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7866                    modeFlags, owner, targetUserId);
7867        }
7868    }
7869
7870    /**
7871     * @param uri This uri must NOT contain an embedded userId.
7872     * @param userId The userId in which the uri is to be resolved.
7873     */
7874    @Override
7875    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7876        synchronized(this) {
7877            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7878            if (owner == null) {
7879                throw new IllegalArgumentException("Unknown owner: " + token);
7880            }
7881
7882            if (uri == null) {
7883                owner.removeUriPermissionsLocked(mode);
7884            } else {
7885                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7886            }
7887        }
7888    }
7889
7890    private void schedulePersistUriGrants() {
7891        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7892            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7893                    10 * DateUtils.SECOND_IN_MILLIS);
7894        }
7895    }
7896
7897    private void writeGrantedUriPermissions() {
7898        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7899
7900        // Snapshot permissions so we can persist without lock
7901        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7902        synchronized (this) {
7903            final int size = mGrantedUriPermissions.size();
7904            for (int i = 0; i < size; i++) {
7905                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7906                for (UriPermission perm : perms.values()) {
7907                    if (perm.persistedModeFlags != 0) {
7908                        persist.add(perm.snapshot());
7909                    }
7910                }
7911            }
7912        }
7913
7914        FileOutputStream fos = null;
7915        try {
7916            fos = mGrantFile.startWrite();
7917
7918            XmlSerializer out = new FastXmlSerializer();
7919            out.setOutput(fos, StandardCharsets.UTF_8.name());
7920            out.startDocument(null, true);
7921            out.startTag(null, TAG_URI_GRANTS);
7922            for (UriPermission.Snapshot perm : persist) {
7923                out.startTag(null, TAG_URI_GRANT);
7924                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7925                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7926                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7927                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7928                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7929                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7930                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7931                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7932                out.endTag(null, TAG_URI_GRANT);
7933            }
7934            out.endTag(null, TAG_URI_GRANTS);
7935            out.endDocument();
7936
7937            mGrantFile.finishWrite(fos);
7938        } catch (IOException e) {
7939            if (fos != null) {
7940                mGrantFile.failWrite(fos);
7941            }
7942        }
7943    }
7944
7945    private void readGrantedUriPermissionsLocked() {
7946        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7947
7948        final long now = System.currentTimeMillis();
7949
7950        FileInputStream fis = null;
7951        try {
7952            fis = mGrantFile.openRead();
7953            final XmlPullParser in = Xml.newPullParser();
7954            in.setInput(fis, StandardCharsets.UTF_8.name());
7955
7956            int type;
7957            while ((type = in.next()) != END_DOCUMENT) {
7958                final String tag = in.getName();
7959                if (type == START_TAG) {
7960                    if (TAG_URI_GRANT.equals(tag)) {
7961                        final int sourceUserId;
7962                        final int targetUserId;
7963                        final int userHandle = readIntAttribute(in,
7964                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7965                        if (userHandle != UserHandle.USER_NULL) {
7966                            // For backwards compatibility.
7967                            sourceUserId = userHandle;
7968                            targetUserId = userHandle;
7969                        } else {
7970                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7971                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7972                        }
7973                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7974                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7975                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7976                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7977                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7978                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7979
7980                        // Sanity check that provider still belongs to source package
7981                        final ProviderInfo pi = getProviderInfoLocked(
7982                                uri.getAuthority(), sourceUserId);
7983                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7984                            int targetUid = -1;
7985                            try {
7986                                targetUid = AppGlobals.getPackageManager()
7987                                        .getPackageUid(targetPkg, targetUserId);
7988                            } catch (RemoteException e) {
7989                            }
7990                            if (targetUid != -1) {
7991                                final UriPermission perm = findOrCreateUriPermissionLocked(
7992                                        sourcePkg, targetPkg, targetUid,
7993                                        new GrantUri(sourceUserId, uri, prefix));
7994                                perm.initPersistedModes(modeFlags, createdTime);
7995                            }
7996                        } else {
7997                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7998                                    + " but instead found " + pi);
7999                        }
8000                    }
8001                }
8002            }
8003        } catch (FileNotFoundException e) {
8004            // Missing grants is okay
8005        } catch (IOException e) {
8006            Slog.wtf(TAG, "Failed reading Uri grants", e);
8007        } catch (XmlPullParserException e) {
8008            Slog.wtf(TAG, "Failed reading Uri grants", e);
8009        } finally {
8010            IoUtils.closeQuietly(fis);
8011        }
8012    }
8013
8014    /**
8015     * @param uri This uri must NOT contain an embedded userId.
8016     * @param userId The userId in which the uri is to be resolved.
8017     */
8018    @Override
8019    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8020        enforceNotIsolatedCaller("takePersistableUriPermission");
8021
8022        Preconditions.checkFlagsArgument(modeFlags,
8023                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8024
8025        synchronized (this) {
8026            final int callingUid = Binder.getCallingUid();
8027            boolean persistChanged = false;
8028            GrantUri grantUri = new GrantUri(userId, uri, false);
8029
8030            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8031                    new GrantUri(userId, uri, false));
8032            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8033                    new GrantUri(userId, uri, true));
8034
8035            final boolean exactValid = (exactPerm != null)
8036                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8037            final boolean prefixValid = (prefixPerm != null)
8038                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8039
8040            if (!(exactValid || prefixValid)) {
8041                throw new SecurityException("No persistable permission grants found for UID "
8042                        + callingUid + " and Uri " + grantUri.toSafeString());
8043            }
8044
8045            if (exactValid) {
8046                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8047            }
8048            if (prefixValid) {
8049                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8050            }
8051
8052            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8053
8054            if (persistChanged) {
8055                schedulePersistUriGrants();
8056            }
8057        }
8058    }
8059
8060    /**
8061     * @param uri This uri must NOT contain an embedded userId.
8062     * @param userId The userId in which the uri is to be resolved.
8063     */
8064    @Override
8065    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8066        enforceNotIsolatedCaller("releasePersistableUriPermission");
8067
8068        Preconditions.checkFlagsArgument(modeFlags,
8069                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8070
8071        synchronized (this) {
8072            final int callingUid = Binder.getCallingUid();
8073            boolean persistChanged = false;
8074
8075            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8076                    new GrantUri(userId, uri, false));
8077            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8078                    new GrantUri(userId, uri, true));
8079            if (exactPerm == null && prefixPerm == null) {
8080                throw new SecurityException("No permission grants found for UID " + callingUid
8081                        + " and Uri " + uri.toSafeString());
8082            }
8083
8084            if (exactPerm != null) {
8085                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8086                removeUriPermissionIfNeededLocked(exactPerm);
8087            }
8088            if (prefixPerm != null) {
8089                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8090                removeUriPermissionIfNeededLocked(prefixPerm);
8091            }
8092
8093            if (persistChanged) {
8094                schedulePersistUriGrants();
8095            }
8096        }
8097    }
8098
8099    /**
8100     * Prune any older {@link UriPermission} for the given UID until outstanding
8101     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8102     *
8103     * @return if any mutations occured that require persisting.
8104     */
8105    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8106        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8107        if (perms == null) return false;
8108        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8109
8110        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8111        for (UriPermission perm : perms.values()) {
8112            if (perm.persistedModeFlags != 0) {
8113                persisted.add(perm);
8114            }
8115        }
8116
8117        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8118        if (trimCount <= 0) return false;
8119
8120        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8121        for (int i = 0; i < trimCount; i++) {
8122            final UriPermission perm = persisted.get(i);
8123
8124            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8125                    "Trimming grant created at " + perm.persistedCreateTime);
8126
8127            perm.releasePersistableModes(~0);
8128            removeUriPermissionIfNeededLocked(perm);
8129        }
8130
8131        return true;
8132    }
8133
8134    @Override
8135    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8136            String packageName, boolean incoming) {
8137        enforceNotIsolatedCaller("getPersistedUriPermissions");
8138        Preconditions.checkNotNull(packageName, "packageName");
8139
8140        final int callingUid = Binder.getCallingUid();
8141        final IPackageManager pm = AppGlobals.getPackageManager();
8142        try {
8143            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8144            if (packageUid != callingUid) {
8145                throw new SecurityException(
8146                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8147            }
8148        } catch (RemoteException e) {
8149            throw new SecurityException("Failed to verify package name ownership");
8150        }
8151
8152        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8153        synchronized (this) {
8154            if (incoming) {
8155                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8156                        callingUid);
8157                if (perms == null) {
8158                    Slog.w(TAG, "No permission grants found for " + packageName);
8159                } else {
8160                    for (UriPermission perm : perms.values()) {
8161                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8162                            result.add(perm.buildPersistedPublicApiObject());
8163                        }
8164                    }
8165                }
8166            } else {
8167                final int size = mGrantedUriPermissions.size();
8168                for (int i = 0; i < size; i++) {
8169                    final ArrayMap<GrantUri, UriPermission> perms =
8170                            mGrantedUriPermissions.valueAt(i);
8171                    for (UriPermission perm : perms.values()) {
8172                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8173                            result.add(perm.buildPersistedPublicApiObject());
8174                        }
8175                    }
8176                }
8177            }
8178        }
8179        return new ParceledListSlice<android.content.UriPermission>(result);
8180    }
8181
8182    @Override
8183    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8184        synchronized (this) {
8185            ProcessRecord app =
8186                who != null ? getRecordForAppLocked(who) : null;
8187            if (app == null) return;
8188
8189            Message msg = Message.obtain();
8190            msg.what = WAIT_FOR_DEBUGGER_MSG;
8191            msg.obj = app;
8192            msg.arg1 = waiting ? 1 : 0;
8193            mUiHandler.sendMessage(msg);
8194        }
8195    }
8196
8197    @Override
8198    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8199        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8200        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8201        outInfo.availMem = Process.getFreeMemory();
8202        outInfo.totalMem = Process.getTotalMemory();
8203        outInfo.threshold = homeAppMem;
8204        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8205        outInfo.hiddenAppThreshold = cachedAppMem;
8206        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8207                ProcessList.SERVICE_ADJ);
8208        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8209                ProcessList.VISIBLE_APP_ADJ);
8210        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8211                ProcessList.FOREGROUND_APP_ADJ);
8212    }
8213
8214    // =========================================================
8215    // TASK MANAGEMENT
8216    // =========================================================
8217
8218    @Override
8219    public List<IAppTask> getAppTasks(String callingPackage) {
8220        int callingUid = Binder.getCallingUid();
8221        long ident = Binder.clearCallingIdentity();
8222
8223        synchronized(this) {
8224            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8225            try {
8226                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8227
8228                final int N = mRecentTasks.size();
8229                for (int i = 0; i < N; i++) {
8230                    TaskRecord tr = mRecentTasks.get(i);
8231                    // Skip tasks that do not match the caller.  We don't need to verify
8232                    // callingPackage, because we are also limiting to callingUid and know
8233                    // that will limit to the correct security sandbox.
8234                    if (tr.effectiveUid != callingUid) {
8235                        continue;
8236                    }
8237                    Intent intent = tr.getBaseIntent();
8238                    if (intent == null ||
8239                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8240                        continue;
8241                    }
8242                    ActivityManager.RecentTaskInfo taskInfo =
8243                            createRecentTaskInfoFromTaskRecord(tr);
8244                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8245                    list.add(taskImpl);
8246                }
8247            } finally {
8248                Binder.restoreCallingIdentity(ident);
8249            }
8250            return list;
8251        }
8252    }
8253
8254    @Override
8255    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8256        final int callingUid = Binder.getCallingUid();
8257        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8258
8259        synchronized(this) {
8260            if (DEBUG_ALL) Slog.v(
8261                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8262
8263            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8264                    callingUid);
8265
8266            // TODO: Improve with MRU list from all ActivityStacks.
8267            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8268        }
8269
8270        return list;
8271    }
8272
8273    /**
8274     * Creates a new RecentTaskInfo from a TaskRecord.
8275     */
8276    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8277        // Update the task description to reflect any changes in the task stack
8278        tr.updateTaskDescription();
8279
8280        // Compose the recent task info
8281        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8282        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8283        rti.persistentId = tr.taskId;
8284        rti.baseIntent = new Intent(tr.getBaseIntent());
8285        rti.origActivity = tr.origActivity;
8286        rti.description = tr.lastDescription;
8287        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8288        rti.userId = tr.userId;
8289        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8290        rti.firstActiveTime = tr.firstActiveTime;
8291        rti.lastActiveTime = tr.lastActiveTime;
8292        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8293        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8294        rti.numActivities = 0;
8295
8296        ActivityRecord base = null;
8297        ActivityRecord top = null;
8298        ActivityRecord tmp;
8299
8300        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8301            tmp = tr.mActivities.get(i);
8302            if (tmp.finishing) {
8303                continue;
8304            }
8305            base = tmp;
8306            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8307                top = base;
8308            }
8309            rti.numActivities++;
8310        }
8311
8312        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8313        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8314
8315        return rti;
8316    }
8317
8318    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8319        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8320                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8321        if (!allowed) {
8322            if (checkPermission(android.Manifest.permission.GET_TASKS,
8323                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8324                // Temporary compatibility: some existing apps on the system image may
8325                // still be requesting the old permission and not switched to the new
8326                // one; if so, we'll still allow them full access.  This means we need
8327                // to see if they are holding the old permission and are a system app.
8328                try {
8329                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8330                        allowed = true;
8331                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8332                                + " is using old GET_TASKS but privileged; allowing");
8333                    }
8334                } catch (RemoteException e) {
8335                }
8336            }
8337        }
8338        if (!allowed) {
8339            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8340                    + " does not hold REAL_GET_TASKS; limiting output");
8341        }
8342        return allowed;
8343    }
8344
8345    @Override
8346    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8347        final int callingUid = Binder.getCallingUid();
8348        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8349                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8350
8351        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8352        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8353        synchronized (this) {
8354            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8355                    callingUid);
8356            final boolean detailed = checkCallingPermission(
8357                    android.Manifest.permission.GET_DETAILED_TASKS)
8358                    == PackageManager.PERMISSION_GRANTED;
8359
8360            final int recentsCount = mRecentTasks.size();
8361            ArrayList<ActivityManager.RecentTaskInfo> res =
8362                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8363
8364            final Set<Integer> includedUsers;
8365            if (includeProfiles) {
8366                includedUsers = getProfileIdsLocked(userId);
8367            } else {
8368                includedUsers = new HashSet<>();
8369            }
8370            includedUsers.add(Integer.valueOf(userId));
8371
8372            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8373                TaskRecord tr = mRecentTasks.get(i);
8374                // Only add calling user or related users recent tasks
8375                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8376                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8377                    continue;
8378                }
8379
8380                // Return the entry if desired by the caller.  We always return
8381                // the first entry, because callers always expect this to be the
8382                // foreground app.  We may filter others if the caller has
8383                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8384                // we should exclude the entry.
8385
8386                if (i == 0
8387                        || withExcluded
8388                        || (tr.intent == null)
8389                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8390                                == 0)) {
8391                    if (!allowed) {
8392                        // If the caller doesn't have the GET_TASKS permission, then only
8393                        // allow them to see a small subset of tasks -- their own and home.
8394                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8395                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8396                            continue;
8397                        }
8398                    }
8399                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8400                        if (tr.stack != null && tr.stack.isHomeStack()) {
8401                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8402                                    "Skipping, home stack task: " + tr);
8403                            continue;
8404                        }
8405                    }
8406                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8407                        // Don't include auto remove tasks that are finished or finishing.
8408                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8409                                "Skipping, auto-remove without activity: " + tr);
8410                        continue;
8411                    }
8412                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8413                            && !tr.isAvailable) {
8414                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8415                                "Skipping, unavail real act: " + tr);
8416                        continue;
8417                    }
8418
8419                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8420                    if (!detailed) {
8421                        rti.baseIntent.replaceExtras((Bundle)null);
8422                    }
8423
8424                    res.add(rti);
8425                    maxNum--;
8426                }
8427            }
8428            return res;
8429        }
8430    }
8431
8432    @Override
8433    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8434        synchronized (this) {
8435            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8436                    "getTaskThumbnail()");
8437            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8438            if (tr != null) {
8439                return tr.getTaskThumbnailLocked();
8440            }
8441        }
8442        return null;
8443    }
8444
8445    @Override
8446    public int addAppTask(IBinder activityToken, Intent intent,
8447            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8448        final int callingUid = Binder.getCallingUid();
8449        final long callingIdent = Binder.clearCallingIdentity();
8450
8451        try {
8452            synchronized (this) {
8453                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8454                if (r == null) {
8455                    throw new IllegalArgumentException("Activity does not exist; token="
8456                            + activityToken);
8457                }
8458                ComponentName comp = intent.getComponent();
8459                if (comp == null) {
8460                    throw new IllegalArgumentException("Intent " + intent
8461                            + " must specify explicit component");
8462                }
8463                if (thumbnail.getWidth() != mThumbnailWidth
8464                        || thumbnail.getHeight() != mThumbnailHeight) {
8465                    throw new IllegalArgumentException("Bad thumbnail size: got "
8466                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8467                            + mThumbnailWidth + "x" + mThumbnailHeight);
8468                }
8469                if (intent.getSelector() != null) {
8470                    intent.setSelector(null);
8471                }
8472                if (intent.getSourceBounds() != null) {
8473                    intent.setSourceBounds(null);
8474                }
8475                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8476                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8477                        // The caller has added this as an auto-remove task...  that makes no
8478                        // sense, so turn off auto-remove.
8479                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8480                    }
8481                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8482                    // Must be a new task.
8483                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8484                }
8485                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8486                    mLastAddedTaskActivity = null;
8487                }
8488                ActivityInfo ainfo = mLastAddedTaskActivity;
8489                if (ainfo == null) {
8490                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8491                            comp, 0, UserHandle.getUserId(callingUid));
8492                    if (ainfo.applicationInfo.uid != callingUid) {
8493                        throw new SecurityException(
8494                                "Can't add task for another application: target uid="
8495                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8496                    }
8497                }
8498
8499                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8500                        intent, description);
8501
8502                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8503                if (trimIdx >= 0) {
8504                    // If this would have caused a trim, then we'll abort because that
8505                    // means it would be added at the end of the list but then just removed.
8506                    return INVALID_TASK_ID;
8507                }
8508
8509                final int N = mRecentTasks.size();
8510                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8511                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8512                    tr.removedFromRecents();
8513                }
8514
8515                task.inRecents = true;
8516                mRecentTasks.add(task);
8517                r.task.stack.addTask(task, false, false);
8518
8519                task.setLastThumbnail(thumbnail);
8520                task.freeLastThumbnail();
8521
8522                return task.taskId;
8523            }
8524        } finally {
8525            Binder.restoreCallingIdentity(callingIdent);
8526        }
8527    }
8528
8529    @Override
8530    public Point getAppTaskThumbnailSize() {
8531        synchronized (this) {
8532            return new Point(mThumbnailWidth,  mThumbnailHeight);
8533        }
8534    }
8535
8536    @Override
8537    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8538        synchronized (this) {
8539            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8540            if (r != null) {
8541                r.setTaskDescription(td);
8542                r.task.updateTaskDescription();
8543            }
8544        }
8545    }
8546
8547    @Override
8548    public void setTaskResizeable(int taskId, boolean resizeable) {
8549        synchronized (this) {
8550            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8551            if (task == null) {
8552                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8553                return;
8554            }
8555            if (task.mResizeable != resizeable) {
8556                task.mResizeable = resizeable;
8557                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8558                mStackSupervisor.resumeTopActivitiesLocked();
8559            }
8560        }
8561    }
8562
8563    @Override
8564    public void resizeTask(int taskId, Rect bounds) {
8565        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8566                "resizeTask()");
8567        long ident = Binder.clearCallingIdentity();
8568        try {
8569            synchronized (this) {
8570                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8571                if (task == null) {
8572                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8573                    return;
8574                }
8575                mStackSupervisor.resizeTaskLocked(task, bounds);
8576            }
8577        } finally {
8578            Binder.restoreCallingIdentity(ident);
8579        }
8580    }
8581
8582    @Override
8583    public Bitmap getTaskDescriptionIcon(String filename) {
8584        if (!FileUtils.isValidExtFilename(filename)
8585                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8586            throw new IllegalArgumentException("Bad filename: " + filename);
8587        }
8588        return mTaskPersister.getTaskDescriptionIcon(filename);
8589    }
8590
8591    @Override
8592    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8593            throws RemoteException {
8594        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8595                opts.getCustomInPlaceResId() == 0) {
8596            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8597                    "with valid animation");
8598        }
8599        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8600        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8601                opts.getCustomInPlaceResId());
8602        mWindowManager.executeAppTransition();
8603    }
8604
8605    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8606        mRecentTasks.remove(tr);
8607        tr.removedFromRecents();
8608        ComponentName component = tr.getBaseIntent().getComponent();
8609        if (component == null) {
8610            Slog.w(TAG, "No component for base intent of task: " + tr);
8611            return;
8612        }
8613
8614        // Find any running services associated with this app and stop if needed.
8615        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8616
8617        if (!killProcess) {
8618            return;
8619        }
8620
8621        // Determine if the process(es) for this task should be killed.
8622        final String pkg = component.getPackageName();
8623        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8624        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8625        for (int i = 0; i < pmap.size(); i++) {
8626
8627            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8628            for (int j = 0; j < uids.size(); j++) {
8629                ProcessRecord proc = uids.valueAt(j);
8630                if (proc.userId != tr.userId) {
8631                    // Don't kill process for a different user.
8632                    continue;
8633                }
8634                if (proc == mHomeProcess) {
8635                    // Don't kill the home process along with tasks from the same package.
8636                    continue;
8637                }
8638                if (!proc.pkgList.containsKey(pkg)) {
8639                    // Don't kill process that is not associated with this task.
8640                    continue;
8641                }
8642
8643                for (int k = 0; k < proc.activities.size(); k++) {
8644                    TaskRecord otherTask = proc.activities.get(k).task;
8645                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8646                        // Don't kill process(es) that has an activity in a different task that is
8647                        // also in recents.
8648                        return;
8649                    }
8650                }
8651
8652                if (proc.foregroundServices) {
8653                    // Don't kill process(es) with foreground service.
8654                    return;
8655                }
8656
8657                // Add process to kill list.
8658                procsToKill.add(proc);
8659            }
8660        }
8661
8662        // Kill the running processes.
8663        for (int i = 0; i < procsToKill.size(); i++) {
8664            ProcessRecord pr = procsToKill.get(i);
8665            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8666                    && pr.curReceiver == null) {
8667                pr.kill("remove task", true);
8668            } else {
8669                // We delay killing processes that are not in the background or running a receiver.
8670                pr.waitingToKill = "remove task";
8671            }
8672        }
8673    }
8674
8675    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8676        // Remove all tasks with activities in the specified package from the list of recent tasks
8677        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8678            TaskRecord tr = mRecentTasks.get(i);
8679            if (tr.userId != userId) continue;
8680
8681            ComponentName cn = tr.intent.getComponent();
8682            if (cn != null && cn.getPackageName().equals(packageName)) {
8683                // If the package name matches, remove the task.
8684                removeTaskByIdLocked(tr.taskId, true);
8685            }
8686        }
8687    }
8688
8689    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8690            int userId) {
8691
8692        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8693            TaskRecord tr = mRecentTasks.get(i);
8694            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8695                continue;
8696            }
8697
8698            ComponentName cn = tr.intent.getComponent();
8699            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8700                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8701            if (sameComponent) {
8702                removeTaskByIdLocked(tr.taskId, false);
8703            }
8704        }
8705    }
8706
8707    /**
8708     * Removes the task with the specified task id.
8709     *
8710     * @param taskId Identifier of the task to be removed.
8711     * @param killProcess Kill any process associated with the task if possible.
8712     * @return Returns true if the given task was found and removed.
8713     */
8714    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8715        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8716        if (tr != null) {
8717            tr.removeTaskActivitiesLocked();
8718            cleanUpRemovedTaskLocked(tr, killProcess);
8719            if (tr.isPersistable) {
8720                notifyTaskPersisterLocked(null, true);
8721            }
8722            return true;
8723        }
8724        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8725        return false;
8726    }
8727
8728    @Override
8729    public boolean removeTask(int taskId) {
8730        synchronized (this) {
8731            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8732                    "removeTask()");
8733            long ident = Binder.clearCallingIdentity();
8734            try {
8735                return removeTaskByIdLocked(taskId, true);
8736            } finally {
8737                Binder.restoreCallingIdentity(ident);
8738            }
8739        }
8740    }
8741
8742    /**
8743     * TODO: Add mController hook
8744     */
8745    @Override
8746    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8747        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8748
8749        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8750        synchronized(this) {
8751            moveTaskToFrontLocked(taskId, flags, options);
8752        }
8753    }
8754
8755    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8756        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8757                Binder.getCallingUid(), -1, -1, "Task to front")) {
8758            ActivityOptions.abort(options);
8759            return;
8760        }
8761        final long origId = Binder.clearCallingIdentity();
8762        try {
8763            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8764            if (task == null) {
8765                Slog.d(TAG, "Could not find task for id: "+ taskId);
8766                return;
8767            }
8768            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8769                mStackSupervisor.showLockTaskToast();
8770                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8771                return;
8772            }
8773            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8774            if (prev != null && prev.isRecentsActivity()) {
8775                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8776            }
8777            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8778        } finally {
8779            Binder.restoreCallingIdentity(origId);
8780        }
8781        ActivityOptions.abort(options);
8782    }
8783
8784    /**
8785     * Moves an activity, and all of the other activities within the same task, to the bottom
8786     * of the history stack.  The activity's order within the task is unchanged.
8787     *
8788     * @param token A reference to the activity we wish to move
8789     * @param nonRoot If false then this only works if the activity is the root
8790     *                of a task; if true it will work for any activity in a task.
8791     * @return Returns true if the move completed, false if not.
8792     */
8793    @Override
8794    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8795        enforceNotIsolatedCaller("moveActivityTaskToBack");
8796        synchronized(this) {
8797            final long origId = Binder.clearCallingIdentity();
8798            try {
8799                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8800                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8801                if (task != null) {
8802                    if (mStackSupervisor.isLockedTask(task)) {
8803                        mStackSupervisor.showLockTaskToast();
8804                        return false;
8805                    }
8806                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8807                }
8808            } finally {
8809                Binder.restoreCallingIdentity(origId);
8810            }
8811        }
8812        return false;
8813    }
8814
8815    @Override
8816    public void moveTaskBackwards(int task) {
8817        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8818                "moveTaskBackwards()");
8819
8820        synchronized(this) {
8821            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8822                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8823                return;
8824            }
8825            final long origId = Binder.clearCallingIdentity();
8826            moveTaskBackwardsLocked(task);
8827            Binder.restoreCallingIdentity(origId);
8828        }
8829    }
8830
8831    private final void moveTaskBackwardsLocked(int task) {
8832        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8833    }
8834
8835    @Override
8836    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8837            IActivityContainerCallback callback) throws RemoteException {
8838        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8839                "createActivityContainer()");
8840        synchronized (this) {
8841            if (parentActivityToken == null) {
8842                throw new IllegalArgumentException("parent token must not be null");
8843            }
8844            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8845            if (r == null) {
8846                return null;
8847            }
8848            if (callback == null) {
8849                throw new IllegalArgumentException("callback must not be null");
8850            }
8851            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8852        }
8853    }
8854
8855    @Override
8856    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8857        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8858                "deleteActivityContainer()");
8859        synchronized (this) {
8860            mStackSupervisor.deleteActivityContainer(container);
8861        }
8862    }
8863
8864    @Override
8865    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8866        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8867                "createStackOnDisplay()");
8868        synchronized (this) {
8869            final int stackId = mStackSupervisor.getNextStackId();
8870            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8871            if (stack == null) {
8872                return null;
8873            }
8874            return stack.mActivityContainer;
8875        }
8876    }
8877
8878    @Override
8879    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8880        synchronized (this) {
8881            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8882            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8883                return stack.mActivityContainer.getDisplayId();
8884            }
8885            return Display.DEFAULT_DISPLAY;
8886        }
8887    }
8888
8889    @Override
8890    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8891        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8892                "moveTaskToStack()");
8893        if (stackId == HOME_STACK_ID) {
8894            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8895                    new RuntimeException("here").fillInStackTrace());
8896        }
8897        synchronized (this) {
8898            long ident = Binder.clearCallingIdentity();
8899            try {
8900                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8901                        + " to stackId=" + stackId + " toTop=" + toTop);
8902                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8903            } finally {
8904                Binder.restoreCallingIdentity(ident);
8905            }
8906        }
8907    }
8908
8909    @Override
8910    public void resizeStack(int stackId, Rect bounds) {
8911        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8912                "resizeStack()");
8913        long ident = Binder.clearCallingIdentity();
8914        try {
8915            synchronized (this) {
8916                mStackSupervisor.resizeStackLocked(stackId, bounds);
8917            }
8918        } finally {
8919            Binder.restoreCallingIdentity(ident);
8920        }
8921    }
8922
8923    @Override
8924    public List<StackInfo> getAllStackInfos() {
8925        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8926                "getAllStackInfos()");
8927        long ident = Binder.clearCallingIdentity();
8928        try {
8929            synchronized (this) {
8930                return mStackSupervisor.getAllStackInfosLocked();
8931            }
8932        } finally {
8933            Binder.restoreCallingIdentity(ident);
8934        }
8935    }
8936
8937    @Override
8938    public StackInfo getStackInfo(int stackId) {
8939        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8940                "getStackInfo()");
8941        long ident = Binder.clearCallingIdentity();
8942        try {
8943            synchronized (this) {
8944                return mStackSupervisor.getStackInfoLocked(stackId);
8945            }
8946        } finally {
8947            Binder.restoreCallingIdentity(ident);
8948        }
8949    }
8950
8951    @Override
8952    public boolean isInHomeStack(int taskId) {
8953        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8954                "getStackInfo()");
8955        long ident = Binder.clearCallingIdentity();
8956        try {
8957            synchronized (this) {
8958                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8959                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8960            }
8961        } finally {
8962            Binder.restoreCallingIdentity(ident);
8963        }
8964    }
8965
8966    @Override
8967    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8968        synchronized(this) {
8969            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8970        }
8971    }
8972
8973    @Override
8974    public void updateDeviceOwner(String packageName) {
8975        final int callingUid = Binder.getCallingUid();
8976        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8977            throw new SecurityException("updateDeviceOwner called from non-system process");
8978        }
8979        synchronized (this) {
8980            mDeviceOwnerName = packageName;
8981        }
8982    }
8983
8984    @Override
8985    public void updateLockTaskPackages(int userId, String[] packages) {
8986        final int callingUid = Binder.getCallingUid();
8987        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8988            throw new SecurityException("updateLockTaskPackage called from non-system process");
8989        }
8990        synchronized (this) {
8991            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8992                    Arrays.toString(packages));
8993            mLockTaskPackages.put(userId, packages);
8994            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8995        }
8996    }
8997
8998
8999    void startLockTaskModeLocked(TaskRecord task) {
9000        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9001        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9002            return;
9003        }
9004
9005        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9006        // is initiated by system after the pinning request was shown and locked mode is initiated
9007        // by an authorized app directly
9008        final int callingUid = Binder.getCallingUid();
9009        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9010        long ident = Binder.clearCallingIdentity();
9011        try {
9012            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9013            if (!isSystemInitiated) {
9014                task.mLockTaskUid = callingUid;
9015                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9016                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9017                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9018                    StatusBarManagerInternal statusBarManager =
9019                            LocalServices.getService(StatusBarManagerInternal.class);
9020                    if (statusBarManager != null) {
9021                        statusBarManager.showScreenPinningRequest();
9022                    }
9023                    return;
9024                }
9025
9026                if (stack == null || task != stack.topTask()) {
9027                    throw new IllegalArgumentException("Invalid task, not in foreground");
9028                }
9029            }
9030            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9031                    "Locking fully");
9032            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9033                    ActivityManager.LOCK_TASK_MODE_PINNED :
9034                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9035                    "startLockTask", true);
9036        } finally {
9037            Binder.restoreCallingIdentity(ident);
9038        }
9039    }
9040
9041    @Override
9042    public void startLockTaskMode(int taskId) {
9043        synchronized (this) {
9044            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9045            if (task != null) {
9046                startLockTaskModeLocked(task);
9047            }
9048        }
9049    }
9050
9051    @Override
9052    public void startLockTaskMode(IBinder token) {
9053        synchronized (this) {
9054            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9055            if (r == null) {
9056                return;
9057            }
9058            final TaskRecord task = r.task;
9059            if (task != null) {
9060                startLockTaskModeLocked(task);
9061            }
9062        }
9063    }
9064
9065    @Override
9066    public void startLockTaskModeOnCurrent() throws RemoteException {
9067        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9068                "startLockTaskModeOnCurrent");
9069        long ident = Binder.clearCallingIdentity();
9070        try {
9071            synchronized (this) {
9072                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9073                if (r != null) {
9074                    startLockTaskModeLocked(r.task);
9075                }
9076            }
9077        } finally {
9078            Binder.restoreCallingIdentity(ident);
9079        }
9080    }
9081
9082    @Override
9083    public void stopLockTaskMode() {
9084        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9085        if (lockTask == null) {
9086            // Our work here is done.
9087            return;
9088        }
9089
9090        final int callingUid = Binder.getCallingUid();
9091        final int lockTaskUid = lockTask.mLockTaskUid;
9092        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9093        // It is possible lockTaskMode was started by the system process because
9094        // android:lockTaskMode is set to a locking value in the application manifest instead of
9095        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9096        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9097        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9098                callingUid != lockTaskUid
9099                && (lockTaskUid != 0
9100                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9101            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9102                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9103        }
9104
9105        long ident = Binder.clearCallingIdentity();
9106        try {
9107            Log.d(TAG, "stopLockTaskMode");
9108            // Stop lock task
9109            synchronized (this) {
9110                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9111                        "stopLockTask", true);
9112            }
9113        } finally {
9114            Binder.restoreCallingIdentity(ident);
9115        }
9116    }
9117
9118    @Override
9119    public void stopLockTaskModeOnCurrent() throws RemoteException {
9120        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9121                "stopLockTaskModeOnCurrent");
9122        long ident = Binder.clearCallingIdentity();
9123        try {
9124            stopLockTaskMode();
9125        } finally {
9126            Binder.restoreCallingIdentity(ident);
9127        }
9128    }
9129
9130    @Override
9131    public boolean isInLockTaskMode() {
9132        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9133    }
9134
9135    @Override
9136    public int getLockTaskModeState() {
9137        synchronized (this) {
9138            return mStackSupervisor.getLockTaskModeState();
9139        }
9140    }
9141
9142    @Override
9143    public void showLockTaskEscapeMessage(IBinder token) {
9144        synchronized (this) {
9145            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9146            if (r == null) {
9147                return;
9148            }
9149            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9150        }
9151    }
9152
9153    // =========================================================
9154    // CONTENT PROVIDERS
9155    // =========================================================
9156
9157    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9158        List<ProviderInfo> providers = null;
9159        try {
9160            providers = AppGlobals.getPackageManager().
9161                queryContentProviders(app.processName, app.uid,
9162                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9163        } catch (RemoteException ex) {
9164        }
9165        if (DEBUG_MU) Slog.v(TAG_MU,
9166                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9167        int userId = app.userId;
9168        if (providers != null) {
9169            int N = providers.size();
9170            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9171            for (int i=0; i<N; i++) {
9172                ProviderInfo cpi =
9173                    (ProviderInfo)providers.get(i);
9174                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9175                        cpi.name, cpi.flags);
9176                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9177                    // This is a singleton provider, but a user besides the
9178                    // default user is asking to initialize a process it runs
9179                    // in...  well, no, it doesn't actually run in this process,
9180                    // it runs in the process of the default user.  Get rid of it.
9181                    providers.remove(i);
9182                    N--;
9183                    i--;
9184                    continue;
9185                }
9186
9187                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9188                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9189                if (cpr == null) {
9190                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9191                    mProviderMap.putProviderByClass(comp, cpr);
9192                }
9193                if (DEBUG_MU) Slog.v(TAG_MU,
9194                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9195                app.pubProviders.put(cpi.name, cpr);
9196                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9197                    // Don't add this if it is a platform component that is marked
9198                    // to run in multiple processes, because this is actually
9199                    // part of the framework so doesn't make sense to track as a
9200                    // separate apk in the process.
9201                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9202                            mProcessStats);
9203                }
9204                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9205            }
9206        }
9207        return providers;
9208    }
9209
9210    /**
9211     * Check if {@link ProcessRecord} has a possible chance at accessing the
9212     * given {@link ProviderInfo}. Final permission checking is always done
9213     * in {@link ContentProvider}.
9214     */
9215    private final String checkContentProviderPermissionLocked(
9216            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9217        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9218        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9219        boolean checkedGrants = false;
9220        if (checkUser) {
9221            // Looking for cross-user grants before enforcing the typical cross-users permissions
9222            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9223            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9224                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9225                    return null;
9226                }
9227                checkedGrants = true;
9228            }
9229            userId = handleIncomingUser(callingPid, callingUid, userId,
9230                    false, ALLOW_NON_FULL,
9231                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9232            if (userId != tmpTargetUserId) {
9233                // When we actually went to determine the final targer user ID, this ended
9234                // up different than our initial check for the authority.  This is because
9235                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9236                // SELF.  So we need to re-check the grants again.
9237                checkedGrants = false;
9238            }
9239        }
9240        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9241                cpi.applicationInfo.uid, cpi.exported)
9242                == PackageManager.PERMISSION_GRANTED) {
9243            return null;
9244        }
9245        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9246                cpi.applicationInfo.uid, cpi.exported)
9247                == PackageManager.PERMISSION_GRANTED) {
9248            return null;
9249        }
9250
9251        PathPermission[] pps = cpi.pathPermissions;
9252        if (pps != null) {
9253            int i = pps.length;
9254            while (i > 0) {
9255                i--;
9256                PathPermission pp = pps[i];
9257                String pprperm = pp.getReadPermission();
9258                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9259                        cpi.applicationInfo.uid, cpi.exported)
9260                        == PackageManager.PERMISSION_GRANTED) {
9261                    return null;
9262                }
9263                String ppwperm = pp.getWritePermission();
9264                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9265                        cpi.applicationInfo.uid, cpi.exported)
9266                        == PackageManager.PERMISSION_GRANTED) {
9267                    return null;
9268                }
9269            }
9270        }
9271        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9272            return null;
9273        }
9274
9275        String msg;
9276        if (!cpi.exported) {
9277            msg = "Permission Denial: opening provider " + cpi.name
9278                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9279                    + ", uid=" + callingUid + ") that is not exported from uid "
9280                    + cpi.applicationInfo.uid;
9281        } else {
9282            msg = "Permission Denial: opening provider " + cpi.name
9283                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9284                    + ", uid=" + callingUid + ") requires "
9285                    + cpi.readPermission + " or " + cpi.writePermission;
9286        }
9287        Slog.w(TAG, msg);
9288        return msg;
9289    }
9290
9291    /**
9292     * Returns if the ContentProvider has granted a uri to callingUid
9293     */
9294    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9295        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9296        if (perms != null) {
9297            for (int i=perms.size()-1; i>=0; i--) {
9298                GrantUri grantUri = perms.keyAt(i);
9299                if (grantUri.sourceUserId == userId || !checkUser) {
9300                    if (matchesProvider(grantUri.uri, cpi)) {
9301                        return true;
9302                    }
9303                }
9304            }
9305        }
9306        return false;
9307    }
9308
9309    /**
9310     * Returns true if the uri authority is one of the authorities specified in the provider.
9311     */
9312    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9313        String uriAuth = uri.getAuthority();
9314        String cpiAuth = cpi.authority;
9315        if (cpiAuth.indexOf(';') == -1) {
9316            return cpiAuth.equals(uriAuth);
9317        }
9318        String[] cpiAuths = cpiAuth.split(";");
9319        int length = cpiAuths.length;
9320        for (int i = 0; i < length; i++) {
9321            if (cpiAuths[i].equals(uriAuth)) return true;
9322        }
9323        return false;
9324    }
9325
9326    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9327            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9328        if (r != null) {
9329            for (int i=0; i<r.conProviders.size(); i++) {
9330                ContentProviderConnection conn = r.conProviders.get(i);
9331                if (conn.provider == cpr) {
9332                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9333                            "Adding provider requested by "
9334                            + r.processName + " from process "
9335                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9336                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9337                    if (stable) {
9338                        conn.stableCount++;
9339                        conn.numStableIncs++;
9340                    } else {
9341                        conn.unstableCount++;
9342                        conn.numUnstableIncs++;
9343                    }
9344                    return conn;
9345                }
9346            }
9347            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9348            if (stable) {
9349                conn.stableCount = 1;
9350                conn.numStableIncs = 1;
9351            } else {
9352                conn.unstableCount = 1;
9353                conn.numUnstableIncs = 1;
9354            }
9355            cpr.connections.add(conn);
9356            r.conProviders.add(conn);
9357            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9358            return conn;
9359        }
9360        cpr.addExternalProcessHandleLocked(externalProcessToken);
9361        return null;
9362    }
9363
9364    boolean decProviderCountLocked(ContentProviderConnection conn,
9365            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9366        if (conn != null) {
9367            cpr = conn.provider;
9368            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9369                    "Removing provider requested by "
9370                    + conn.client.processName + " from process "
9371                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9372                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9373            if (stable) {
9374                conn.stableCount--;
9375            } else {
9376                conn.unstableCount--;
9377            }
9378            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9379                cpr.connections.remove(conn);
9380                conn.client.conProviders.remove(conn);
9381                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9382                return true;
9383            }
9384            return false;
9385        }
9386        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9387        return false;
9388    }
9389
9390    private void checkTime(long startTime, String where) {
9391        long now = SystemClock.elapsedRealtime();
9392        if ((now-startTime) > 1000) {
9393            // If we are taking more than a second, log about it.
9394            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9395        }
9396    }
9397
9398    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9399            String name, IBinder token, boolean stable, int userId) {
9400        ContentProviderRecord cpr;
9401        ContentProviderConnection conn = null;
9402        ProviderInfo cpi = null;
9403
9404        synchronized(this) {
9405            long startTime = SystemClock.elapsedRealtime();
9406
9407            ProcessRecord r = null;
9408            if (caller != null) {
9409                r = getRecordForAppLocked(caller);
9410                if (r == null) {
9411                    throw new SecurityException(
9412                            "Unable to find app for caller " + caller
9413                          + " (pid=" + Binder.getCallingPid()
9414                          + ") when getting content provider " + name);
9415                }
9416            }
9417
9418            boolean checkCrossUser = true;
9419
9420            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9421
9422            // First check if this content provider has been published...
9423            cpr = mProviderMap.getProviderByName(name, userId);
9424            // If that didn't work, check if it exists for user 0 and then
9425            // verify that it's a singleton provider before using it.
9426            if (cpr == null && userId != UserHandle.USER_OWNER) {
9427                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9428                if (cpr != null) {
9429                    cpi = cpr.info;
9430                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9431                            cpi.name, cpi.flags)
9432                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9433                        userId = UserHandle.USER_OWNER;
9434                        checkCrossUser = false;
9435                    } else {
9436                        cpr = null;
9437                        cpi = null;
9438                    }
9439                }
9440            }
9441
9442            boolean providerRunning = cpr != null;
9443            if (providerRunning) {
9444                cpi = cpr.info;
9445                String msg;
9446                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9447                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9448                        != null) {
9449                    throw new SecurityException(msg);
9450                }
9451                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9452
9453                if (r != null && cpr.canRunHere(r)) {
9454                    // This provider has been published or is in the process
9455                    // of being published...  but it is also allowed to run
9456                    // in the caller's process, so don't make a connection
9457                    // and just let the caller instantiate its own instance.
9458                    ContentProviderHolder holder = cpr.newHolder(null);
9459                    // don't give caller the provider object, it needs
9460                    // to make its own.
9461                    holder.provider = null;
9462                    return holder;
9463                }
9464
9465                final long origId = Binder.clearCallingIdentity();
9466
9467                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9468
9469                // In this case the provider instance already exists, so we can
9470                // return it right away.
9471                conn = incProviderCountLocked(r, cpr, token, stable);
9472                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9473                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9474                        // If this is a perceptible app accessing the provider,
9475                        // make sure to count it as being accessed and thus
9476                        // back up on the LRU list.  This is good because
9477                        // content providers are often expensive to start.
9478                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9479                        updateLruProcessLocked(cpr.proc, false, null);
9480                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9481                    }
9482                }
9483
9484                if (cpr.proc != null) {
9485                    if (false) {
9486                        if (cpr.name.flattenToShortString().equals(
9487                                "com.android.providers.calendar/.CalendarProvider2")) {
9488                            Slog.v(TAG, "****************** KILLING "
9489                                + cpr.name.flattenToShortString());
9490                            Process.killProcess(cpr.proc.pid);
9491                        }
9492                    }
9493                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9494                    boolean success = updateOomAdjLocked(cpr.proc);
9495                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9496                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9497                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9498                    // NOTE: there is still a race here where a signal could be
9499                    // pending on the process even though we managed to update its
9500                    // adj level.  Not sure what to do about this, but at least
9501                    // the race is now smaller.
9502                    if (!success) {
9503                        // Uh oh...  it looks like the provider's process
9504                        // has been killed on us.  We need to wait for a new
9505                        // process to be started, and make sure its death
9506                        // doesn't kill our process.
9507                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9508                                + " is crashing; detaching " + r);
9509                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9510                        checkTime(startTime, "getContentProviderImpl: before appDied");
9511                        appDiedLocked(cpr.proc);
9512                        checkTime(startTime, "getContentProviderImpl: after appDied");
9513                        if (!lastRef) {
9514                            // This wasn't the last ref our process had on
9515                            // the provider...  we have now been killed, bail.
9516                            return null;
9517                        }
9518                        providerRunning = false;
9519                        conn = null;
9520                    }
9521                }
9522
9523                Binder.restoreCallingIdentity(origId);
9524            }
9525
9526            boolean singleton;
9527            if (!providerRunning) {
9528                try {
9529                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9530                    cpi = AppGlobals.getPackageManager().
9531                        resolveContentProvider(name,
9532                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9533                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9534                } catch (RemoteException ex) {
9535                }
9536                if (cpi == null) {
9537                    return null;
9538                }
9539                // If the provider is a singleton AND
9540                // (it's a call within the same user || the provider is a
9541                // privileged app)
9542                // Then allow connecting to the singleton provider
9543                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9544                        cpi.name, cpi.flags)
9545                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9546                if (singleton) {
9547                    userId = UserHandle.USER_OWNER;
9548                }
9549                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9550                checkTime(startTime, "getContentProviderImpl: got app info for user");
9551
9552                String msg;
9553                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9554                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9555                        != null) {
9556                    throw new SecurityException(msg);
9557                }
9558                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9559
9560                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9561                        && !cpi.processName.equals("system")) {
9562                    // If this content provider does not run in the system
9563                    // process, and the system is not yet ready to run other
9564                    // processes, then fail fast instead of hanging.
9565                    throw new IllegalArgumentException(
9566                            "Attempt to launch content provider before system ready");
9567                }
9568
9569                // Make sure that the user who owns this provider is running.  If not,
9570                // we don't want to allow it to run.
9571                if (!isUserRunningLocked(userId, false)) {
9572                    Slog.w(TAG, "Unable to launch app "
9573                            + cpi.applicationInfo.packageName + "/"
9574                            + cpi.applicationInfo.uid + " for provider "
9575                            + name + ": user " + userId + " is stopped");
9576                    return null;
9577                }
9578
9579                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9580                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9581                cpr = mProviderMap.getProviderByClass(comp, userId);
9582                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9583                final boolean firstClass = cpr == null;
9584                if (firstClass) {
9585                    final long ident = Binder.clearCallingIdentity();
9586                    try {
9587                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9588                        ApplicationInfo ai =
9589                            AppGlobals.getPackageManager().
9590                                getApplicationInfo(
9591                                        cpi.applicationInfo.packageName,
9592                                        STOCK_PM_FLAGS, userId);
9593                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9594                        if (ai == null) {
9595                            Slog.w(TAG, "No package info for content provider "
9596                                    + cpi.name);
9597                            return null;
9598                        }
9599                        ai = getAppInfoForUser(ai, userId);
9600                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9601                    } catch (RemoteException ex) {
9602                        // pm is in same process, this will never happen.
9603                    } finally {
9604                        Binder.restoreCallingIdentity(ident);
9605                    }
9606                }
9607
9608                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9609
9610                if (r != null && cpr.canRunHere(r)) {
9611                    // If this is a multiprocess provider, then just return its
9612                    // info and allow the caller to instantiate it.  Only do
9613                    // this if the provider is the same user as the caller's
9614                    // process, or can run as root (so can be in any process).
9615                    return cpr.newHolder(null);
9616                }
9617
9618                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9619                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9620                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9621
9622                // This is single process, and our app is now connecting to it.
9623                // See if we are already in the process of launching this
9624                // provider.
9625                final int N = mLaunchingProviders.size();
9626                int i;
9627                for (i = 0; i < N; i++) {
9628                    if (mLaunchingProviders.get(i) == cpr) {
9629                        break;
9630                    }
9631                }
9632
9633                // If the provider is not already being launched, then get it
9634                // started.
9635                if (i >= N) {
9636                    final long origId = Binder.clearCallingIdentity();
9637
9638                    try {
9639                        // Content provider is now in use, its package can't be stopped.
9640                        try {
9641                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9642                            AppGlobals.getPackageManager().setPackageStoppedState(
9643                                    cpr.appInfo.packageName, false, userId);
9644                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9645                        } catch (RemoteException e) {
9646                        } catch (IllegalArgumentException e) {
9647                            Slog.w(TAG, "Failed trying to unstop package "
9648                                    + cpr.appInfo.packageName + ": " + e);
9649                        }
9650
9651                        // Use existing process if already started
9652                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9653                        ProcessRecord proc = getProcessRecordLocked(
9654                                cpi.processName, cpr.appInfo.uid, false);
9655                        if (proc != null && proc.thread != null) {
9656                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9657                                    "Installing in existing process " + proc);
9658                            if (!proc.pubProviders.containsKey(cpi.name)) {
9659                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9660                                proc.pubProviders.put(cpi.name, cpr);
9661                                try {
9662                                    proc.thread.scheduleInstallProvider(cpi);
9663                                } catch (RemoteException e) {
9664                                }
9665                            }
9666                        } else {
9667                            checkTime(startTime, "getContentProviderImpl: before start process");
9668                            proc = startProcessLocked(cpi.processName,
9669                                    cpr.appInfo, false, 0, "content provider",
9670                                    new ComponentName(cpi.applicationInfo.packageName,
9671                                            cpi.name), false, false, false);
9672                            checkTime(startTime, "getContentProviderImpl: after start process");
9673                            if (proc == null) {
9674                                Slog.w(TAG, "Unable to launch app "
9675                                        + cpi.applicationInfo.packageName + "/"
9676                                        + cpi.applicationInfo.uid + " for provider "
9677                                        + name + ": process is bad");
9678                                return null;
9679                            }
9680                        }
9681                        cpr.launchingApp = proc;
9682                        mLaunchingProviders.add(cpr);
9683                    } finally {
9684                        Binder.restoreCallingIdentity(origId);
9685                    }
9686                }
9687
9688                checkTime(startTime, "getContentProviderImpl: updating data structures");
9689
9690                // Make sure the provider is published (the same provider class
9691                // may be published under multiple names).
9692                if (firstClass) {
9693                    mProviderMap.putProviderByClass(comp, cpr);
9694                }
9695
9696                mProviderMap.putProviderByName(name, cpr);
9697                conn = incProviderCountLocked(r, cpr, token, stable);
9698                if (conn != null) {
9699                    conn.waiting = true;
9700                }
9701            }
9702            checkTime(startTime, "getContentProviderImpl: done!");
9703        }
9704
9705        // Wait for the provider to be published...
9706        synchronized (cpr) {
9707            while (cpr.provider == null) {
9708                if (cpr.launchingApp == null) {
9709                    Slog.w(TAG, "Unable to launch app "
9710                            + cpi.applicationInfo.packageName + "/"
9711                            + cpi.applicationInfo.uid + " for provider "
9712                            + name + ": launching app became null");
9713                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9714                            UserHandle.getUserId(cpi.applicationInfo.uid),
9715                            cpi.applicationInfo.packageName,
9716                            cpi.applicationInfo.uid, name);
9717                    return null;
9718                }
9719                try {
9720                    if (DEBUG_MU) Slog.v(TAG_MU,
9721                            "Waiting to start provider " + cpr
9722                            + " launchingApp=" + cpr.launchingApp);
9723                    if (conn != null) {
9724                        conn.waiting = true;
9725                    }
9726                    cpr.wait();
9727                } catch (InterruptedException ex) {
9728                } finally {
9729                    if (conn != null) {
9730                        conn.waiting = false;
9731                    }
9732                }
9733            }
9734        }
9735        return cpr != null ? cpr.newHolder(conn) : null;
9736    }
9737
9738    @Override
9739    public final ContentProviderHolder getContentProvider(
9740            IApplicationThread caller, String name, int userId, boolean stable) {
9741        enforceNotIsolatedCaller("getContentProvider");
9742        if (caller == null) {
9743            String msg = "null IApplicationThread when getting content provider "
9744                    + name;
9745            Slog.w(TAG, msg);
9746            throw new SecurityException(msg);
9747        }
9748        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9749        // with cross-user grant.
9750        return getContentProviderImpl(caller, name, null, stable, userId);
9751    }
9752
9753    public ContentProviderHolder getContentProviderExternal(
9754            String name, int userId, IBinder token) {
9755        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9756            "Do not have permission in call getContentProviderExternal()");
9757        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9758                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9759        return getContentProviderExternalUnchecked(name, token, userId);
9760    }
9761
9762    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9763            IBinder token, int userId) {
9764        return getContentProviderImpl(null, name, token, true, userId);
9765    }
9766
9767    /**
9768     * Drop a content provider from a ProcessRecord's bookkeeping
9769     */
9770    public void removeContentProvider(IBinder connection, boolean stable) {
9771        enforceNotIsolatedCaller("removeContentProvider");
9772        long ident = Binder.clearCallingIdentity();
9773        try {
9774            synchronized (this) {
9775                ContentProviderConnection conn;
9776                try {
9777                    conn = (ContentProviderConnection)connection;
9778                } catch (ClassCastException e) {
9779                    String msg ="removeContentProvider: " + connection
9780                            + " not a ContentProviderConnection";
9781                    Slog.w(TAG, msg);
9782                    throw new IllegalArgumentException(msg);
9783                }
9784                if (conn == null) {
9785                    throw new NullPointerException("connection is null");
9786                }
9787                if (decProviderCountLocked(conn, null, null, stable)) {
9788                    updateOomAdjLocked();
9789                }
9790            }
9791        } finally {
9792            Binder.restoreCallingIdentity(ident);
9793        }
9794    }
9795
9796    public void removeContentProviderExternal(String name, IBinder token) {
9797        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9798            "Do not have permission in call removeContentProviderExternal()");
9799        int userId = UserHandle.getCallingUserId();
9800        long ident = Binder.clearCallingIdentity();
9801        try {
9802            removeContentProviderExternalUnchecked(name, token, userId);
9803        } finally {
9804            Binder.restoreCallingIdentity(ident);
9805        }
9806    }
9807
9808    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9809        synchronized (this) {
9810            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9811            if(cpr == null) {
9812                //remove from mProvidersByClass
9813                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9814                return;
9815            }
9816
9817            //update content provider record entry info
9818            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9819            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9820            if (localCpr.hasExternalProcessHandles()) {
9821                if (localCpr.removeExternalProcessHandleLocked(token)) {
9822                    updateOomAdjLocked();
9823                } else {
9824                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9825                            + " with no external reference for token: "
9826                            + token + ".");
9827                }
9828            } else {
9829                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9830                        + " with no external references.");
9831            }
9832        }
9833    }
9834
9835    public final void publishContentProviders(IApplicationThread caller,
9836            List<ContentProviderHolder> providers) {
9837        if (providers == null) {
9838            return;
9839        }
9840
9841        enforceNotIsolatedCaller("publishContentProviders");
9842        synchronized (this) {
9843            final ProcessRecord r = getRecordForAppLocked(caller);
9844            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9845            if (r == null) {
9846                throw new SecurityException(
9847                        "Unable to find app for caller " + caller
9848                      + " (pid=" + Binder.getCallingPid()
9849                      + ") when publishing content providers");
9850            }
9851
9852            final long origId = Binder.clearCallingIdentity();
9853
9854            final int N = providers.size();
9855            for (int i=0; i<N; i++) {
9856                ContentProviderHolder src = providers.get(i);
9857                if (src == null || src.info == null || src.provider == null) {
9858                    continue;
9859                }
9860                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9861                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9862                if (dst != null) {
9863                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9864                    mProviderMap.putProviderByClass(comp, dst);
9865                    String names[] = dst.info.authority.split(";");
9866                    for (int j = 0; j < names.length; j++) {
9867                        mProviderMap.putProviderByName(names[j], dst);
9868                    }
9869
9870                    int NL = mLaunchingProviders.size();
9871                    int j;
9872                    for (j=0; j<NL; j++) {
9873                        if (mLaunchingProviders.get(j) == dst) {
9874                            mLaunchingProviders.remove(j);
9875                            j--;
9876                            NL--;
9877                        }
9878                    }
9879                    synchronized (dst) {
9880                        dst.provider = src.provider;
9881                        dst.proc = r;
9882                        dst.notifyAll();
9883                    }
9884                    updateOomAdjLocked(r);
9885                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9886                            src.info.authority);
9887                }
9888            }
9889
9890            Binder.restoreCallingIdentity(origId);
9891        }
9892    }
9893
9894    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9895        ContentProviderConnection conn;
9896        try {
9897            conn = (ContentProviderConnection)connection;
9898        } catch (ClassCastException e) {
9899            String msg ="refContentProvider: " + connection
9900                    + " not a ContentProviderConnection";
9901            Slog.w(TAG, msg);
9902            throw new IllegalArgumentException(msg);
9903        }
9904        if (conn == null) {
9905            throw new NullPointerException("connection is null");
9906        }
9907
9908        synchronized (this) {
9909            if (stable > 0) {
9910                conn.numStableIncs += stable;
9911            }
9912            stable = conn.stableCount + stable;
9913            if (stable < 0) {
9914                throw new IllegalStateException("stableCount < 0: " + stable);
9915            }
9916
9917            if (unstable > 0) {
9918                conn.numUnstableIncs += unstable;
9919            }
9920            unstable = conn.unstableCount + unstable;
9921            if (unstable < 0) {
9922                throw new IllegalStateException("unstableCount < 0: " + unstable);
9923            }
9924
9925            if ((stable+unstable) <= 0) {
9926                throw new IllegalStateException("ref counts can't go to zero here: stable="
9927                        + stable + " unstable=" + unstable);
9928            }
9929            conn.stableCount = stable;
9930            conn.unstableCount = unstable;
9931            return !conn.dead;
9932        }
9933    }
9934
9935    public void unstableProviderDied(IBinder connection) {
9936        ContentProviderConnection conn;
9937        try {
9938            conn = (ContentProviderConnection)connection;
9939        } catch (ClassCastException e) {
9940            String msg ="refContentProvider: " + connection
9941                    + " not a ContentProviderConnection";
9942            Slog.w(TAG, msg);
9943            throw new IllegalArgumentException(msg);
9944        }
9945        if (conn == null) {
9946            throw new NullPointerException("connection is null");
9947        }
9948
9949        // Safely retrieve the content provider associated with the connection.
9950        IContentProvider provider;
9951        synchronized (this) {
9952            provider = conn.provider.provider;
9953        }
9954
9955        if (provider == null) {
9956            // Um, yeah, we're way ahead of you.
9957            return;
9958        }
9959
9960        // Make sure the caller is being honest with us.
9961        if (provider.asBinder().pingBinder()) {
9962            // Er, no, still looks good to us.
9963            synchronized (this) {
9964                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9965                        + " says " + conn + " died, but we don't agree");
9966                return;
9967            }
9968        }
9969
9970        // Well look at that!  It's dead!
9971        synchronized (this) {
9972            if (conn.provider.provider != provider) {
9973                // But something changed...  good enough.
9974                return;
9975            }
9976
9977            ProcessRecord proc = conn.provider.proc;
9978            if (proc == null || proc.thread == null) {
9979                // Seems like the process is already cleaned up.
9980                return;
9981            }
9982
9983            // As far as we're concerned, this is just like receiving a
9984            // death notification...  just a bit prematurely.
9985            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9986                    + ") early provider death");
9987            final long ident = Binder.clearCallingIdentity();
9988            try {
9989                appDiedLocked(proc);
9990            } finally {
9991                Binder.restoreCallingIdentity(ident);
9992            }
9993        }
9994    }
9995
9996    @Override
9997    public void appNotRespondingViaProvider(IBinder connection) {
9998        enforceCallingPermission(
9999                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10000
10001        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10002        if (conn == null) {
10003            Slog.w(TAG, "ContentProviderConnection is null");
10004            return;
10005        }
10006
10007        final ProcessRecord host = conn.provider.proc;
10008        if (host == null) {
10009            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10010            return;
10011        }
10012
10013        final long token = Binder.clearCallingIdentity();
10014        try {
10015            appNotResponding(host, null, null, false, "ContentProvider not responding");
10016        } finally {
10017            Binder.restoreCallingIdentity(token);
10018        }
10019    }
10020
10021    public final void installSystemProviders() {
10022        List<ProviderInfo> providers;
10023        synchronized (this) {
10024            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10025            providers = generateApplicationProvidersLocked(app);
10026            if (providers != null) {
10027                for (int i=providers.size()-1; i>=0; i--) {
10028                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10029                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10030                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10031                                + ": not system .apk");
10032                        providers.remove(i);
10033                    }
10034                }
10035            }
10036        }
10037        if (providers != null) {
10038            mSystemThread.installSystemProviders(providers);
10039        }
10040
10041        mCoreSettingsObserver = new CoreSettingsObserver(this);
10042
10043        //mUsageStatsService.monitorPackages();
10044    }
10045
10046    /**
10047     * Allows apps to retrieve the MIME type of a URI.
10048     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10049     * users, then it does not need permission to access the ContentProvider.
10050     * Either, it needs cross-user uri grants.
10051     *
10052     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10053     *
10054     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10055     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10056     */
10057    public String getProviderMimeType(Uri uri, int userId) {
10058        enforceNotIsolatedCaller("getProviderMimeType");
10059        final String name = uri.getAuthority();
10060        int callingUid = Binder.getCallingUid();
10061        int callingPid = Binder.getCallingPid();
10062        long ident = 0;
10063        boolean clearedIdentity = false;
10064        userId = unsafeConvertIncomingUser(userId);
10065        if (canClearIdentity(callingPid, callingUid, userId)) {
10066            clearedIdentity = true;
10067            ident = Binder.clearCallingIdentity();
10068        }
10069        ContentProviderHolder holder = null;
10070        try {
10071            holder = getContentProviderExternalUnchecked(name, null, userId);
10072            if (holder != null) {
10073                return holder.provider.getType(uri);
10074            }
10075        } catch (RemoteException e) {
10076            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10077            return null;
10078        } finally {
10079            // We need to clear the identity to call removeContentProviderExternalUnchecked
10080            if (!clearedIdentity) {
10081                ident = Binder.clearCallingIdentity();
10082            }
10083            try {
10084                if (holder != null) {
10085                    removeContentProviderExternalUnchecked(name, null, userId);
10086                }
10087            } finally {
10088                Binder.restoreCallingIdentity(ident);
10089            }
10090        }
10091
10092        return null;
10093    }
10094
10095    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10096        if (UserHandle.getUserId(callingUid) == userId) {
10097            return true;
10098        }
10099        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10100                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10101                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10102                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10103                return true;
10104        }
10105        return false;
10106    }
10107
10108    // =========================================================
10109    // GLOBAL MANAGEMENT
10110    // =========================================================
10111
10112    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10113            boolean isolated, int isolatedUid) {
10114        String proc = customProcess != null ? customProcess : info.processName;
10115        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10116        final int userId = UserHandle.getUserId(info.uid);
10117        int uid = info.uid;
10118        if (isolated) {
10119            if (isolatedUid == 0) {
10120                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10121                while (true) {
10122                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10123                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10124                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10125                    }
10126                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10127                    mNextIsolatedProcessUid++;
10128                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10129                        // No process for this uid, use it.
10130                        break;
10131                    }
10132                    stepsLeft--;
10133                    if (stepsLeft <= 0) {
10134                        return null;
10135                    }
10136                }
10137            } else {
10138                // Special case for startIsolatedProcess (internal only), where
10139                // the uid of the isolated process is specified by the caller.
10140                uid = isolatedUid;
10141            }
10142        }
10143        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10144        if (!mBooted && !mBooting
10145                && userId == UserHandle.USER_OWNER
10146                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10147            r.persistent = true;
10148        }
10149        addProcessNameLocked(r);
10150        return r;
10151    }
10152
10153    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10154            String abiOverride) {
10155        ProcessRecord app;
10156        if (!isolated) {
10157            app = getProcessRecordLocked(info.processName, info.uid, true);
10158        } else {
10159            app = null;
10160        }
10161
10162        if (app == null) {
10163            app = newProcessRecordLocked(info, null, isolated, 0);
10164            updateLruProcessLocked(app, false, null);
10165            updateOomAdjLocked();
10166        }
10167
10168        // This package really, really can not be stopped.
10169        try {
10170            AppGlobals.getPackageManager().setPackageStoppedState(
10171                    info.packageName, false, UserHandle.getUserId(app.uid));
10172        } catch (RemoteException e) {
10173        } catch (IllegalArgumentException e) {
10174            Slog.w(TAG, "Failed trying to unstop package "
10175                    + info.packageName + ": " + e);
10176        }
10177
10178        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10179            app.persistent = true;
10180            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10181        }
10182        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10183            mPersistentStartingProcesses.add(app);
10184            startProcessLocked(app, "added application", app.processName, abiOverride,
10185                    null /* entryPoint */, null /* entryPointArgs */);
10186        }
10187
10188        return app;
10189    }
10190
10191    public void unhandledBack() {
10192        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10193                "unhandledBack()");
10194
10195        synchronized(this) {
10196            final long origId = Binder.clearCallingIdentity();
10197            try {
10198                getFocusedStack().unhandledBackLocked();
10199            } finally {
10200                Binder.restoreCallingIdentity(origId);
10201            }
10202        }
10203    }
10204
10205    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10206        enforceNotIsolatedCaller("openContentUri");
10207        final int userId = UserHandle.getCallingUserId();
10208        String name = uri.getAuthority();
10209        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10210        ParcelFileDescriptor pfd = null;
10211        if (cph != null) {
10212            // We record the binder invoker's uid in thread-local storage before
10213            // going to the content provider to open the file.  Later, in the code
10214            // that handles all permissions checks, we look for this uid and use
10215            // that rather than the Activity Manager's own uid.  The effect is that
10216            // we do the check against the caller's permissions even though it looks
10217            // to the content provider like the Activity Manager itself is making
10218            // the request.
10219            Binder token = new Binder();
10220            sCallerIdentity.set(new Identity(
10221                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10222            try {
10223                pfd = cph.provider.openFile(null, uri, "r", null, token);
10224            } catch (FileNotFoundException e) {
10225                // do nothing; pfd will be returned null
10226            } finally {
10227                // Ensure that whatever happens, we clean up the identity state
10228                sCallerIdentity.remove();
10229                // Ensure we're done with the provider.
10230                removeContentProviderExternalUnchecked(name, null, userId);
10231            }
10232        } else {
10233            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10234        }
10235        return pfd;
10236    }
10237
10238    // Actually is sleeping or shutting down or whatever else in the future
10239    // is an inactive state.
10240    public boolean isSleepingOrShuttingDown() {
10241        return isSleeping() || mShuttingDown;
10242    }
10243
10244    public boolean isSleeping() {
10245        return mSleeping;
10246    }
10247
10248    void onWakefulnessChanged(int wakefulness) {
10249        synchronized(this) {
10250            mWakefulness = wakefulness;
10251            updateSleepIfNeededLocked();
10252        }
10253    }
10254
10255    void finishRunningVoiceLocked() {
10256        if (mRunningVoice != null) {
10257            mRunningVoice = null;
10258            mVoiceWakeLock.release();
10259            updateSleepIfNeededLocked();
10260        }
10261    }
10262
10263    void startTimeTrackingFocusedActivityLocked() {
10264        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10265            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10266        }
10267    }
10268
10269    void updateSleepIfNeededLocked() {
10270        if (mSleeping && !shouldSleepLocked()) {
10271            mSleeping = false;
10272            startTimeTrackingFocusedActivityLocked();
10273            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10274            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10275            updateOomAdjLocked();
10276        } else if (!mSleeping && shouldSleepLocked()) {
10277            mSleeping = true;
10278            if (mCurAppTimeTracker != null) {
10279                mCurAppTimeTracker.stop();
10280            }
10281            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10282            mStackSupervisor.goingToSleepLocked();
10283            updateOomAdjLocked();
10284
10285            // Initialize the wake times of all processes.
10286            checkExcessivePowerUsageLocked(false);
10287            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10288            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10289            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10290        }
10291    }
10292
10293    private boolean shouldSleepLocked() {
10294        // Resume applications while running a voice interactor.
10295        if (mRunningVoice != null) {
10296            return false;
10297        }
10298
10299        // TODO: Transform the lock screen state into a sleep token instead.
10300        switch (mWakefulness) {
10301            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10302            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10303            case PowerManagerInternal.WAKEFULNESS_DOZING:
10304                // Pause applications whenever the lock screen is shown or any sleep
10305                // tokens have been acquired.
10306                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10307            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10308            default:
10309                // If we're asleep then pause applications unconditionally.
10310                return true;
10311        }
10312    }
10313
10314    /** Pokes the task persister. */
10315    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10316        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10317            // Never persist the home stack.
10318            return;
10319        }
10320        mTaskPersister.wakeup(task, flush);
10321    }
10322
10323    /** Notifies all listeners when the task stack has changed. */
10324    void notifyTaskStackChangedLocked() {
10325        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10326        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10327        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10328    }
10329
10330    @Override
10331    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10332        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10333    }
10334
10335    @Override
10336    public boolean shutdown(int timeout) {
10337        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10338                != PackageManager.PERMISSION_GRANTED) {
10339            throw new SecurityException("Requires permission "
10340                    + android.Manifest.permission.SHUTDOWN);
10341        }
10342
10343        boolean timedout = false;
10344
10345        synchronized(this) {
10346            mShuttingDown = true;
10347            updateEventDispatchingLocked();
10348            timedout = mStackSupervisor.shutdownLocked(timeout);
10349        }
10350
10351        mAppOpsService.shutdown();
10352        if (mUsageStatsService != null) {
10353            mUsageStatsService.prepareShutdown();
10354        }
10355        mBatteryStatsService.shutdown();
10356        synchronized (this) {
10357            mProcessStats.shutdownLocked();
10358            notifyTaskPersisterLocked(null, true);
10359        }
10360
10361        return timedout;
10362    }
10363
10364    public final void activitySlept(IBinder token) {
10365        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10366
10367        final long origId = Binder.clearCallingIdentity();
10368
10369        synchronized (this) {
10370            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10371            if (r != null) {
10372                mStackSupervisor.activitySleptLocked(r);
10373            }
10374        }
10375
10376        Binder.restoreCallingIdentity(origId);
10377    }
10378
10379    private String lockScreenShownToString() {
10380        switch (mLockScreenShown) {
10381            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10382            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10383            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10384            default: return "Unknown=" + mLockScreenShown;
10385        }
10386    }
10387
10388    void logLockScreen(String msg) {
10389        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10390                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10391                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10392                + " mSleeping=" + mSleeping);
10393    }
10394
10395    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10396        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10397        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10398            boolean wasRunningVoice = mRunningVoice != null;
10399            mRunningVoice = session;
10400            if (!wasRunningVoice) {
10401                mVoiceWakeLock.acquire();
10402                updateSleepIfNeededLocked();
10403            }
10404        }
10405    }
10406
10407    private void updateEventDispatchingLocked() {
10408        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10409    }
10410
10411    public void setLockScreenShown(boolean shown) {
10412        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10413                != PackageManager.PERMISSION_GRANTED) {
10414            throw new SecurityException("Requires permission "
10415                    + android.Manifest.permission.DEVICE_POWER);
10416        }
10417
10418        synchronized(this) {
10419            long ident = Binder.clearCallingIdentity();
10420            try {
10421                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10422                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10423                updateSleepIfNeededLocked();
10424            } finally {
10425                Binder.restoreCallingIdentity(ident);
10426            }
10427        }
10428    }
10429
10430    @Override
10431    public void stopAppSwitches() {
10432        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10433                != PackageManager.PERMISSION_GRANTED) {
10434            throw new SecurityException("Requires permission "
10435                    + android.Manifest.permission.STOP_APP_SWITCHES);
10436        }
10437
10438        synchronized(this) {
10439            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10440                    + APP_SWITCH_DELAY_TIME;
10441            mDidAppSwitch = false;
10442            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10443            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10444            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10445        }
10446    }
10447
10448    public void resumeAppSwitches() {
10449        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10450                != PackageManager.PERMISSION_GRANTED) {
10451            throw new SecurityException("Requires permission "
10452                    + android.Manifest.permission.STOP_APP_SWITCHES);
10453        }
10454
10455        synchronized(this) {
10456            // Note that we don't execute any pending app switches... we will
10457            // let those wait until either the timeout, or the next start
10458            // activity request.
10459            mAppSwitchesAllowedTime = 0;
10460        }
10461    }
10462
10463    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10464            int callingPid, int callingUid, String name) {
10465        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10466            return true;
10467        }
10468
10469        int perm = checkComponentPermission(
10470                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10471                sourceUid, -1, true);
10472        if (perm == PackageManager.PERMISSION_GRANTED) {
10473            return true;
10474        }
10475
10476        // If the actual IPC caller is different from the logical source, then
10477        // also see if they are allowed to control app switches.
10478        if (callingUid != -1 && callingUid != sourceUid) {
10479            perm = checkComponentPermission(
10480                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10481                    callingUid, -1, true);
10482            if (perm == PackageManager.PERMISSION_GRANTED) {
10483                return true;
10484            }
10485        }
10486
10487        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10488        return false;
10489    }
10490
10491    public void setDebugApp(String packageName, boolean waitForDebugger,
10492            boolean persistent) {
10493        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10494                "setDebugApp()");
10495
10496        long ident = Binder.clearCallingIdentity();
10497        try {
10498            // Note that this is not really thread safe if there are multiple
10499            // callers into it at the same time, but that's not a situation we
10500            // care about.
10501            if (persistent) {
10502                final ContentResolver resolver = mContext.getContentResolver();
10503                Settings.Global.putString(
10504                    resolver, Settings.Global.DEBUG_APP,
10505                    packageName);
10506                Settings.Global.putInt(
10507                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10508                    waitForDebugger ? 1 : 0);
10509            }
10510
10511            synchronized (this) {
10512                if (!persistent) {
10513                    mOrigDebugApp = mDebugApp;
10514                    mOrigWaitForDebugger = mWaitForDebugger;
10515                }
10516                mDebugApp = packageName;
10517                mWaitForDebugger = waitForDebugger;
10518                mDebugTransient = !persistent;
10519                if (packageName != null) {
10520                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10521                            false, UserHandle.USER_ALL, "set debug app");
10522                }
10523            }
10524        } finally {
10525            Binder.restoreCallingIdentity(ident);
10526        }
10527    }
10528
10529    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10530        synchronized (this) {
10531            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10532            if (!isDebuggable) {
10533                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10534                    throw new SecurityException("Process not debuggable: " + app.packageName);
10535                }
10536            }
10537
10538            mOpenGlTraceApp = processName;
10539        }
10540    }
10541
10542    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10543        synchronized (this) {
10544            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10545            if (!isDebuggable) {
10546                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10547                    throw new SecurityException("Process not debuggable: " + app.packageName);
10548                }
10549            }
10550
10551            mTrackAllocationApp = processName;
10552        }
10553    }
10554
10555    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10556        synchronized (this) {
10557            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10558            if (!isDebuggable) {
10559                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10560                    throw new SecurityException("Process not debuggable: " + app.packageName);
10561                }
10562            }
10563            mProfileApp = processName;
10564            mProfileFile = profilerInfo.profileFile;
10565            if (mProfileFd != null) {
10566                try {
10567                    mProfileFd.close();
10568                } catch (IOException e) {
10569                }
10570                mProfileFd = null;
10571            }
10572            mProfileFd = profilerInfo.profileFd;
10573            mSamplingInterval = profilerInfo.samplingInterval;
10574            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10575            mProfileType = 0;
10576        }
10577    }
10578
10579    @Override
10580    public void setAlwaysFinish(boolean enabled) {
10581        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10582                "setAlwaysFinish()");
10583
10584        Settings.Global.putInt(
10585                mContext.getContentResolver(),
10586                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10587
10588        synchronized (this) {
10589            mAlwaysFinishActivities = enabled;
10590        }
10591    }
10592
10593    @Override
10594    public void setActivityController(IActivityController controller) {
10595        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10596                "setActivityController()");
10597        synchronized (this) {
10598            mController = controller;
10599            Watchdog.getInstance().setActivityController(controller);
10600        }
10601    }
10602
10603    @Override
10604    public void setUserIsMonkey(boolean userIsMonkey) {
10605        synchronized (this) {
10606            synchronized (mPidsSelfLocked) {
10607                final int callingPid = Binder.getCallingPid();
10608                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10609                if (precessRecord == null) {
10610                    throw new SecurityException("Unknown process: " + callingPid);
10611                }
10612                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10613                    throw new SecurityException("Only an instrumentation process "
10614                            + "with a UiAutomation can call setUserIsMonkey");
10615                }
10616            }
10617            mUserIsMonkey = userIsMonkey;
10618        }
10619    }
10620
10621    @Override
10622    public boolean isUserAMonkey() {
10623        synchronized (this) {
10624            // If there is a controller also implies the user is a monkey.
10625            return (mUserIsMonkey || mController != null);
10626        }
10627    }
10628
10629    public void requestBugReport() {
10630        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10631        SystemProperties.set("ctl.start", "bugreport");
10632    }
10633
10634    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10635        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10636    }
10637
10638    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10639        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10640            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10641        }
10642        return KEY_DISPATCHING_TIMEOUT;
10643    }
10644
10645    @Override
10646    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10647        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10648                != PackageManager.PERMISSION_GRANTED) {
10649            throw new SecurityException("Requires permission "
10650                    + android.Manifest.permission.FILTER_EVENTS);
10651        }
10652        ProcessRecord proc;
10653        long timeout;
10654        synchronized (this) {
10655            synchronized (mPidsSelfLocked) {
10656                proc = mPidsSelfLocked.get(pid);
10657            }
10658            timeout = getInputDispatchingTimeoutLocked(proc);
10659        }
10660
10661        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10662            return -1;
10663        }
10664
10665        return timeout;
10666    }
10667
10668    /**
10669     * Handle input dispatching timeouts.
10670     * Returns whether input dispatching should be aborted or not.
10671     */
10672    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10673            final ActivityRecord activity, final ActivityRecord parent,
10674            final boolean aboveSystem, String reason) {
10675        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10676                != PackageManager.PERMISSION_GRANTED) {
10677            throw new SecurityException("Requires permission "
10678                    + android.Manifest.permission.FILTER_EVENTS);
10679        }
10680
10681        final String annotation;
10682        if (reason == null) {
10683            annotation = "Input dispatching timed out";
10684        } else {
10685            annotation = "Input dispatching timed out (" + reason + ")";
10686        }
10687
10688        if (proc != null) {
10689            synchronized (this) {
10690                if (proc.debugging) {
10691                    return false;
10692                }
10693
10694                if (mDidDexOpt) {
10695                    // Give more time since we were dexopting.
10696                    mDidDexOpt = false;
10697                    return false;
10698                }
10699
10700                if (proc.instrumentationClass != null) {
10701                    Bundle info = new Bundle();
10702                    info.putString("shortMsg", "keyDispatchingTimedOut");
10703                    info.putString("longMsg", annotation);
10704                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10705                    return true;
10706                }
10707            }
10708            mHandler.post(new Runnable() {
10709                @Override
10710                public void run() {
10711                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10712                }
10713            });
10714        }
10715
10716        return true;
10717    }
10718
10719    @Override
10720    public Bundle getAssistContextExtras(int requestType) {
10721        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10722                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10723        if (pae == null) {
10724            return null;
10725        }
10726        synchronized (pae) {
10727            while (!pae.haveResult) {
10728                try {
10729                    pae.wait();
10730                } catch (InterruptedException e) {
10731                }
10732            }
10733        }
10734        synchronized (this) {
10735            buildAssistBundleLocked(pae, pae.result);
10736            mPendingAssistExtras.remove(pae);
10737            mHandler.removeCallbacks(pae);
10738        }
10739        return pae.extras;
10740    }
10741
10742    @Override
10743    public boolean isAssistDataAllowedOnCurrentActivity() {
10744        int userId = mCurrentUserId;
10745        synchronized (this) {
10746            ActivityRecord activity = getFocusedStack().topActivity();
10747            if (activity == null) {
10748                return false;
10749            }
10750            userId = activity.userId;
10751        }
10752        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10753                Context.DEVICE_POLICY_SERVICE);
10754        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10755    }
10756
10757    @Override
10758    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10759        long ident = Binder.clearCallingIdentity();
10760        try {
10761            synchronized (this) {
10762                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10763                ActivityRecord top = getFocusedStack().topActivity();
10764                if (top != caller) {
10765                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10766                            + " is not current top " + top);
10767                    return false;
10768                }
10769                if (!top.nowVisible) {
10770                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10771                            + " is not visible");
10772                    return false;
10773                }
10774            }
10775            AssistUtils utils = new AssistUtils(mContext);
10776            return utils.showSessionForActiveService(args,
10777                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10778        } finally {
10779            Binder.restoreCallingIdentity(ident);
10780        }
10781    }
10782
10783    @Override
10784    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10785            IBinder activityToken) {
10786        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10787                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10788    }
10789
10790    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10791            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10792            long timeout) {
10793        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10794                "enqueueAssistContext()");
10795        synchronized (this) {
10796            ActivityRecord activity = getFocusedStack().topActivity();
10797            if (activity == null) {
10798                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10799                return null;
10800            }
10801            if (activity.app == null || activity.app.thread == null) {
10802                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10803                return null;
10804            }
10805            if (activityToken != null) {
10806                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10807                if (activity != caller) {
10808                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10809                            + " is not current top " + activity);
10810                    return null;
10811                }
10812            }
10813            PendingAssistExtras pae;
10814            Bundle extras = new Bundle();
10815            if (args != null) {
10816                extras.putAll(args);
10817            }
10818            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10819            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10820            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10821            try {
10822                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10823                        requestType);
10824                mPendingAssistExtras.add(pae);
10825                mHandler.postDelayed(pae, timeout);
10826            } catch (RemoteException e) {
10827                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10828                return null;
10829            }
10830            return pae;
10831        }
10832    }
10833
10834    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10835        IResultReceiver receiver;
10836        synchronized (this) {
10837            mPendingAssistExtras.remove(pae);
10838            receiver = pae.receiver;
10839        }
10840        if (receiver != null) {
10841            // Caller wants result sent back to them.
10842            try {
10843                pae.receiver.send(0, null);
10844            } catch (RemoteException e) {
10845            }
10846        }
10847    }
10848
10849    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10850        if (result != null) {
10851            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10852        }
10853        if (pae.hint != null) {
10854            pae.extras.putBoolean(pae.hint, true);
10855        }
10856    }
10857
10858    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10859            AssistContent content, Uri referrer) {
10860        PendingAssistExtras pae = (PendingAssistExtras)token;
10861        synchronized (pae) {
10862            pae.result = extras;
10863            pae.structure = structure;
10864            pae.content = content;
10865            if (referrer != null) {
10866                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10867            }
10868            pae.haveResult = true;
10869            pae.notifyAll();
10870            if (pae.intent == null && pae.receiver == null) {
10871                // Caller is just waiting for the result.
10872                return;
10873            }
10874        }
10875
10876        // We are now ready to launch the assist activity.
10877        IResultReceiver sendReceiver = null;
10878        Bundle sendBundle = null;
10879        synchronized (this) {
10880            buildAssistBundleLocked(pae, extras);
10881            boolean exists = mPendingAssistExtras.remove(pae);
10882            mHandler.removeCallbacks(pae);
10883            if (!exists) {
10884                // Timed out.
10885                return;
10886            }
10887            if ((sendReceiver=pae.receiver) != null) {
10888                // Caller wants result sent back to them.
10889                sendBundle = new Bundle();
10890                sendBundle.putBundle("data", pae.extras);
10891                sendBundle.putParcelable("structure", pae.structure);
10892                sendBundle.putParcelable("content", pae.content);
10893            }
10894        }
10895        if (sendReceiver != null) {
10896            try {
10897                sendReceiver.send(0, sendBundle);
10898            } catch (RemoteException e) {
10899            }
10900            return;
10901        }
10902
10903        long ident = Binder.clearCallingIdentity();
10904        try {
10905            pae.intent.replaceExtras(pae.extras);
10906            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10907                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10908                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10909            closeSystemDialogs("assist");
10910            try {
10911                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10912            } catch (ActivityNotFoundException e) {
10913                Slog.w(TAG, "No activity to handle assist action.", e);
10914            }
10915        } finally {
10916            Binder.restoreCallingIdentity(ident);
10917        }
10918    }
10919
10920    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10921            Bundle args) {
10922        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10923                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10924    }
10925
10926    public void registerProcessObserver(IProcessObserver observer) {
10927        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10928                "registerProcessObserver()");
10929        synchronized (this) {
10930            mProcessObservers.register(observer);
10931        }
10932    }
10933
10934    @Override
10935    public void unregisterProcessObserver(IProcessObserver observer) {
10936        synchronized (this) {
10937            mProcessObservers.unregister(observer);
10938        }
10939    }
10940
10941    public void registerUidObserver(IUidObserver observer) {
10942        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10943                "registerUidObserver()");
10944        synchronized (this) {
10945            mUidObservers.register(observer);
10946        }
10947    }
10948
10949    @Override
10950    public void unregisterUidObserver(IUidObserver observer) {
10951        synchronized (this) {
10952            mUidObservers.unregister(observer);
10953        }
10954    }
10955
10956    @Override
10957    public boolean convertFromTranslucent(IBinder token) {
10958        final long origId = Binder.clearCallingIdentity();
10959        try {
10960            synchronized (this) {
10961                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10962                if (r == null) {
10963                    return false;
10964                }
10965                final boolean translucentChanged = r.changeWindowTranslucency(true);
10966                if (translucentChanged) {
10967                    r.task.stack.releaseBackgroundResources(r);
10968                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10969                }
10970                mWindowManager.setAppFullscreen(token, true);
10971                return translucentChanged;
10972            }
10973        } finally {
10974            Binder.restoreCallingIdentity(origId);
10975        }
10976    }
10977
10978    @Override
10979    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10980        final long origId = Binder.clearCallingIdentity();
10981        try {
10982            synchronized (this) {
10983                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10984                if (r == null) {
10985                    return false;
10986                }
10987                int index = r.task.mActivities.lastIndexOf(r);
10988                if (index > 0) {
10989                    ActivityRecord under = r.task.mActivities.get(index - 1);
10990                    under.returningOptions = options;
10991                }
10992                final boolean translucentChanged = r.changeWindowTranslucency(false);
10993                if (translucentChanged) {
10994                    r.task.stack.convertActivityToTranslucent(r);
10995                }
10996                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10997                mWindowManager.setAppFullscreen(token, false);
10998                return translucentChanged;
10999            }
11000        } finally {
11001            Binder.restoreCallingIdentity(origId);
11002        }
11003    }
11004
11005    @Override
11006    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11007        final long origId = Binder.clearCallingIdentity();
11008        try {
11009            synchronized (this) {
11010                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11011                if (r != null) {
11012                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11013                }
11014            }
11015            return false;
11016        } finally {
11017            Binder.restoreCallingIdentity(origId);
11018        }
11019    }
11020
11021    @Override
11022    public boolean isBackgroundVisibleBehind(IBinder token) {
11023        final long origId = Binder.clearCallingIdentity();
11024        try {
11025            synchronized (this) {
11026                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11027                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11028                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11029                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11030                return visible;
11031            }
11032        } finally {
11033            Binder.restoreCallingIdentity(origId);
11034        }
11035    }
11036
11037    @Override
11038    public ActivityOptions getActivityOptions(IBinder token) {
11039        final long origId = Binder.clearCallingIdentity();
11040        try {
11041            synchronized (this) {
11042                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11043                if (r != null) {
11044                    final ActivityOptions activityOptions = r.pendingOptions;
11045                    r.pendingOptions = null;
11046                    return activityOptions;
11047                }
11048                return null;
11049            }
11050        } finally {
11051            Binder.restoreCallingIdentity(origId);
11052        }
11053    }
11054
11055    @Override
11056    public void setImmersive(IBinder token, boolean immersive) {
11057        synchronized(this) {
11058            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11059            if (r == null) {
11060                throw new IllegalArgumentException();
11061            }
11062            r.immersive = immersive;
11063
11064            // update associated state if we're frontmost
11065            if (r == mFocusedActivity) {
11066                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11067                applyUpdateLockStateLocked(r);
11068            }
11069        }
11070    }
11071
11072    @Override
11073    public boolean isImmersive(IBinder token) {
11074        synchronized (this) {
11075            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11076            if (r == null) {
11077                throw new IllegalArgumentException();
11078            }
11079            return r.immersive;
11080        }
11081    }
11082
11083    public boolean isTopActivityImmersive() {
11084        enforceNotIsolatedCaller("startActivity");
11085        synchronized (this) {
11086            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11087            return (r != null) ? r.immersive : false;
11088        }
11089    }
11090
11091    @Override
11092    public boolean isTopOfTask(IBinder token) {
11093        synchronized (this) {
11094            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11095            if (r == null) {
11096                throw new IllegalArgumentException();
11097            }
11098            return r.task.getTopActivity() == r;
11099        }
11100    }
11101
11102    public final void enterSafeMode() {
11103        synchronized(this) {
11104            // It only makes sense to do this before the system is ready
11105            // and started launching other packages.
11106            if (!mSystemReady) {
11107                try {
11108                    AppGlobals.getPackageManager().enterSafeMode();
11109                } catch (RemoteException e) {
11110                }
11111            }
11112
11113            mSafeMode = true;
11114        }
11115    }
11116
11117    public final void showSafeModeOverlay() {
11118        View v = LayoutInflater.from(mContext).inflate(
11119                com.android.internal.R.layout.safe_mode, null);
11120        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11121        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11122        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11123        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11124        lp.gravity = Gravity.BOTTOM | Gravity.START;
11125        lp.format = v.getBackground().getOpacity();
11126        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11127                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11128        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11129        ((WindowManager)mContext.getSystemService(
11130                Context.WINDOW_SERVICE)).addView(v, lp);
11131    }
11132
11133    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11134        if (!(sender instanceof PendingIntentRecord)) {
11135            return;
11136        }
11137        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11138        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11139        synchronized (stats) {
11140            if (mBatteryStatsService.isOnBattery()) {
11141                mBatteryStatsService.enforceCallingPermission();
11142                int MY_UID = Binder.getCallingUid();
11143                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11144                BatteryStatsImpl.Uid.Pkg pkg =
11145                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11146                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11147                pkg.noteWakeupAlarmLocked(tag);
11148            }
11149        }
11150    }
11151
11152    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11153        if (!(sender instanceof PendingIntentRecord)) {
11154            return;
11155        }
11156        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11157        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11158        synchronized (stats) {
11159            mBatteryStatsService.enforceCallingPermission();
11160            int MY_UID = Binder.getCallingUid();
11161            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11162            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11163        }
11164    }
11165
11166    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11167        if (!(sender instanceof PendingIntentRecord)) {
11168            return;
11169        }
11170        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11171        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11172        synchronized (stats) {
11173            mBatteryStatsService.enforceCallingPermission();
11174            int MY_UID = Binder.getCallingUid();
11175            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11176            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11177        }
11178    }
11179
11180    public boolean killPids(int[] pids, String pReason, boolean secure) {
11181        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11182            throw new SecurityException("killPids only available to the system");
11183        }
11184        String reason = (pReason == null) ? "Unknown" : pReason;
11185        // XXX Note: don't acquire main activity lock here, because the window
11186        // manager calls in with its locks held.
11187
11188        boolean killed = false;
11189        synchronized (mPidsSelfLocked) {
11190            int[] types = new int[pids.length];
11191            int worstType = 0;
11192            for (int i=0; i<pids.length; i++) {
11193                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11194                if (proc != null) {
11195                    int type = proc.setAdj;
11196                    types[i] = type;
11197                    if (type > worstType) {
11198                        worstType = type;
11199                    }
11200                }
11201            }
11202
11203            // If the worst oom_adj is somewhere in the cached proc LRU range,
11204            // then constrain it so we will kill all cached procs.
11205            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11206                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11207                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11208            }
11209
11210            // If this is not a secure call, don't let it kill processes that
11211            // are important.
11212            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11213                worstType = ProcessList.SERVICE_ADJ;
11214            }
11215
11216            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11217            for (int i=0; i<pids.length; i++) {
11218                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11219                if (proc == null) {
11220                    continue;
11221                }
11222                int adj = proc.setAdj;
11223                if (adj >= worstType && !proc.killedByAm) {
11224                    proc.kill(reason, true);
11225                    killed = true;
11226                }
11227            }
11228        }
11229        return killed;
11230    }
11231
11232    @Override
11233    public void killUid(int uid, String reason) {
11234        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11235        synchronized (this) {
11236            final long identity = Binder.clearCallingIdentity();
11237            try {
11238                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11239                        UserHandle.getUserId(uid),
11240                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11241                        reason != null ? reason : "kill uid");
11242            } finally {
11243                Binder.restoreCallingIdentity(identity);
11244            }
11245        }
11246    }
11247
11248    @Override
11249    public boolean killProcessesBelowForeground(String reason) {
11250        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11251            throw new SecurityException("killProcessesBelowForeground() only available to system");
11252        }
11253
11254        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11255    }
11256
11257    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11258        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11259            throw new SecurityException("killProcessesBelowAdj() only available to system");
11260        }
11261
11262        boolean killed = false;
11263        synchronized (mPidsSelfLocked) {
11264            final int size = mPidsSelfLocked.size();
11265            for (int i = 0; i < size; i++) {
11266                final int pid = mPidsSelfLocked.keyAt(i);
11267                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11268                if (proc == null) continue;
11269
11270                final int adj = proc.setAdj;
11271                if (adj > belowAdj && !proc.killedByAm) {
11272                    proc.kill(reason, true);
11273                    killed = true;
11274                }
11275            }
11276        }
11277        return killed;
11278    }
11279
11280    @Override
11281    public void hang(final IBinder who, boolean allowRestart) {
11282        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11283                != PackageManager.PERMISSION_GRANTED) {
11284            throw new SecurityException("Requires permission "
11285                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11286        }
11287
11288        final IBinder.DeathRecipient death = new DeathRecipient() {
11289            @Override
11290            public void binderDied() {
11291                synchronized (this) {
11292                    notifyAll();
11293                }
11294            }
11295        };
11296
11297        try {
11298            who.linkToDeath(death, 0);
11299        } catch (RemoteException e) {
11300            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11301            return;
11302        }
11303
11304        synchronized (this) {
11305            Watchdog.getInstance().setAllowRestart(allowRestart);
11306            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11307            synchronized (death) {
11308                while (who.isBinderAlive()) {
11309                    try {
11310                        death.wait();
11311                    } catch (InterruptedException e) {
11312                    }
11313                }
11314            }
11315            Watchdog.getInstance().setAllowRestart(true);
11316        }
11317    }
11318
11319    @Override
11320    public void restart() {
11321        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11322                != PackageManager.PERMISSION_GRANTED) {
11323            throw new SecurityException("Requires permission "
11324                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11325        }
11326
11327        Log.i(TAG, "Sending shutdown broadcast...");
11328
11329        BroadcastReceiver br = new BroadcastReceiver() {
11330            @Override public void onReceive(Context context, Intent intent) {
11331                // Now the broadcast is done, finish up the low-level shutdown.
11332                Log.i(TAG, "Shutting down activity manager...");
11333                shutdown(10000);
11334                Log.i(TAG, "Shutdown complete, restarting!");
11335                Process.killProcess(Process.myPid());
11336                System.exit(10);
11337            }
11338        };
11339
11340        // First send the high-level shut down broadcast.
11341        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11342        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11343        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11344        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11345        mContext.sendOrderedBroadcastAsUser(intent,
11346                UserHandle.ALL, null, br, mHandler, 0, null, null);
11347        */
11348        br.onReceive(mContext, intent);
11349    }
11350
11351    private long getLowRamTimeSinceIdle(long now) {
11352        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11353    }
11354
11355    @Override
11356    public void performIdleMaintenance() {
11357        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11358                != PackageManager.PERMISSION_GRANTED) {
11359            throw new SecurityException("Requires permission "
11360                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11361        }
11362
11363        synchronized (this) {
11364            final long now = SystemClock.uptimeMillis();
11365            final long timeSinceLastIdle = now - mLastIdleTime;
11366            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11367            mLastIdleTime = now;
11368            mLowRamTimeSinceLastIdle = 0;
11369            if (mLowRamStartTime != 0) {
11370                mLowRamStartTime = now;
11371            }
11372
11373            StringBuilder sb = new StringBuilder(128);
11374            sb.append("Idle maintenance over ");
11375            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11376            sb.append(" low RAM for ");
11377            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11378            Slog.i(TAG, sb.toString());
11379
11380            // If at least 1/3 of our time since the last idle period has been spent
11381            // with RAM low, then we want to kill processes.
11382            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11383
11384            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11385                ProcessRecord proc = mLruProcesses.get(i);
11386                if (proc.notCachedSinceIdle) {
11387                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11388                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11389                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11390                        if (doKilling && proc.initialIdlePss != 0
11391                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11392                            sb = new StringBuilder(128);
11393                            sb.append("Kill");
11394                            sb.append(proc.processName);
11395                            sb.append(" in idle maint: pss=");
11396                            sb.append(proc.lastPss);
11397                            sb.append(", initialPss=");
11398                            sb.append(proc.initialIdlePss);
11399                            sb.append(", period=");
11400                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11401                            sb.append(", lowRamPeriod=");
11402                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11403                            Slog.wtfQuiet(TAG, sb.toString());
11404                            proc.kill("idle maint (pss " + proc.lastPss
11405                                    + " from " + proc.initialIdlePss + ")", true);
11406                        }
11407                    }
11408                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11409                    proc.notCachedSinceIdle = true;
11410                    proc.initialIdlePss = 0;
11411                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11412                            mTestPssMode, isSleeping(), now);
11413                }
11414            }
11415
11416            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11417            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11418        }
11419    }
11420
11421    private void retrieveSettings() {
11422        final ContentResolver resolver = mContext.getContentResolver();
11423        String debugApp = Settings.Global.getString(
11424            resolver, Settings.Global.DEBUG_APP);
11425        boolean waitForDebugger = Settings.Global.getInt(
11426            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11427        boolean alwaysFinishActivities = Settings.Global.getInt(
11428            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11429        boolean forceRtl = Settings.Global.getInt(
11430                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11431        // Transfer any global setting for forcing RTL layout, into a System Property
11432        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11433
11434        Configuration configuration = new Configuration();
11435        Settings.System.getConfiguration(resolver, configuration);
11436        if (forceRtl) {
11437            // This will take care of setting the correct layout direction flags
11438            configuration.setLayoutDirection(configuration.locale);
11439        }
11440
11441        synchronized (this) {
11442            mDebugApp = mOrigDebugApp = debugApp;
11443            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11444            mAlwaysFinishActivities = alwaysFinishActivities;
11445            // This happens before any activities are started, so we can
11446            // change mConfiguration in-place.
11447            updateConfigurationLocked(configuration, null, false, true);
11448            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11449                    "Initial config: " + mConfiguration);
11450        }
11451    }
11452
11453    /** Loads resources after the current configuration has been set. */
11454    private void loadResourcesOnSystemReady() {
11455        final Resources res = mContext.getResources();
11456        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11457        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11458        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11459    }
11460
11461    public boolean testIsSystemReady() {
11462        // no need to synchronize(this) just to read & return the value
11463        return mSystemReady;
11464    }
11465
11466    private static File getCalledPreBootReceiversFile() {
11467        File dataDir = Environment.getDataDirectory();
11468        File systemDir = new File(dataDir, "system");
11469        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11470        return fname;
11471    }
11472
11473    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11474        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11475        File file = getCalledPreBootReceiversFile();
11476        FileInputStream fis = null;
11477        try {
11478            fis = new FileInputStream(file);
11479            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11480            int fvers = dis.readInt();
11481            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11482                String vers = dis.readUTF();
11483                String codename = dis.readUTF();
11484                String build = dis.readUTF();
11485                if (android.os.Build.VERSION.RELEASE.equals(vers)
11486                        && android.os.Build.VERSION.CODENAME.equals(codename)
11487                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11488                    int num = dis.readInt();
11489                    while (num > 0) {
11490                        num--;
11491                        String pkg = dis.readUTF();
11492                        String cls = dis.readUTF();
11493                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11494                    }
11495                }
11496            }
11497        } catch (FileNotFoundException e) {
11498        } catch (IOException e) {
11499            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11500        } finally {
11501            if (fis != null) {
11502                try {
11503                    fis.close();
11504                } catch (IOException e) {
11505                }
11506            }
11507        }
11508        return lastDoneReceivers;
11509    }
11510
11511    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11512        File file = getCalledPreBootReceiversFile();
11513        FileOutputStream fos = null;
11514        DataOutputStream dos = null;
11515        try {
11516            fos = new FileOutputStream(file);
11517            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11518            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11519            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11520            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11521            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11522            dos.writeInt(list.size());
11523            for (int i=0; i<list.size(); i++) {
11524                dos.writeUTF(list.get(i).getPackageName());
11525                dos.writeUTF(list.get(i).getClassName());
11526            }
11527        } catch (IOException e) {
11528            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11529            file.delete();
11530        } finally {
11531            FileUtils.sync(fos);
11532            if (dos != null) {
11533                try {
11534                    dos.close();
11535                } catch (IOException e) {
11536                    // TODO Auto-generated catch block
11537                    e.printStackTrace();
11538                }
11539            }
11540        }
11541    }
11542
11543    final class PreBootContinuation extends IIntentReceiver.Stub {
11544        final Intent intent;
11545        final Runnable onFinishCallback;
11546        final ArrayList<ComponentName> doneReceivers;
11547        final List<ResolveInfo> ris;
11548        final int[] users;
11549        int lastRi = -1;
11550        int curRi = 0;
11551        int curUser = 0;
11552
11553        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11554                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11555            intent = _intent;
11556            onFinishCallback = _onFinishCallback;
11557            doneReceivers = _doneReceivers;
11558            ris = _ris;
11559            users = _users;
11560        }
11561
11562        void go() {
11563            if (lastRi != curRi) {
11564                ActivityInfo ai = ris.get(curRi).activityInfo;
11565                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11566                intent.setComponent(comp);
11567                doneReceivers.add(comp);
11568                lastRi = curRi;
11569                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11570                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11571            }
11572            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11573                    + " for user " + users[curUser]);
11574            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11575            broadcastIntentLocked(null, null, intent, null, this,
11576                    0, null, null, null, AppOpsManager.OP_NONE,
11577                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11578        }
11579
11580        public void performReceive(Intent intent, int resultCode,
11581                String data, Bundle extras, boolean ordered,
11582                boolean sticky, int sendingUser) {
11583            curUser++;
11584            if (curUser >= users.length) {
11585                curUser = 0;
11586                curRi++;
11587                if (curRi >= ris.size()) {
11588                    // All done sending broadcasts!
11589                    if (onFinishCallback != null) {
11590                        // The raw IIntentReceiver interface is called
11591                        // with the AM lock held, so redispatch to
11592                        // execute our code without the lock.
11593                        mHandler.post(onFinishCallback);
11594                    }
11595                    return;
11596                }
11597            }
11598            go();
11599        }
11600    }
11601
11602    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11603            ArrayList<ComponentName> doneReceivers, int userId) {
11604        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11605        List<ResolveInfo> ris = null;
11606        try {
11607            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11608                    intent, null, 0, userId);
11609        } catch (RemoteException e) {
11610        }
11611        if (ris == null) {
11612            return false;
11613        }
11614        for (int i=ris.size()-1; i>=0; i--) {
11615            if ((ris.get(i).activityInfo.applicationInfo.flags
11616                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11617                ris.remove(i);
11618            }
11619        }
11620        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11621
11622        // For User 0, load the version number. When delivering to a new user, deliver
11623        // to all receivers.
11624        if (userId == UserHandle.USER_OWNER) {
11625            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11626            for (int i=0; i<ris.size(); i++) {
11627                ActivityInfo ai = ris.get(i).activityInfo;
11628                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11629                if (lastDoneReceivers.contains(comp)) {
11630                    // We already did the pre boot receiver for this app with the current
11631                    // platform version, so don't do it again...
11632                    ris.remove(i);
11633                    i--;
11634                    // ...however, do keep it as one that has been done, so we don't
11635                    // forget about it when rewriting the file of last done receivers.
11636                    doneReceivers.add(comp);
11637                }
11638            }
11639        }
11640
11641        if (ris.size() <= 0) {
11642            return false;
11643        }
11644
11645        // If primary user, send broadcast to all available users, else just to userId
11646        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11647                : new int[] { userId };
11648        if (users.length <= 0) {
11649            return false;
11650        }
11651
11652        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11653                ris, users);
11654        cont.go();
11655        return true;
11656    }
11657
11658    public void systemReady(final Runnable goingCallback) {
11659        synchronized(this) {
11660            if (mSystemReady) {
11661                // If we're done calling all the receivers, run the next "boot phase" passed in
11662                // by the SystemServer
11663                if (goingCallback != null) {
11664                    goingCallback.run();
11665                }
11666                return;
11667            }
11668
11669            mLocalDeviceIdleController
11670                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11671
11672            // Make sure we have the current profile info, since it is needed for
11673            // security checks.
11674            updateCurrentProfileIdsLocked();
11675
11676            mRecentTasks.clear();
11677            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11678            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11679            mTaskPersister.startPersisting();
11680
11681            // Check to see if there are any update receivers to run.
11682            if (!mDidUpdate) {
11683                if (mWaitingUpdate) {
11684                    return;
11685                }
11686                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11687                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11688                    public void run() {
11689                        synchronized (ActivityManagerService.this) {
11690                            mDidUpdate = true;
11691                        }
11692                        showBootMessage(mContext.getText(
11693                                R.string.android_upgrading_complete),
11694                                false);
11695                        writeLastDonePreBootReceivers(doneReceivers);
11696                        systemReady(goingCallback);
11697                    }
11698                }, doneReceivers, UserHandle.USER_OWNER);
11699
11700                if (mWaitingUpdate) {
11701                    return;
11702                }
11703                mDidUpdate = true;
11704            }
11705
11706            mAppOpsService.systemReady();
11707            mSystemReady = true;
11708        }
11709
11710        ArrayList<ProcessRecord> procsToKill = null;
11711        synchronized(mPidsSelfLocked) {
11712            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11713                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11714                if (!isAllowedWhileBooting(proc.info)){
11715                    if (procsToKill == null) {
11716                        procsToKill = new ArrayList<ProcessRecord>();
11717                    }
11718                    procsToKill.add(proc);
11719                }
11720            }
11721        }
11722
11723        synchronized(this) {
11724            if (procsToKill != null) {
11725                for (int i=procsToKill.size()-1; i>=0; i--) {
11726                    ProcessRecord proc = procsToKill.get(i);
11727                    Slog.i(TAG, "Removing system update proc: " + proc);
11728                    removeProcessLocked(proc, true, false, "system update done");
11729                }
11730            }
11731
11732            // Now that we have cleaned up any update processes, we
11733            // are ready to start launching real processes and know that
11734            // we won't trample on them any more.
11735            mProcessesReady = true;
11736        }
11737
11738        Slog.i(TAG, "System now ready");
11739        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11740            SystemClock.uptimeMillis());
11741
11742        synchronized(this) {
11743            // Make sure we have no pre-ready processes sitting around.
11744
11745            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11746                ResolveInfo ri = mContext.getPackageManager()
11747                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11748                                STOCK_PM_FLAGS);
11749                CharSequence errorMsg = null;
11750                if (ri != null) {
11751                    ActivityInfo ai = ri.activityInfo;
11752                    ApplicationInfo app = ai.applicationInfo;
11753                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11754                        mTopAction = Intent.ACTION_FACTORY_TEST;
11755                        mTopData = null;
11756                        mTopComponent = new ComponentName(app.packageName,
11757                                ai.name);
11758                    } else {
11759                        errorMsg = mContext.getResources().getText(
11760                                com.android.internal.R.string.factorytest_not_system);
11761                    }
11762                } else {
11763                    errorMsg = mContext.getResources().getText(
11764                            com.android.internal.R.string.factorytest_no_action);
11765                }
11766                if (errorMsg != null) {
11767                    mTopAction = null;
11768                    mTopData = null;
11769                    mTopComponent = null;
11770                    Message msg = Message.obtain();
11771                    msg.what = SHOW_FACTORY_ERROR_MSG;
11772                    msg.getData().putCharSequence("msg", errorMsg);
11773                    mUiHandler.sendMessage(msg);
11774                }
11775            }
11776        }
11777
11778        retrieveSettings();
11779        loadResourcesOnSystemReady();
11780
11781        synchronized (this) {
11782            readGrantedUriPermissionsLocked();
11783        }
11784
11785        if (goingCallback != null) goingCallback.run();
11786
11787        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11788                Integer.toString(mCurrentUserId), mCurrentUserId);
11789        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11790                Integer.toString(mCurrentUserId), mCurrentUserId);
11791        mSystemServiceManager.startUser(mCurrentUserId);
11792
11793        synchronized (this) {
11794            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11795                try {
11796                    List apps = AppGlobals.getPackageManager().
11797                        getPersistentApplications(STOCK_PM_FLAGS);
11798                    if (apps != null) {
11799                        int N = apps.size();
11800                        int i;
11801                        for (i=0; i<N; i++) {
11802                            ApplicationInfo info
11803                                = (ApplicationInfo)apps.get(i);
11804                            if (info != null &&
11805                                    !info.packageName.equals("android")) {
11806                                addAppLocked(info, false, null /* ABI override */);
11807                            }
11808                        }
11809                    }
11810                } catch (RemoteException ex) {
11811                    // pm is in same process, this will never happen.
11812                }
11813            }
11814
11815            // Start up initial activity.
11816            mBooting = true;
11817            startHomeActivityLocked(mCurrentUserId, "systemReady");
11818
11819            try {
11820                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11821                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11822                            + " data partition or your device will be unstable.");
11823                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11824                }
11825            } catch (RemoteException e) {
11826            }
11827
11828            if (!Build.isBuildConsistent()) {
11829                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11830                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11831            }
11832
11833            long ident = Binder.clearCallingIdentity();
11834            try {
11835                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11836                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11837                        | Intent.FLAG_RECEIVER_FOREGROUND);
11838                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11839                broadcastIntentLocked(null, null, intent,
11840                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11841                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11842                intent = new Intent(Intent.ACTION_USER_STARTING);
11843                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11844                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11845                broadcastIntentLocked(null, null, intent,
11846                        null, new IIntentReceiver.Stub() {
11847                            @Override
11848                            public void performReceive(Intent intent, int resultCode, String data,
11849                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11850                                    throws RemoteException {
11851                            }
11852                        }, 0, null, null,
11853                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11854                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11855            } catch (Throwable t) {
11856                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11857            } finally {
11858                Binder.restoreCallingIdentity(ident);
11859            }
11860            mStackSupervisor.resumeTopActivitiesLocked();
11861            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11862        }
11863    }
11864
11865    private boolean makeAppCrashingLocked(ProcessRecord app,
11866            String shortMsg, String longMsg, String stackTrace) {
11867        app.crashing = true;
11868        app.crashingReport = generateProcessError(app,
11869                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11870        startAppProblemLocked(app);
11871        app.stopFreezingAllLocked();
11872        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11873    }
11874
11875    private void makeAppNotRespondingLocked(ProcessRecord app,
11876            String activity, String shortMsg, String longMsg) {
11877        app.notResponding = true;
11878        app.notRespondingReport = generateProcessError(app,
11879                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11880                activity, shortMsg, longMsg, null);
11881        startAppProblemLocked(app);
11882        app.stopFreezingAllLocked();
11883    }
11884
11885    /**
11886     * Generate a process error record, suitable for attachment to a ProcessRecord.
11887     *
11888     * @param app The ProcessRecord in which the error occurred.
11889     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11890     *                      ActivityManager.AppErrorStateInfo
11891     * @param activity The activity associated with the crash, if known.
11892     * @param shortMsg Short message describing the crash.
11893     * @param longMsg Long message describing the crash.
11894     * @param stackTrace Full crash stack trace, may be null.
11895     *
11896     * @return Returns a fully-formed AppErrorStateInfo record.
11897     */
11898    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11899            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11900        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11901
11902        report.condition = condition;
11903        report.processName = app.processName;
11904        report.pid = app.pid;
11905        report.uid = app.info.uid;
11906        report.tag = activity;
11907        report.shortMsg = shortMsg;
11908        report.longMsg = longMsg;
11909        report.stackTrace = stackTrace;
11910
11911        return report;
11912    }
11913
11914    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11915        synchronized (this) {
11916            app.crashing = false;
11917            app.crashingReport = null;
11918            app.notResponding = false;
11919            app.notRespondingReport = null;
11920            if (app.anrDialog == fromDialog) {
11921                app.anrDialog = null;
11922            }
11923            if (app.waitDialog == fromDialog) {
11924                app.waitDialog = null;
11925            }
11926            if (app.pid > 0 && app.pid != MY_PID) {
11927                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11928                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11929                app.kill("user request after error", true);
11930            }
11931        }
11932    }
11933
11934    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11935            String shortMsg, String longMsg, String stackTrace) {
11936        long now = SystemClock.uptimeMillis();
11937
11938        Long crashTime;
11939        if (!app.isolated) {
11940            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11941        } else {
11942            crashTime = null;
11943        }
11944        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11945            // This process loses!
11946            Slog.w(TAG, "Process " + app.info.processName
11947                    + " has crashed too many times: killing!");
11948            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11949                    app.userId, app.info.processName, app.uid);
11950            mStackSupervisor.handleAppCrashLocked(app);
11951            if (!app.persistent) {
11952                // We don't want to start this process again until the user
11953                // explicitly does so...  but for persistent process, we really
11954                // need to keep it running.  If a persistent process is actually
11955                // repeatedly crashing, then badness for everyone.
11956                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11957                        app.info.processName);
11958                if (!app.isolated) {
11959                    // XXX We don't have a way to mark isolated processes
11960                    // as bad, since they don't have a peristent identity.
11961                    mBadProcesses.put(app.info.processName, app.uid,
11962                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11963                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11964                }
11965                app.bad = true;
11966                app.removed = true;
11967                // Don't let services in this process be restarted and potentially
11968                // annoy the user repeatedly.  Unless it is persistent, since those
11969                // processes run critical code.
11970                removeProcessLocked(app, false, false, "crash");
11971                mStackSupervisor.resumeTopActivitiesLocked();
11972                return false;
11973            }
11974            mStackSupervisor.resumeTopActivitiesLocked();
11975        } else {
11976            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11977        }
11978
11979        // Bump up the crash count of any services currently running in the proc.
11980        for (int i=app.services.size()-1; i>=0; i--) {
11981            // Any services running in the application need to be placed
11982            // back in the pending list.
11983            ServiceRecord sr = app.services.valueAt(i);
11984            sr.crashCount++;
11985        }
11986
11987        // If the crashing process is what we consider to be the "home process" and it has been
11988        // replaced by a third-party app, clear the package preferred activities from packages
11989        // with a home activity running in the process to prevent a repeatedly crashing app
11990        // from blocking the user to manually clear the list.
11991        final ArrayList<ActivityRecord> activities = app.activities;
11992        if (app == mHomeProcess && activities.size() > 0
11993                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11994            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11995                final ActivityRecord r = activities.get(activityNdx);
11996                if (r.isHomeActivity()) {
11997                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11998                    try {
11999                        ActivityThread.getPackageManager()
12000                                .clearPackagePreferredActivities(r.packageName);
12001                    } catch (RemoteException c) {
12002                        // pm is in same process, this will never happen.
12003                    }
12004                }
12005            }
12006        }
12007
12008        if (!app.isolated) {
12009            // XXX Can't keep track of crash times for isolated processes,
12010            // because they don't have a perisistent identity.
12011            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12012        }
12013
12014        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12015        return true;
12016    }
12017
12018    void startAppProblemLocked(ProcessRecord app) {
12019        // If this app is not running under the current user, then we
12020        // can't give it a report button because that would require
12021        // launching the report UI under a different user.
12022        app.errorReportReceiver = null;
12023
12024        for (int userId : mCurrentProfileIds) {
12025            if (app.userId == userId) {
12026                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12027                        mContext, app.info.packageName, app.info.flags);
12028            }
12029        }
12030        skipCurrentReceiverLocked(app);
12031    }
12032
12033    void skipCurrentReceiverLocked(ProcessRecord app) {
12034        for (BroadcastQueue queue : mBroadcastQueues) {
12035            queue.skipCurrentReceiverLocked(app);
12036        }
12037    }
12038
12039    /**
12040     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12041     * The application process will exit immediately after this call returns.
12042     * @param app object of the crashing app, null for the system server
12043     * @param crashInfo describing the exception
12044     */
12045    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12046        ProcessRecord r = findAppProcess(app, "Crash");
12047        final String processName = app == null ? "system_server"
12048                : (r == null ? "unknown" : r.processName);
12049
12050        handleApplicationCrashInner("crash", r, processName, crashInfo);
12051    }
12052
12053    /* Native crash reporting uses this inner version because it needs to be somewhat
12054     * decoupled from the AM-managed cleanup lifecycle
12055     */
12056    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12057            ApplicationErrorReport.CrashInfo crashInfo) {
12058        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12059                UserHandle.getUserId(Binder.getCallingUid()), processName,
12060                r == null ? -1 : r.info.flags,
12061                crashInfo.exceptionClassName,
12062                crashInfo.exceptionMessage,
12063                crashInfo.throwFileName,
12064                crashInfo.throwLineNumber);
12065
12066        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12067
12068        crashApplication(r, crashInfo);
12069    }
12070
12071    public void handleApplicationStrictModeViolation(
12072            IBinder app,
12073            int violationMask,
12074            StrictMode.ViolationInfo info) {
12075        ProcessRecord r = findAppProcess(app, "StrictMode");
12076        if (r == null) {
12077            return;
12078        }
12079
12080        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12081            Integer stackFingerprint = info.hashCode();
12082            boolean logIt = true;
12083            synchronized (mAlreadyLoggedViolatedStacks) {
12084                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12085                    logIt = false;
12086                    // TODO: sub-sample into EventLog for these, with
12087                    // the info.durationMillis?  Then we'd get
12088                    // the relative pain numbers, without logging all
12089                    // the stack traces repeatedly.  We'd want to do
12090                    // likewise in the client code, which also does
12091                    // dup suppression, before the Binder call.
12092                } else {
12093                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12094                        mAlreadyLoggedViolatedStacks.clear();
12095                    }
12096                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12097                }
12098            }
12099            if (logIt) {
12100                logStrictModeViolationToDropBox(r, info);
12101            }
12102        }
12103
12104        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12105            AppErrorResult result = new AppErrorResult();
12106            synchronized (this) {
12107                final long origId = Binder.clearCallingIdentity();
12108
12109                Message msg = Message.obtain();
12110                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12111                HashMap<String, Object> data = new HashMap<String, Object>();
12112                data.put("result", result);
12113                data.put("app", r);
12114                data.put("violationMask", violationMask);
12115                data.put("info", info);
12116                msg.obj = data;
12117                mUiHandler.sendMessage(msg);
12118
12119                Binder.restoreCallingIdentity(origId);
12120            }
12121            int res = result.get();
12122            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12123        }
12124    }
12125
12126    // Depending on the policy in effect, there could be a bunch of
12127    // these in quick succession so we try to batch these together to
12128    // minimize disk writes, number of dropbox entries, and maximize
12129    // compression, by having more fewer, larger records.
12130    private void logStrictModeViolationToDropBox(
12131            ProcessRecord process,
12132            StrictMode.ViolationInfo info) {
12133        if (info == null) {
12134            return;
12135        }
12136        final boolean isSystemApp = process == null ||
12137                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12138                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12139        final String processName = process == null ? "unknown" : process.processName;
12140        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12141        final DropBoxManager dbox = (DropBoxManager)
12142                mContext.getSystemService(Context.DROPBOX_SERVICE);
12143
12144        // Exit early if the dropbox isn't configured to accept this report type.
12145        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12146
12147        boolean bufferWasEmpty;
12148        boolean needsFlush;
12149        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12150        synchronized (sb) {
12151            bufferWasEmpty = sb.length() == 0;
12152            appendDropBoxProcessHeaders(process, processName, sb);
12153            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12154            sb.append("System-App: ").append(isSystemApp).append("\n");
12155            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12156            if (info.violationNumThisLoop != 0) {
12157                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12158            }
12159            if (info.numAnimationsRunning != 0) {
12160                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12161            }
12162            if (info.broadcastIntentAction != null) {
12163                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12164            }
12165            if (info.durationMillis != -1) {
12166                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12167            }
12168            if (info.numInstances != -1) {
12169                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12170            }
12171            if (info.tags != null) {
12172                for (String tag : info.tags) {
12173                    sb.append("Span-Tag: ").append(tag).append("\n");
12174                }
12175            }
12176            sb.append("\n");
12177            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12178                sb.append(info.crashInfo.stackTrace);
12179                sb.append("\n");
12180            }
12181            if (info.message != null) {
12182                sb.append(info.message);
12183                sb.append("\n");
12184            }
12185
12186            // Only buffer up to ~64k.  Various logging bits truncate
12187            // things at 128k.
12188            needsFlush = (sb.length() > 64 * 1024);
12189        }
12190
12191        // Flush immediately if the buffer's grown too large, or this
12192        // is a non-system app.  Non-system apps are isolated with a
12193        // different tag & policy and not batched.
12194        //
12195        // Batching is useful during internal testing with
12196        // StrictMode settings turned up high.  Without batching,
12197        // thousands of separate files could be created on boot.
12198        if (!isSystemApp || needsFlush) {
12199            new Thread("Error dump: " + dropboxTag) {
12200                @Override
12201                public void run() {
12202                    String report;
12203                    synchronized (sb) {
12204                        report = sb.toString();
12205                        sb.delete(0, sb.length());
12206                        sb.trimToSize();
12207                    }
12208                    if (report.length() != 0) {
12209                        dbox.addText(dropboxTag, report);
12210                    }
12211                }
12212            }.start();
12213            return;
12214        }
12215
12216        // System app batching:
12217        if (!bufferWasEmpty) {
12218            // An existing dropbox-writing thread is outstanding, so
12219            // we don't need to start it up.  The existing thread will
12220            // catch the buffer appends we just did.
12221            return;
12222        }
12223
12224        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12225        // (After this point, we shouldn't access AMS internal data structures.)
12226        new Thread("Error dump: " + dropboxTag) {
12227            @Override
12228            public void run() {
12229                // 5 second sleep to let stacks arrive and be batched together
12230                try {
12231                    Thread.sleep(5000);  // 5 seconds
12232                } catch (InterruptedException e) {}
12233
12234                String errorReport;
12235                synchronized (mStrictModeBuffer) {
12236                    errorReport = mStrictModeBuffer.toString();
12237                    if (errorReport.length() == 0) {
12238                        return;
12239                    }
12240                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12241                    mStrictModeBuffer.trimToSize();
12242                }
12243                dbox.addText(dropboxTag, errorReport);
12244            }
12245        }.start();
12246    }
12247
12248    /**
12249     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12250     * @param app object of the crashing app, null for the system server
12251     * @param tag reported by the caller
12252     * @param system whether this wtf is coming from the system
12253     * @param crashInfo describing the context of the error
12254     * @return true if the process should exit immediately (WTF is fatal)
12255     */
12256    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12257            final ApplicationErrorReport.CrashInfo crashInfo) {
12258        final int callingUid = Binder.getCallingUid();
12259        final int callingPid = Binder.getCallingPid();
12260
12261        if (system) {
12262            // If this is coming from the system, we could very well have low-level
12263            // system locks held, so we want to do this all asynchronously.  And we
12264            // never want this to become fatal, so there is that too.
12265            mHandler.post(new Runnable() {
12266                @Override public void run() {
12267                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12268                }
12269            });
12270            return false;
12271        }
12272
12273        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12274                crashInfo);
12275
12276        if (r != null && r.pid != Process.myPid() &&
12277                Settings.Global.getInt(mContext.getContentResolver(),
12278                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12279            crashApplication(r, crashInfo);
12280            return true;
12281        } else {
12282            return false;
12283        }
12284    }
12285
12286    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12287            final ApplicationErrorReport.CrashInfo crashInfo) {
12288        final ProcessRecord r = findAppProcess(app, "WTF");
12289        final String processName = app == null ? "system_server"
12290                : (r == null ? "unknown" : r.processName);
12291
12292        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12293                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12294
12295        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12296
12297        return r;
12298    }
12299
12300    /**
12301     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12302     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12303     */
12304    private ProcessRecord findAppProcess(IBinder app, String reason) {
12305        if (app == null) {
12306            return null;
12307        }
12308
12309        synchronized (this) {
12310            final int NP = mProcessNames.getMap().size();
12311            for (int ip=0; ip<NP; ip++) {
12312                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12313                final int NA = apps.size();
12314                for (int ia=0; ia<NA; ia++) {
12315                    ProcessRecord p = apps.valueAt(ia);
12316                    if (p.thread != null && p.thread.asBinder() == app) {
12317                        return p;
12318                    }
12319                }
12320            }
12321
12322            Slog.w(TAG, "Can't find mystery application for " + reason
12323                    + " from pid=" + Binder.getCallingPid()
12324                    + " uid=" + Binder.getCallingUid() + ": " + app);
12325            return null;
12326        }
12327    }
12328
12329    /**
12330     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12331     * to append various headers to the dropbox log text.
12332     */
12333    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12334            StringBuilder sb) {
12335        // Watchdog thread ends up invoking this function (with
12336        // a null ProcessRecord) to add the stack file to dropbox.
12337        // Do not acquire a lock on this (am) in such cases, as it
12338        // could cause a potential deadlock, if and when watchdog
12339        // is invoked due to unavailability of lock on am and it
12340        // would prevent watchdog from killing system_server.
12341        if (process == null) {
12342            sb.append("Process: ").append(processName).append("\n");
12343            return;
12344        }
12345        // Note: ProcessRecord 'process' is guarded by the service
12346        // instance.  (notably process.pkgList, which could otherwise change
12347        // concurrently during execution of this method)
12348        synchronized (this) {
12349            sb.append("Process: ").append(processName).append("\n");
12350            int flags = process.info.flags;
12351            IPackageManager pm = AppGlobals.getPackageManager();
12352            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12353            for (int ip=0; ip<process.pkgList.size(); ip++) {
12354                String pkg = process.pkgList.keyAt(ip);
12355                sb.append("Package: ").append(pkg);
12356                try {
12357                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12358                    if (pi != null) {
12359                        sb.append(" v").append(pi.versionCode);
12360                        if (pi.versionName != null) {
12361                            sb.append(" (").append(pi.versionName).append(")");
12362                        }
12363                    }
12364                } catch (RemoteException e) {
12365                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12366                }
12367                sb.append("\n");
12368            }
12369        }
12370    }
12371
12372    private static String processClass(ProcessRecord process) {
12373        if (process == null || process.pid == MY_PID) {
12374            return "system_server";
12375        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12376            return "system_app";
12377        } else {
12378            return "data_app";
12379        }
12380    }
12381
12382    /**
12383     * Write a description of an error (crash, WTF, ANR) to the drop box.
12384     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12385     * @param process which caused the error, null means the system server
12386     * @param activity which triggered the error, null if unknown
12387     * @param parent activity related to the error, null if unknown
12388     * @param subject line related to the error, null if absent
12389     * @param report in long form describing the error, null if absent
12390     * @param logFile to include in the report, null if none
12391     * @param crashInfo giving an application stack trace, null if absent
12392     */
12393    public void addErrorToDropBox(String eventType,
12394            ProcessRecord process, String processName, ActivityRecord activity,
12395            ActivityRecord parent, String subject,
12396            final String report, final File logFile,
12397            final ApplicationErrorReport.CrashInfo crashInfo) {
12398        // NOTE -- this must never acquire the ActivityManagerService lock,
12399        // otherwise the watchdog may be prevented from resetting the system.
12400
12401        final String dropboxTag = processClass(process) + "_" + eventType;
12402        final DropBoxManager dbox = (DropBoxManager)
12403                mContext.getSystemService(Context.DROPBOX_SERVICE);
12404
12405        // Exit early if the dropbox isn't configured to accept this report type.
12406        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12407
12408        final StringBuilder sb = new StringBuilder(1024);
12409        appendDropBoxProcessHeaders(process, processName, sb);
12410        if (activity != null) {
12411            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12412        }
12413        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12414            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12415        }
12416        if (parent != null && parent != activity) {
12417            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12418        }
12419        if (subject != null) {
12420            sb.append("Subject: ").append(subject).append("\n");
12421        }
12422        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12423        if (Debug.isDebuggerConnected()) {
12424            sb.append("Debugger: Connected\n");
12425        }
12426        sb.append("\n");
12427
12428        // Do the rest in a worker thread to avoid blocking the caller on I/O
12429        // (After this point, we shouldn't access AMS internal data structures.)
12430        Thread worker = new Thread("Error dump: " + dropboxTag) {
12431            @Override
12432            public void run() {
12433                if (report != null) {
12434                    sb.append(report);
12435                }
12436                if (logFile != null) {
12437                    try {
12438                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12439                                    "\n\n[[TRUNCATED]]"));
12440                    } catch (IOException e) {
12441                        Slog.e(TAG, "Error reading " + logFile, e);
12442                    }
12443                }
12444                if (crashInfo != null && crashInfo.stackTrace != null) {
12445                    sb.append(crashInfo.stackTrace);
12446                }
12447
12448                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12449                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12450                if (lines > 0) {
12451                    sb.append("\n");
12452
12453                    // Merge several logcat streams, and take the last N lines
12454                    InputStreamReader input = null;
12455                    try {
12456                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12457                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12458                                "-b", "crash",
12459                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12460
12461                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12462                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12463                        input = new InputStreamReader(logcat.getInputStream());
12464
12465                        int num;
12466                        char[] buf = new char[8192];
12467                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12468                    } catch (IOException e) {
12469                        Slog.e(TAG, "Error running logcat", e);
12470                    } finally {
12471                        if (input != null) try { input.close(); } catch (IOException e) {}
12472                    }
12473                }
12474
12475                dbox.addText(dropboxTag, sb.toString());
12476            }
12477        };
12478
12479        if (process == null) {
12480            // If process is null, we are being called from some internal code
12481            // and may be about to die -- run this synchronously.
12482            worker.run();
12483        } else {
12484            worker.start();
12485        }
12486    }
12487
12488    /**
12489     * Bring up the "unexpected error" dialog box for a crashing app.
12490     * Deal with edge cases (intercepts from instrumented applications,
12491     * ActivityController, error intent receivers, that sort of thing).
12492     * @param r the application crashing
12493     * @param crashInfo describing the failure
12494     */
12495    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12496        long timeMillis = System.currentTimeMillis();
12497        String shortMsg = crashInfo.exceptionClassName;
12498        String longMsg = crashInfo.exceptionMessage;
12499        String stackTrace = crashInfo.stackTrace;
12500        if (shortMsg != null && longMsg != null) {
12501            longMsg = shortMsg + ": " + longMsg;
12502        } else if (shortMsg != null) {
12503            longMsg = shortMsg;
12504        }
12505
12506        AppErrorResult result = new AppErrorResult();
12507        synchronized (this) {
12508            if (mController != null) {
12509                try {
12510                    String name = r != null ? r.processName : null;
12511                    int pid = r != null ? r.pid : Binder.getCallingPid();
12512                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12513                    if (!mController.appCrashed(name, pid,
12514                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12515                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12516                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12517                            Slog.w(TAG, "Skip killing native crashed app " + name
12518                                    + "(" + pid + ") during testing");
12519                        } else {
12520                            Slog.w(TAG, "Force-killing crashed app " + name
12521                                    + " at watcher's request");
12522                            if (r != null) {
12523                                r.kill("crash", true);
12524                            } else {
12525                                // Huh.
12526                                Process.killProcess(pid);
12527                                killProcessGroup(uid, pid);
12528                            }
12529                        }
12530                        return;
12531                    }
12532                } catch (RemoteException e) {
12533                    mController = null;
12534                    Watchdog.getInstance().setActivityController(null);
12535                }
12536            }
12537
12538            final long origId = Binder.clearCallingIdentity();
12539
12540            // If this process is running instrumentation, finish it.
12541            if (r != null && r.instrumentationClass != null) {
12542                Slog.w(TAG, "Error in app " + r.processName
12543                      + " running instrumentation " + r.instrumentationClass + ":");
12544                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12545                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12546                Bundle info = new Bundle();
12547                info.putString("shortMsg", shortMsg);
12548                info.putString("longMsg", longMsg);
12549                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12550                Binder.restoreCallingIdentity(origId);
12551                return;
12552            }
12553
12554            // Log crash in battery stats.
12555            if (r != null) {
12556                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12557            }
12558
12559            // If we can't identify the process or it's already exceeded its crash quota,
12560            // quit right away without showing a crash dialog.
12561            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12562                Binder.restoreCallingIdentity(origId);
12563                return;
12564            }
12565
12566            Message msg = Message.obtain();
12567            msg.what = SHOW_ERROR_MSG;
12568            HashMap data = new HashMap();
12569            data.put("result", result);
12570            data.put("app", r);
12571            msg.obj = data;
12572            mUiHandler.sendMessage(msg);
12573
12574            Binder.restoreCallingIdentity(origId);
12575        }
12576
12577        int res = result.get();
12578
12579        Intent appErrorIntent = null;
12580        synchronized (this) {
12581            if (r != null && !r.isolated) {
12582                // XXX Can't keep track of crash time for isolated processes,
12583                // since they don't have a persistent identity.
12584                mProcessCrashTimes.put(r.info.processName, r.uid,
12585                        SystemClock.uptimeMillis());
12586            }
12587            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12588                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12589            }
12590        }
12591
12592        if (appErrorIntent != null) {
12593            try {
12594                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12595            } catch (ActivityNotFoundException e) {
12596                Slog.w(TAG, "bug report receiver dissappeared", e);
12597            }
12598        }
12599    }
12600
12601    Intent createAppErrorIntentLocked(ProcessRecord r,
12602            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12603        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12604        if (report == null) {
12605            return null;
12606        }
12607        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12608        result.setComponent(r.errorReportReceiver);
12609        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12610        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12611        return result;
12612    }
12613
12614    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12615            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12616        if (r.errorReportReceiver == null) {
12617            return null;
12618        }
12619
12620        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12621            return null;
12622        }
12623
12624        ApplicationErrorReport report = new ApplicationErrorReport();
12625        report.packageName = r.info.packageName;
12626        report.installerPackageName = r.errorReportReceiver.getPackageName();
12627        report.processName = r.processName;
12628        report.time = timeMillis;
12629        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12630
12631        if (r.crashing || r.forceCrashReport) {
12632            report.type = ApplicationErrorReport.TYPE_CRASH;
12633            report.crashInfo = crashInfo;
12634        } else if (r.notResponding) {
12635            report.type = ApplicationErrorReport.TYPE_ANR;
12636            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12637
12638            report.anrInfo.activity = r.notRespondingReport.tag;
12639            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12640            report.anrInfo.info = r.notRespondingReport.longMsg;
12641        }
12642
12643        return report;
12644    }
12645
12646    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12647        enforceNotIsolatedCaller("getProcessesInErrorState");
12648        // assume our apps are happy - lazy create the list
12649        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12650
12651        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12652                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12653        int userId = UserHandle.getUserId(Binder.getCallingUid());
12654
12655        synchronized (this) {
12656
12657            // iterate across all processes
12658            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12659                ProcessRecord app = mLruProcesses.get(i);
12660                if (!allUsers && app.userId != userId) {
12661                    continue;
12662                }
12663                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12664                    // This one's in trouble, so we'll generate a report for it
12665                    // crashes are higher priority (in case there's a crash *and* an anr)
12666                    ActivityManager.ProcessErrorStateInfo report = null;
12667                    if (app.crashing) {
12668                        report = app.crashingReport;
12669                    } else if (app.notResponding) {
12670                        report = app.notRespondingReport;
12671                    }
12672
12673                    if (report != null) {
12674                        if (errList == null) {
12675                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12676                        }
12677                        errList.add(report);
12678                    } else {
12679                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12680                                " crashing = " + app.crashing +
12681                                " notResponding = " + app.notResponding);
12682                    }
12683                }
12684            }
12685        }
12686
12687        return errList;
12688    }
12689
12690    static int procStateToImportance(int procState, int memAdj,
12691            ActivityManager.RunningAppProcessInfo currApp) {
12692        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12693        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12694            currApp.lru = memAdj;
12695        } else {
12696            currApp.lru = 0;
12697        }
12698        return imp;
12699    }
12700
12701    private void fillInProcMemInfo(ProcessRecord app,
12702            ActivityManager.RunningAppProcessInfo outInfo) {
12703        outInfo.pid = app.pid;
12704        outInfo.uid = app.info.uid;
12705        if (mHeavyWeightProcess == app) {
12706            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12707        }
12708        if (app.persistent) {
12709            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12710        }
12711        if (app.activities.size() > 0) {
12712            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12713        }
12714        outInfo.lastTrimLevel = app.trimMemoryLevel;
12715        int adj = app.curAdj;
12716        int procState = app.curProcState;
12717        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12718        outInfo.importanceReasonCode = app.adjTypeCode;
12719        outInfo.processState = app.curProcState;
12720    }
12721
12722    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12723        enforceNotIsolatedCaller("getRunningAppProcesses");
12724
12725        final int callingUid = Binder.getCallingUid();
12726
12727        // Lazy instantiation of list
12728        List<ActivityManager.RunningAppProcessInfo> runList = null;
12729        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12730                callingUid) == PackageManager.PERMISSION_GRANTED;
12731        final int userId = UserHandle.getUserId(callingUid);
12732        final boolean allUids = isGetTasksAllowed(
12733                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12734
12735        synchronized (this) {
12736            // Iterate across all processes
12737            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12738                ProcessRecord app = mLruProcesses.get(i);
12739                if ((!allUsers && app.userId != userId)
12740                        || (!allUids && app.uid != callingUid)) {
12741                    continue;
12742                }
12743                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12744                    // Generate process state info for running application
12745                    ActivityManager.RunningAppProcessInfo currApp =
12746                        new ActivityManager.RunningAppProcessInfo(app.processName,
12747                                app.pid, app.getPackageList());
12748                    fillInProcMemInfo(app, currApp);
12749                    if (app.adjSource instanceof ProcessRecord) {
12750                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12751                        currApp.importanceReasonImportance =
12752                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12753                                        app.adjSourceProcState);
12754                    } else if (app.adjSource instanceof ActivityRecord) {
12755                        ActivityRecord r = (ActivityRecord)app.adjSource;
12756                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12757                    }
12758                    if (app.adjTarget instanceof ComponentName) {
12759                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12760                    }
12761                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12762                    //        + " lru=" + currApp.lru);
12763                    if (runList == null) {
12764                        runList = new ArrayList<>();
12765                    }
12766                    runList.add(currApp);
12767                }
12768            }
12769        }
12770        return runList;
12771    }
12772
12773    public List<ApplicationInfo> getRunningExternalApplications() {
12774        enforceNotIsolatedCaller("getRunningExternalApplications");
12775        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12776        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12777        if (runningApps != null && runningApps.size() > 0) {
12778            Set<String> extList = new HashSet<String>();
12779            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12780                if (app.pkgList != null) {
12781                    for (String pkg : app.pkgList) {
12782                        extList.add(pkg);
12783                    }
12784                }
12785            }
12786            IPackageManager pm = AppGlobals.getPackageManager();
12787            for (String pkg : extList) {
12788                try {
12789                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12790                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12791                        retList.add(info);
12792                    }
12793                } catch (RemoteException e) {
12794                }
12795            }
12796        }
12797        return retList;
12798    }
12799
12800    @Override
12801    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12802        enforceNotIsolatedCaller("getMyMemoryState");
12803        synchronized (this) {
12804            ProcessRecord proc;
12805            synchronized (mPidsSelfLocked) {
12806                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12807            }
12808            fillInProcMemInfo(proc, outInfo);
12809        }
12810    }
12811
12812    @Override
12813    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12814        if (checkCallingPermission(android.Manifest.permission.DUMP)
12815                != PackageManager.PERMISSION_GRANTED) {
12816            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12817                    + Binder.getCallingPid()
12818                    + ", uid=" + Binder.getCallingUid()
12819                    + " without permission "
12820                    + android.Manifest.permission.DUMP);
12821            return;
12822        }
12823
12824        boolean dumpAll = false;
12825        boolean dumpClient = false;
12826        String dumpPackage = null;
12827
12828        int opti = 0;
12829        while (opti < args.length) {
12830            String opt = args[opti];
12831            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12832                break;
12833            }
12834            opti++;
12835            if ("-a".equals(opt)) {
12836                dumpAll = true;
12837            } else if ("-c".equals(opt)) {
12838                dumpClient = true;
12839            } else if ("-p".equals(opt)) {
12840                if (opti < args.length) {
12841                    dumpPackage = args[opti];
12842                    opti++;
12843                } else {
12844                    pw.println("Error: -p option requires package argument");
12845                    return;
12846                }
12847                dumpClient = true;
12848            } else if ("-h".equals(opt)) {
12849                pw.println("Activity manager dump options:");
12850                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12851                pw.println("  cmd may be one of:");
12852                pw.println("    a[ctivities]: activity stack state");
12853                pw.println("    r[recents]: recent activities state");
12854                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12855                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12856                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12857                pw.println("    o[om]: out of memory management");
12858                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12859                pw.println("    provider [COMP_SPEC]: provider client-side state");
12860                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12861                pw.println("    as[sociations]: tracked app associations");
12862                pw.println("    service [COMP_SPEC]: service client-side state");
12863                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12864                pw.println("    all: dump all activities");
12865                pw.println("    top: dump the top activity");
12866                pw.println("    write: write all pending state to storage");
12867                pw.println("    track-associations: enable association tracking");
12868                pw.println("    untrack-associations: disable and clear association tracking");
12869                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12870                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12871                pw.println("    a partial substring in a component name, a");
12872                pw.println("    hex object identifier.");
12873                pw.println("  -a: include all available server state.");
12874                pw.println("  -c: include client state.");
12875                pw.println("  -p: limit output to given package.");
12876                return;
12877            } else {
12878                pw.println("Unknown argument: " + opt + "; use -h for help");
12879            }
12880        }
12881
12882        long origId = Binder.clearCallingIdentity();
12883        boolean more = false;
12884        // Is the caller requesting to dump a particular piece of data?
12885        if (opti < args.length) {
12886            String cmd = args[opti];
12887            opti++;
12888            if ("activities".equals(cmd) || "a".equals(cmd)) {
12889                synchronized (this) {
12890                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12891                }
12892            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12893                synchronized (this) {
12894                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12895                }
12896            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12897                String[] newArgs;
12898                String name;
12899                if (opti >= args.length) {
12900                    name = null;
12901                    newArgs = EMPTY_STRING_ARRAY;
12902                } else {
12903                    dumpPackage = args[opti];
12904                    opti++;
12905                    newArgs = new String[args.length - opti];
12906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12907                            args.length - opti);
12908                }
12909                synchronized (this) {
12910                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12911                }
12912            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12913                String[] newArgs;
12914                String name;
12915                if (opti >= args.length) {
12916                    name = null;
12917                    newArgs = EMPTY_STRING_ARRAY;
12918                } else {
12919                    dumpPackage = args[opti];
12920                    opti++;
12921                    newArgs = new String[args.length - opti];
12922                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12923                            args.length - opti);
12924                }
12925                synchronized (this) {
12926                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12927                }
12928            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12929                String[] newArgs;
12930                String name;
12931                if (opti >= args.length) {
12932                    name = null;
12933                    newArgs = EMPTY_STRING_ARRAY;
12934                } else {
12935                    dumpPackage = args[opti];
12936                    opti++;
12937                    newArgs = new String[args.length - opti];
12938                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12939                            args.length - opti);
12940                }
12941                synchronized (this) {
12942                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12943                }
12944            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12945                synchronized (this) {
12946                    dumpOomLocked(fd, pw, args, opti, true);
12947                }
12948            } else if ("provider".equals(cmd)) {
12949                String[] newArgs;
12950                String name;
12951                if (opti >= args.length) {
12952                    name = null;
12953                    newArgs = EMPTY_STRING_ARRAY;
12954                } else {
12955                    name = args[opti];
12956                    opti++;
12957                    newArgs = new String[args.length - opti];
12958                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12959                }
12960                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12961                    pw.println("No providers match: " + name);
12962                    pw.println("Use -h for help.");
12963                }
12964            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12965                synchronized (this) {
12966                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12967                }
12968            } else if ("service".equals(cmd)) {
12969                String[] newArgs;
12970                String name;
12971                if (opti >= args.length) {
12972                    name = null;
12973                    newArgs = EMPTY_STRING_ARRAY;
12974                } else {
12975                    name = args[opti];
12976                    opti++;
12977                    newArgs = new String[args.length - opti];
12978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12979                            args.length - opti);
12980                }
12981                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12982                    pw.println("No services match: " + name);
12983                    pw.println("Use -h for help.");
12984                }
12985            } else if ("package".equals(cmd)) {
12986                String[] newArgs;
12987                if (opti >= args.length) {
12988                    pw.println("package: no package name specified");
12989                    pw.println("Use -h for help.");
12990                } else {
12991                    dumpPackage = args[opti];
12992                    opti++;
12993                    newArgs = new String[args.length - opti];
12994                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12995                            args.length - opti);
12996                    args = newArgs;
12997                    opti = 0;
12998                    more = true;
12999                }
13000            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13001                synchronized (this) {
13002                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13003                }
13004            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13005                synchronized (this) {
13006                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13007                }
13008            } else if ("write".equals(cmd)) {
13009                mTaskPersister.flush();
13010                pw.println("All tasks persisted.");
13011                return;
13012            } else if ("track-associations".equals(cmd)) {
13013                synchronized (this) {
13014                    if (!mTrackingAssociations) {
13015                        mTrackingAssociations = true;
13016                        pw.println("Association tracking started.");
13017                    } else {
13018                        pw.println("Association tracking already enabled.");
13019                    }
13020                }
13021                return;
13022            } else if ("untrack-associations".equals(cmd)) {
13023                synchronized (this) {
13024                    if (mTrackingAssociations) {
13025                        mTrackingAssociations = false;
13026                        mAssociations.clear();
13027                        pw.println("Association tracking stopped.");
13028                    } else {
13029                        pw.println("Association tracking not running.");
13030                    }
13031                }
13032                return;
13033            } else {
13034                // Dumping a single activity?
13035                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13036                    pw.println("Bad activity command, or no activities match: " + cmd);
13037                    pw.println("Use -h for help.");
13038                }
13039            }
13040            if (!more) {
13041                Binder.restoreCallingIdentity(origId);
13042                return;
13043            }
13044        }
13045
13046        // No piece of data specified, dump everything.
13047        synchronized (this) {
13048            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13049            pw.println();
13050            if (dumpAll) {
13051                pw.println("-------------------------------------------------------------------------------");
13052            }
13053            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13054            pw.println();
13055            if (dumpAll) {
13056                pw.println("-------------------------------------------------------------------------------");
13057            }
13058            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13059            pw.println();
13060            if (dumpAll) {
13061                pw.println("-------------------------------------------------------------------------------");
13062            }
13063            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13064            pw.println();
13065            if (dumpAll) {
13066                pw.println("-------------------------------------------------------------------------------");
13067            }
13068            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13069            pw.println();
13070            if (dumpAll) {
13071                pw.println("-------------------------------------------------------------------------------");
13072            }
13073            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13074            if (mAssociations.size() > 0) {
13075                pw.println();
13076                if (dumpAll) {
13077                    pw.println("-------------------------------------------------------------------------------");
13078                }
13079                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13080            }
13081            pw.println();
13082            if (dumpAll) {
13083                pw.println("-------------------------------------------------------------------------------");
13084            }
13085            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13086        }
13087        Binder.restoreCallingIdentity(origId);
13088    }
13089
13090    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13091            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13092        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13093
13094        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13095                dumpPackage);
13096        boolean needSep = printedAnything;
13097
13098        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13099                dumpPackage, needSep, "  mFocusedActivity: ");
13100        if (printed) {
13101            printedAnything = true;
13102            needSep = false;
13103        }
13104
13105        if (dumpPackage == null) {
13106            if (needSep) {
13107                pw.println();
13108            }
13109            needSep = true;
13110            printedAnything = true;
13111            mStackSupervisor.dump(pw, "  ");
13112        }
13113
13114        if (!printedAnything) {
13115            pw.println("  (nothing)");
13116        }
13117    }
13118
13119    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13120            int opti, boolean dumpAll, String dumpPackage) {
13121        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13122
13123        boolean printedAnything = false;
13124
13125        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13126            boolean printedHeader = false;
13127
13128            final int N = mRecentTasks.size();
13129            for (int i=0; i<N; i++) {
13130                TaskRecord tr = mRecentTasks.get(i);
13131                if (dumpPackage != null) {
13132                    if (tr.realActivity == null ||
13133                            !dumpPackage.equals(tr.realActivity)) {
13134                        continue;
13135                    }
13136                }
13137                if (!printedHeader) {
13138                    pw.println("  Recent tasks:");
13139                    printedHeader = true;
13140                    printedAnything = true;
13141                }
13142                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13143                        pw.println(tr);
13144                if (dumpAll) {
13145                    mRecentTasks.get(i).dump(pw, "    ");
13146                }
13147            }
13148        }
13149
13150        if (!printedAnything) {
13151            pw.println("  (nothing)");
13152        }
13153    }
13154
13155    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13156            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13157        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13158
13159        int dumpUid = 0;
13160        if (dumpPackage != null) {
13161            IPackageManager pm = AppGlobals.getPackageManager();
13162            try {
13163                dumpUid = pm.getPackageUid(dumpPackage, 0);
13164            } catch (RemoteException e) {
13165            }
13166        }
13167
13168        boolean printedAnything = false;
13169
13170        final long now = SystemClock.uptimeMillis();
13171
13172        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13173            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13174                    = mAssociations.valueAt(i1);
13175            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13176                SparseArray<ArrayMap<String, Association>> sourceUids
13177                        = targetComponents.valueAt(i2);
13178                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13179                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13180                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13181                        Association ass = sourceProcesses.valueAt(i4);
13182                        if (dumpPackage != null) {
13183                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13184                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13185                                continue;
13186                            }
13187                        }
13188                        printedAnything = true;
13189                        pw.print("  ");
13190                        pw.print(ass.mTargetProcess);
13191                        pw.print("/");
13192                        UserHandle.formatUid(pw, ass.mTargetUid);
13193                        pw.print(" <- ");
13194                        pw.print(ass.mSourceProcess);
13195                        pw.print("/");
13196                        UserHandle.formatUid(pw, ass.mSourceUid);
13197                        pw.println();
13198                        pw.print("    via ");
13199                        pw.print(ass.mTargetComponent.flattenToShortString());
13200                        pw.println();
13201                        pw.print("    ");
13202                        long dur = ass.mTime;
13203                        if (ass.mNesting > 0) {
13204                            dur += now - ass.mStartTime;
13205                        }
13206                        TimeUtils.formatDuration(dur, pw);
13207                        pw.print(" (");
13208                        pw.print(ass.mCount);
13209                        pw.println(" times)");
13210                        if (ass.mNesting > 0) {
13211                            pw.print("    ");
13212                            pw.print(" Currently active: ");
13213                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13214                            pw.println();
13215                        }
13216                    }
13217                }
13218            }
13219
13220        }
13221
13222        if (!printedAnything) {
13223            pw.println("  (nothing)");
13224        }
13225    }
13226
13227    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13228            int opti, boolean dumpAll, String dumpPackage) {
13229        boolean needSep = false;
13230        boolean printedAnything = false;
13231        int numPers = 0;
13232
13233        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13234
13235        if (dumpAll) {
13236            final int NP = mProcessNames.getMap().size();
13237            for (int ip=0; ip<NP; ip++) {
13238                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13239                final int NA = procs.size();
13240                for (int ia=0; ia<NA; ia++) {
13241                    ProcessRecord r = procs.valueAt(ia);
13242                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13243                        continue;
13244                    }
13245                    if (!needSep) {
13246                        pw.println("  All known processes:");
13247                        needSep = true;
13248                        printedAnything = true;
13249                    }
13250                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13251                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13252                        pw.print(" "); pw.println(r);
13253                    r.dump(pw, "    ");
13254                    if (r.persistent) {
13255                        numPers++;
13256                    }
13257                }
13258            }
13259        }
13260
13261        if (mIsolatedProcesses.size() > 0) {
13262            boolean printed = false;
13263            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13264                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13265                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13266                    continue;
13267                }
13268                if (!printed) {
13269                    if (needSep) {
13270                        pw.println();
13271                    }
13272                    pw.println("  Isolated process list (sorted by uid):");
13273                    printedAnything = true;
13274                    printed = true;
13275                    needSep = true;
13276                }
13277                pw.println(String.format("%sIsolated #%2d: %s",
13278                        "    ", i, r.toString()));
13279            }
13280        }
13281
13282        if (mActiveUids.size() > 0) {
13283            if (needSep) {
13284                pw.println();
13285            }
13286            pw.println("  UID states:");
13287            for (int i=0; i<mActiveUids.size(); i++) {
13288                UidRecord uidRec = mActiveUids.valueAt(i);
13289                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13290                pw.print(": "); pw.println(uidRec);
13291            }
13292            needSep = true;
13293            printedAnything = true;
13294        }
13295
13296        if (mLruProcesses.size() > 0) {
13297            if (needSep) {
13298                pw.println();
13299            }
13300            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13301                    pw.print(" total, non-act at ");
13302                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13303                    pw.print(", non-svc at ");
13304                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13305                    pw.println("):");
13306            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13307            needSep = true;
13308            printedAnything = true;
13309        }
13310
13311        if (dumpAll || dumpPackage != null) {
13312            synchronized (mPidsSelfLocked) {
13313                boolean printed = false;
13314                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13315                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13316                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13317                        continue;
13318                    }
13319                    if (!printed) {
13320                        if (needSep) pw.println();
13321                        needSep = true;
13322                        pw.println("  PID mappings:");
13323                        printed = true;
13324                        printedAnything = true;
13325                    }
13326                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13327                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13328                }
13329            }
13330        }
13331
13332        if (mForegroundProcesses.size() > 0) {
13333            synchronized (mPidsSelfLocked) {
13334                boolean printed = false;
13335                for (int i=0; i<mForegroundProcesses.size(); i++) {
13336                    ProcessRecord r = mPidsSelfLocked.get(
13337                            mForegroundProcesses.valueAt(i).pid);
13338                    if (dumpPackage != null && (r == null
13339                            || !r.pkgList.containsKey(dumpPackage))) {
13340                        continue;
13341                    }
13342                    if (!printed) {
13343                        if (needSep) pw.println();
13344                        needSep = true;
13345                        pw.println("  Foreground Processes:");
13346                        printed = true;
13347                        printedAnything = true;
13348                    }
13349                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13350                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13351                }
13352            }
13353        }
13354
13355        if (mPersistentStartingProcesses.size() > 0) {
13356            if (needSep) pw.println();
13357            needSep = true;
13358            printedAnything = true;
13359            pw.println("  Persisent processes that are starting:");
13360            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13361                    "Starting Norm", "Restarting PERS", dumpPackage);
13362        }
13363
13364        if (mRemovedProcesses.size() > 0) {
13365            if (needSep) pw.println();
13366            needSep = true;
13367            printedAnything = true;
13368            pw.println("  Processes that are being removed:");
13369            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13370                    "Removed Norm", "Removed PERS", dumpPackage);
13371        }
13372
13373        if (mProcessesOnHold.size() > 0) {
13374            if (needSep) pw.println();
13375            needSep = true;
13376            printedAnything = true;
13377            pw.println("  Processes that are on old until the system is ready:");
13378            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13379                    "OnHold Norm", "OnHold PERS", dumpPackage);
13380        }
13381
13382        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13383
13384        if (mProcessCrashTimes.getMap().size() > 0) {
13385            boolean printed = false;
13386            long now = SystemClock.uptimeMillis();
13387            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13388            final int NP = pmap.size();
13389            for (int ip=0; ip<NP; ip++) {
13390                String pname = pmap.keyAt(ip);
13391                SparseArray<Long> uids = pmap.valueAt(ip);
13392                final int N = uids.size();
13393                for (int i=0; i<N; i++) {
13394                    int puid = uids.keyAt(i);
13395                    ProcessRecord r = mProcessNames.get(pname, puid);
13396                    if (dumpPackage != null && (r == null
13397                            || !r.pkgList.containsKey(dumpPackage))) {
13398                        continue;
13399                    }
13400                    if (!printed) {
13401                        if (needSep) pw.println();
13402                        needSep = true;
13403                        pw.println("  Time since processes crashed:");
13404                        printed = true;
13405                        printedAnything = true;
13406                    }
13407                    pw.print("    Process "); pw.print(pname);
13408                            pw.print(" uid "); pw.print(puid);
13409                            pw.print(": last crashed ");
13410                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13411                            pw.println(" ago");
13412                }
13413            }
13414        }
13415
13416        if (mBadProcesses.getMap().size() > 0) {
13417            boolean printed = false;
13418            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13419            final int NP = pmap.size();
13420            for (int ip=0; ip<NP; ip++) {
13421                String pname = pmap.keyAt(ip);
13422                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13423                final int N = uids.size();
13424                for (int i=0; i<N; i++) {
13425                    int puid = uids.keyAt(i);
13426                    ProcessRecord r = mProcessNames.get(pname, puid);
13427                    if (dumpPackage != null && (r == null
13428                            || !r.pkgList.containsKey(dumpPackage))) {
13429                        continue;
13430                    }
13431                    if (!printed) {
13432                        if (needSep) pw.println();
13433                        needSep = true;
13434                        pw.println("  Bad processes:");
13435                        printedAnything = true;
13436                    }
13437                    BadProcessInfo info = uids.valueAt(i);
13438                    pw.print("    Bad process "); pw.print(pname);
13439                            pw.print(" uid "); pw.print(puid);
13440                            pw.print(": crashed at time "); pw.println(info.time);
13441                    if (info.shortMsg != null) {
13442                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13443                    }
13444                    if (info.longMsg != null) {
13445                        pw.print("      Long msg: "); pw.println(info.longMsg);
13446                    }
13447                    if (info.stack != null) {
13448                        pw.println("      Stack:");
13449                        int lastPos = 0;
13450                        for (int pos=0; pos<info.stack.length(); pos++) {
13451                            if (info.stack.charAt(pos) == '\n') {
13452                                pw.print("        ");
13453                                pw.write(info.stack, lastPos, pos-lastPos);
13454                                pw.println();
13455                                lastPos = pos+1;
13456                            }
13457                        }
13458                        if (lastPos < info.stack.length()) {
13459                            pw.print("        ");
13460                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13461                            pw.println();
13462                        }
13463                    }
13464                }
13465            }
13466        }
13467
13468        if (dumpPackage == null) {
13469            pw.println();
13470            needSep = false;
13471            pw.println("  mStartedUsers:");
13472            for (int i=0; i<mStartedUsers.size(); i++) {
13473                UserState uss = mStartedUsers.valueAt(i);
13474                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13475                        pw.print(": "); uss.dump("", pw);
13476            }
13477            pw.print("  mStartedUserArray: [");
13478            for (int i=0; i<mStartedUserArray.length; i++) {
13479                if (i > 0) pw.print(", ");
13480                pw.print(mStartedUserArray[i]);
13481            }
13482            pw.println("]");
13483            pw.print("  mUserLru: [");
13484            for (int i=0; i<mUserLru.size(); i++) {
13485                if (i > 0) pw.print(", ");
13486                pw.print(mUserLru.get(i));
13487            }
13488            pw.println("]");
13489            if (dumpAll) {
13490                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13491            }
13492            synchronized (mUserProfileGroupIdsSelfLocked) {
13493                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13494                    pw.println("  mUserProfileGroupIds:");
13495                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13496                        pw.print("    User #");
13497                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13498                        pw.print(" -> profile #");
13499                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13500                    }
13501                }
13502            }
13503        }
13504        if (mHomeProcess != null && (dumpPackage == null
13505                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13506            if (needSep) {
13507                pw.println();
13508                needSep = false;
13509            }
13510            pw.println("  mHomeProcess: " + mHomeProcess);
13511        }
13512        if (mPreviousProcess != null && (dumpPackage == null
13513                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13514            if (needSep) {
13515                pw.println();
13516                needSep = false;
13517            }
13518            pw.println("  mPreviousProcess: " + mPreviousProcess);
13519        }
13520        if (dumpAll) {
13521            StringBuilder sb = new StringBuilder(128);
13522            sb.append("  mPreviousProcessVisibleTime: ");
13523            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13524            pw.println(sb);
13525        }
13526        if (mHeavyWeightProcess != null && (dumpPackage == null
13527                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13528            if (needSep) {
13529                pw.println();
13530                needSep = false;
13531            }
13532            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13533        }
13534        if (dumpPackage == null) {
13535            pw.println("  mConfiguration: " + mConfiguration);
13536        }
13537        if (dumpAll) {
13538            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13539            if (mCompatModePackages.getPackages().size() > 0) {
13540                boolean printed = false;
13541                for (Map.Entry<String, Integer> entry
13542                        : mCompatModePackages.getPackages().entrySet()) {
13543                    String pkg = entry.getKey();
13544                    int mode = entry.getValue();
13545                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13546                        continue;
13547                    }
13548                    if (!printed) {
13549                        pw.println("  mScreenCompatPackages:");
13550                        printed = true;
13551                    }
13552                    pw.print("    "); pw.print(pkg); pw.print(": ");
13553                            pw.print(mode); pw.println();
13554                }
13555            }
13556        }
13557        if (dumpPackage == null) {
13558            pw.println("  mWakefulness="
13559                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13560            pw.println("  mSleepTokens=" + mSleepTokens);
13561            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13562                    + lockScreenShownToString());
13563            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13564            if (mRunningVoice != null) {
13565                pw.println("  mRunningVoice=" + mRunningVoice);
13566                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13567            }
13568        }
13569        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13570                || mOrigWaitForDebugger) {
13571            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13572                    || dumpPackage.equals(mOrigDebugApp)) {
13573                if (needSep) {
13574                    pw.println();
13575                    needSep = false;
13576                }
13577                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13578                        + " mDebugTransient=" + mDebugTransient
13579                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13580            }
13581        }
13582        if (mCurAppTimeTracker != null) {
13583            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13584        }
13585        if (mMemWatchProcesses.getMap().size() > 0) {
13586            pw.println("  Mem watch processes:");
13587            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13588                    = mMemWatchProcesses.getMap();
13589            for (int i=0; i<procs.size(); i++) {
13590                final String proc = procs.keyAt(i);
13591                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13592                for (int j=0; j<uids.size(); j++) {
13593                    if (needSep) {
13594                        pw.println();
13595                        needSep = false;
13596                    }
13597                    StringBuilder sb = new StringBuilder();
13598                    sb.append("    ").append(proc).append('/');
13599                    UserHandle.formatUid(sb, uids.keyAt(j));
13600                    Pair<Long, String> val = uids.valueAt(j);
13601                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13602                    if (val.second != null) {
13603                        sb.append(", report to ").append(val.second);
13604                    }
13605                    pw.println(sb.toString());
13606                }
13607            }
13608            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13609            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13610            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13611                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13612        }
13613        if (mOpenGlTraceApp != null) {
13614            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13615                if (needSep) {
13616                    pw.println();
13617                    needSep = false;
13618                }
13619                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13620            }
13621        }
13622        if (mTrackAllocationApp != null) {
13623            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13624                if (needSep) {
13625                    pw.println();
13626                    needSep = false;
13627                }
13628                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13629            }
13630        }
13631        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13632                || mProfileFd != null) {
13633            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13634                if (needSep) {
13635                    pw.println();
13636                    needSep = false;
13637                }
13638                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13639                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13640                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13641                        + mAutoStopProfiler);
13642                pw.println("  mProfileType=" + mProfileType);
13643            }
13644        }
13645        if (dumpPackage == null) {
13646            if (mAlwaysFinishActivities || mController != null) {
13647                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13648                        + " mController=" + mController);
13649            }
13650            if (dumpAll) {
13651                pw.println("  Total persistent processes: " + numPers);
13652                pw.println("  mProcessesReady=" + mProcessesReady
13653                        + " mSystemReady=" + mSystemReady
13654                        + " mBooted=" + mBooted
13655                        + " mFactoryTest=" + mFactoryTest);
13656                pw.println("  mBooting=" + mBooting
13657                        + " mCallFinishBooting=" + mCallFinishBooting
13658                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13659                pw.print("  mLastPowerCheckRealtime=");
13660                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13661                        pw.println("");
13662                pw.print("  mLastPowerCheckUptime=");
13663                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13664                        pw.println("");
13665                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13666                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13667                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13668                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13669                        + " (" + mLruProcesses.size() + " total)"
13670                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13671                        + " mNumServiceProcs=" + mNumServiceProcs
13672                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13673                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13674                        + " mLastMemoryLevel" + mLastMemoryLevel
13675                        + " mLastNumProcesses" + mLastNumProcesses);
13676                long now = SystemClock.uptimeMillis();
13677                pw.print("  mLastIdleTime=");
13678                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13679                        pw.print(" mLowRamSinceLastIdle=");
13680                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13681                        pw.println();
13682            }
13683        }
13684
13685        if (!printedAnything) {
13686            pw.println("  (nothing)");
13687        }
13688    }
13689
13690    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13691            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13692        if (mProcessesToGc.size() > 0) {
13693            boolean printed = false;
13694            long now = SystemClock.uptimeMillis();
13695            for (int i=0; i<mProcessesToGc.size(); i++) {
13696                ProcessRecord proc = mProcessesToGc.get(i);
13697                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13698                    continue;
13699                }
13700                if (!printed) {
13701                    if (needSep) pw.println();
13702                    needSep = true;
13703                    pw.println("  Processes that are waiting to GC:");
13704                    printed = true;
13705                }
13706                pw.print("    Process "); pw.println(proc);
13707                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13708                        pw.print(", last gced=");
13709                        pw.print(now-proc.lastRequestedGc);
13710                        pw.print(" ms ago, last lowMem=");
13711                        pw.print(now-proc.lastLowMemory);
13712                        pw.println(" ms ago");
13713
13714            }
13715        }
13716        return needSep;
13717    }
13718
13719    void printOomLevel(PrintWriter pw, String name, int adj) {
13720        pw.print("    ");
13721        if (adj >= 0) {
13722            pw.print(' ');
13723            if (adj < 10) pw.print(' ');
13724        } else {
13725            if (adj > -10) pw.print(' ');
13726        }
13727        pw.print(adj);
13728        pw.print(": ");
13729        pw.print(name);
13730        pw.print(" (");
13731        pw.print(mProcessList.getMemLevel(adj)/1024);
13732        pw.println(" kB)");
13733    }
13734
13735    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13736            int opti, boolean dumpAll) {
13737        boolean needSep = false;
13738
13739        if (mLruProcesses.size() > 0) {
13740            if (needSep) pw.println();
13741            needSep = true;
13742            pw.println("  OOM levels:");
13743            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13744            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13745            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13746            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13747            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13748            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13749            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13750            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13751            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13752            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13753            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13754            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13755            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13756            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13757
13758            if (needSep) pw.println();
13759            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13760                    pw.print(" total, non-act at ");
13761                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13762                    pw.print(", non-svc at ");
13763                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13764                    pw.println("):");
13765            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13766            needSep = true;
13767        }
13768
13769        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13770
13771        pw.println();
13772        pw.println("  mHomeProcess: " + mHomeProcess);
13773        pw.println("  mPreviousProcess: " + mPreviousProcess);
13774        if (mHeavyWeightProcess != null) {
13775            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13776        }
13777
13778        return true;
13779    }
13780
13781    /**
13782     * There are three ways to call this:
13783     *  - no provider specified: dump all the providers
13784     *  - a flattened component name that matched an existing provider was specified as the
13785     *    first arg: dump that one provider
13786     *  - the first arg isn't the flattened component name of an existing provider:
13787     *    dump all providers whose component contains the first arg as a substring
13788     */
13789    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13790            int opti, boolean dumpAll) {
13791        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13792    }
13793
13794    static class ItemMatcher {
13795        ArrayList<ComponentName> components;
13796        ArrayList<String> strings;
13797        ArrayList<Integer> objects;
13798        boolean all;
13799
13800        ItemMatcher() {
13801            all = true;
13802        }
13803
13804        void build(String name) {
13805            ComponentName componentName = ComponentName.unflattenFromString(name);
13806            if (componentName != null) {
13807                if (components == null) {
13808                    components = new ArrayList<ComponentName>();
13809                }
13810                components.add(componentName);
13811                all = false;
13812            } else {
13813                int objectId = 0;
13814                // Not a '/' separated full component name; maybe an object ID?
13815                try {
13816                    objectId = Integer.parseInt(name, 16);
13817                    if (objects == null) {
13818                        objects = new ArrayList<Integer>();
13819                    }
13820                    objects.add(objectId);
13821                    all = false;
13822                } catch (RuntimeException e) {
13823                    // Not an integer; just do string match.
13824                    if (strings == null) {
13825                        strings = new ArrayList<String>();
13826                    }
13827                    strings.add(name);
13828                    all = false;
13829                }
13830            }
13831        }
13832
13833        int build(String[] args, int opti) {
13834            for (; opti<args.length; opti++) {
13835                String name = args[opti];
13836                if ("--".equals(name)) {
13837                    return opti+1;
13838                }
13839                build(name);
13840            }
13841            return opti;
13842        }
13843
13844        boolean match(Object object, ComponentName comp) {
13845            if (all) {
13846                return true;
13847            }
13848            if (components != null) {
13849                for (int i=0; i<components.size(); i++) {
13850                    if (components.get(i).equals(comp)) {
13851                        return true;
13852                    }
13853                }
13854            }
13855            if (objects != null) {
13856                for (int i=0; i<objects.size(); i++) {
13857                    if (System.identityHashCode(object) == objects.get(i)) {
13858                        return true;
13859                    }
13860                }
13861            }
13862            if (strings != null) {
13863                String flat = comp.flattenToString();
13864                for (int i=0; i<strings.size(); i++) {
13865                    if (flat.contains(strings.get(i))) {
13866                        return true;
13867                    }
13868                }
13869            }
13870            return false;
13871        }
13872    }
13873
13874    /**
13875     * There are three things that cmd can be:
13876     *  - a flattened component name that matches an existing activity
13877     *  - the cmd arg isn't the flattened component name of an existing activity:
13878     *    dump all activity whose component contains the cmd as a substring
13879     *  - A hex number of the ActivityRecord object instance.
13880     */
13881    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13882            int opti, boolean dumpAll) {
13883        ArrayList<ActivityRecord> activities;
13884
13885        synchronized (this) {
13886            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13887        }
13888
13889        if (activities.size() <= 0) {
13890            return false;
13891        }
13892
13893        String[] newArgs = new String[args.length - opti];
13894        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13895
13896        TaskRecord lastTask = null;
13897        boolean needSep = false;
13898        for (int i=activities.size()-1; i>=0; i--) {
13899            ActivityRecord r = activities.get(i);
13900            if (needSep) {
13901                pw.println();
13902            }
13903            needSep = true;
13904            synchronized (this) {
13905                if (lastTask != r.task) {
13906                    lastTask = r.task;
13907                    pw.print("TASK "); pw.print(lastTask.affinity);
13908                            pw.print(" id="); pw.println(lastTask.taskId);
13909                    if (dumpAll) {
13910                        lastTask.dump(pw, "  ");
13911                    }
13912                }
13913            }
13914            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13915        }
13916        return true;
13917    }
13918
13919    /**
13920     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13921     * there is a thread associated with the activity.
13922     */
13923    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13924            final ActivityRecord r, String[] args, boolean dumpAll) {
13925        String innerPrefix = prefix + "  ";
13926        synchronized (this) {
13927            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13928                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13929                    pw.print(" pid=");
13930                    if (r.app != null) pw.println(r.app.pid);
13931                    else pw.println("(not running)");
13932            if (dumpAll) {
13933                r.dump(pw, innerPrefix);
13934            }
13935        }
13936        if (r.app != null && r.app.thread != null) {
13937            // flush anything that is already in the PrintWriter since the thread is going
13938            // to write to the file descriptor directly
13939            pw.flush();
13940            try {
13941                TransferPipe tp = new TransferPipe();
13942                try {
13943                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13944                            r.appToken, innerPrefix, args);
13945                    tp.go(fd);
13946                } finally {
13947                    tp.kill();
13948                }
13949            } catch (IOException e) {
13950                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13951            } catch (RemoteException e) {
13952                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13953            }
13954        }
13955    }
13956
13957    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13958            int opti, boolean dumpAll, String dumpPackage) {
13959        boolean needSep = false;
13960        boolean onlyHistory = false;
13961        boolean printedAnything = false;
13962
13963        if ("history".equals(dumpPackage)) {
13964            if (opti < args.length && "-s".equals(args[opti])) {
13965                dumpAll = false;
13966            }
13967            onlyHistory = true;
13968            dumpPackage = null;
13969        }
13970
13971        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13972        if (!onlyHistory && dumpAll) {
13973            if (mRegisteredReceivers.size() > 0) {
13974                boolean printed = false;
13975                Iterator it = mRegisteredReceivers.values().iterator();
13976                while (it.hasNext()) {
13977                    ReceiverList r = (ReceiverList)it.next();
13978                    if (dumpPackage != null && (r.app == null ||
13979                            !dumpPackage.equals(r.app.info.packageName))) {
13980                        continue;
13981                    }
13982                    if (!printed) {
13983                        pw.println("  Registered Receivers:");
13984                        needSep = true;
13985                        printed = true;
13986                        printedAnything = true;
13987                    }
13988                    pw.print("  * "); pw.println(r);
13989                    r.dump(pw, "    ");
13990                }
13991            }
13992
13993            if (mReceiverResolver.dump(pw, needSep ?
13994                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13995                    "    ", dumpPackage, false, false)) {
13996                needSep = true;
13997                printedAnything = true;
13998            }
13999        }
14000
14001        for (BroadcastQueue q : mBroadcastQueues) {
14002            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14003            printedAnything |= needSep;
14004        }
14005
14006        needSep = true;
14007
14008        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14009            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14010                if (needSep) {
14011                    pw.println();
14012                }
14013                needSep = true;
14014                printedAnything = true;
14015                pw.print("  Sticky broadcasts for user ");
14016                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14017                StringBuilder sb = new StringBuilder(128);
14018                for (Map.Entry<String, ArrayList<Intent>> ent
14019                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14020                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14021                    if (dumpAll) {
14022                        pw.println(":");
14023                        ArrayList<Intent> intents = ent.getValue();
14024                        final int N = intents.size();
14025                        for (int i=0; i<N; i++) {
14026                            sb.setLength(0);
14027                            sb.append("    Intent: ");
14028                            intents.get(i).toShortString(sb, false, true, false, false);
14029                            pw.println(sb.toString());
14030                            Bundle bundle = intents.get(i).getExtras();
14031                            if (bundle != null) {
14032                                pw.print("      ");
14033                                pw.println(bundle.toString());
14034                            }
14035                        }
14036                    } else {
14037                        pw.println("");
14038                    }
14039                }
14040            }
14041        }
14042
14043        if (!onlyHistory && dumpAll) {
14044            pw.println();
14045            for (BroadcastQueue queue : mBroadcastQueues) {
14046                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14047                        + queue.mBroadcastsScheduled);
14048            }
14049            pw.println("  mHandler:");
14050            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14051            needSep = true;
14052            printedAnything = true;
14053        }
14054
14055        if (!printedAnything) {
14056            pw.println("  (nothing)");
14057        }
14058    }
14059
14060    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14061            int opti, boolean dumpAll, String dumpPackage) {
14062        boolean needSep;
14063        boolean printedAnything = false;
14064
14065        ItemMatcher matcher = new ItemMatcher();
14066        matcher.build(args, opti);
14067
14068        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14069
14070        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14071        printedAnything |= needSep;
14072
14073        if (mLaunchingProviders.size() > 0) {
14074            boolean printed = false;
14075            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14076                ContentProviderRecord r = mLaunchingProviders.get(i);
14077                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14078                    continue;
14079                }
14080                if (!printed) {
14081                    if (needSep) pw.println();
14082                    needSep = true;
14083                    pw.println("  Launching content providers:");
14084                    printed = true;
14085                    printedAnything = true;
14086                }
14087                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14088                        pw.println(r);
14089            }
14090        }
14091
14092        if (mGrantedUriPermissions.size() > 0) {
14093            boolean printed = false;
14094            int dumpUid = -2;
14095            if (dumpPackage != null) {
14096                try {
14097                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14098                } catch (NameNotFoundException e) {
14099                    dumpUid = -1;
14100                }
14101            }
14102            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14103                int uid = mGrantedUriPermissions.keyAt(i);
14104                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14105                    continue;
14106                }
14107                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14108                if (!printed) {
14109                    if (needSep) pw.println();
14110                    needSep = true;
14111                    pw.println("  Granted Uri Permissions:");
14112                    printed = true;
14113                    printedAnything = true;
14114                }
14115                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14116                for (UriPermission perm : perms.values()) {
14117                    pw.print("    "); pw.println(perm);
14118                    if (dumpAll) {
14119                        perm.dump(pw, "      ");
14120                    }
14121                }
14122            }
14123        }
14124
14125        if (!printedAnything) {
14126            pw.println("  (nothing)");
14127        }
14128    }
14129
14130    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14131            int opti, boolean dumpAll, String dumpPackage) {
14132        boolean printed = false;
14133
14134        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14135
14136        if (mIntentSenderRecords.size() > 0) {
14137            Iterator<WeakReference<PendingIntentRecord>> it
14138                    = mIntentSenderRecords.values().iterator();
14139            while (it.hasNext()) {
14140                WeakReference<PendingIntentRecord> ref = it.next();
14141                PendingIntentRecord rec = ref != null ? ref.get(): null;
14142                if (dumpPackage != null && (rec == null
14143                        || !dumpPackage.equals(rec.key.packageName))) {
14144                    continue;
14145                }
14146                printed = true;
14147                if (rec != null) {
14148                    pw.print("  * "); pw.println(rec);
14149                    if (dumpAll) {
14150                        rec.dump(pw, "    ");
14151                    }
14152                } else {
14153                    pw.print("  * "); pw.println(ref);
14154                }
14155            }
14156        }
14157
14158        if (!printed) {
14159            pw.println("  (nothing)");
14160        }
14161    }
14162
14163    private static final int dumpProcessList(PrintWriter pw,
14164            ActivityManagerService service, List list,
14165            String prefix, String normalLabel, String persistentLabel,
14166            String dumpPackage) {
14167        int numPers = 0;
14168        final int N = list.size()-1;
14169        for (int i=N; i>=0; i--) {
14170            ProcessRecord r = (ProcessRecord)list.get(i);
14171            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14172                continue;
14173            }
14174            pw.println(String.format("%s%s #%2d: %s",
14175                    prefix, (r.persistent ? persistentLabel : normalLabel),
14176                    i, r.toString()));
14177            if (r.persistent) {
14178                numPers++;
14179            }
14180        }
14181        return numPers;
14182    }
14183
14184    private static final boolean dumpProcessOomList(PrintWriter pw,
14185            ActivityManagerService service, List<ProcessRecord> origList,
14186            String prefix, String normalLabel, String persistentLabel,
14187            boolean inclDetails, String dumpPackage) {
14188
14189        ArrayList<Pair<ProcessRecord, Integer>> list
14190                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14191        for (int i=0; i<origList.size(); i++) {
14192            ProcessRecord r = origList.get(i);
14193            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14194                continue;
14195            }
14196            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14197        }
14198
14199        if (list.size() <= 0) {
14200            return false;
14201        }
14202
14203        Comparator<Pair<ProcessRecord, Integer>> comparator
14204                = new Comparator<Pair<ProcessRecord, Integer>>() {
14205            @Override
14206            public int compare(Pair<ProcessRecord, Integer> object1,
14207                    Pair<ProcessRecord, Integer> object2) {
14208                if (object1.first.setAdj != object2.first.setAdj) {
14209                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14210                }
14211                if (object1.second.intValue() != object2.second.intValue()) {
14212                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14213                }
14214                return 0;
14215            }
14216        };
14217
14218        Collections.sort(list, comparator);
14219
14220        final long curRealtime = SystemClock.elapsedRealtime();
14221        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14222        final long curUptime = SystemClock.uptimeMillis();
14223        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14224
14225        for (int i=list.size()-1; i>=0; i--) {
14226            ProcessRecord r = list.get(i).first;
14227            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14228            char schedGroup;
14229            switch (r.setSchedGroup) {
14230                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14231                    schedGroup = 'B';
14232                    break;
14233                case Process.THREAD_GROUP_DEFAULT:
14234                    schedGroup = 'F';
14235                    break;
14236                default:
14237                    schedGroup = '?';
14238                    break;
14239            }
14240            char foreground;
14241            if (r.foregroundActivities) {
14242                foreground = 'A';
14243            } else if (r.foregroundServices) {
14244                foreground = 'S';
14245            } else {
14246                foreground = ' ';
14247            }
14248            String procState = ProcessList.makeProcStateString(r.curProcState);
14249            pw.print(prefix);
14250            pw.print(r.persistent ? persistentLabel : normalLabel);
14251            pw.print(" #");
14252            int num = (origList.size()-1)-list.get(i).second;
14253            if (num < 10) pw.print(' ');
14254            pw.print(num);
14255            pw.print(": ");
14256            pw.print(oomAdj);
14257            pw.print(' ');
14258            pw.print(schedGroup);
14259            pw.print('/');
14260            pw.print(foreground);
14261            pw.print('/');
14262            pw.print(procState);
14263            pw.print(" trm:");
14264            if (r.trimMemoryLevel < 10) pw.print(' ');
14265            pw.print(r.trimMemoryLevel);
14266            pw.print(' ');
14267            pw.print(r.toShortString());
14268            pw.print(" (");
14269            pw.print(r.adjType);
14270            pw.println(')');
14271            if (r.adjSource != null || r.adjTarget != null) {
14272                pw.print(prefix);
14273                pw.print("    ");
14274                if (r.adjTarget instanceof ComponentName) {
14275                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14276                } else if (r.adjTarget != null) {
14277                    pw.print(r.adjTarget.toString());
14278                } else {
14279                    pw.print("{null}");
14280                }
14281                pw.print("<=");
14282                if (r.adjSource instanceof ProcessRecord) {
14283                    pw.print("Proc{");
14284                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14285                    pw.println("}");
14286                } else if (r.adjSource != null) {
14287                    pw.println(r.adjSource.toString());
14288                } else {
14289                    pw.println("{null}");
14290                }
14291            }
14292            if (inclDetails) {
14293                pw.print(prefix);
14294                pw.print("    ");
14295                pw.print("oom: max="); pw.print(r.maxAdj);
14296                pw.print(" curRaw="); pw.print(r.curRawAdj);
14297                pw.print(" setRaw="); pw.print(r.setRawAdj);
14298                pw.print(" cur="); pw.print(r.curAdj);
14299                pw.print(" set="); pw.println(r.setAdj);
14300                pw.print(prefix);
14301                pw.print("    ");
14302                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14303                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14304                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14305                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14306                pw.println();
14307                pw.print(prefix);
14308                pw.print("    ");
14309                pw.print("cached="); pw.print(r.cached);
14310                pw.print(" empty="); pw.print(r.empty);
14311                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14312
14313                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14314                    if (r.lastWakeTime != 0) {
14315                        long wtime;
14316                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14317                        synchronized (stats) {
14318                            wtime = stats.getProcessWakeTime(r.info.uid,
14319                                    r.pid, curRealtime);
14320                        }
14321                        long timeUsed = wtime - r.lastWakeTime;
14322                        pw.print(prefix);
14323                        pw.print("    ");
14324                        pw.print("keep awake over ");
14325                        TimeUtils.formatDuration(realtimeSince, pw);
14326                        pw.print(" used ");
14327                        TimeUtils.formatDuration(timeUsed, pw);
14328                        pw.print(" (");
14329                        pw.print((timeUsed*100)/realtimeSince);
14330                        pw.println("%)");
14331                    }
14332                    if (r.lastCpuTime != 0) {
14333                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14334                        pw.print(prefix);
14335                        pw.print("    ");
14336                        pw.print("run cpu over ");
14337                        TimeUtils.formatDuration(uptimeSince, pw);
14338                        pw.print(" used ");
14339                        TimeUtils.formatDuration(timeUsed, pw);
14340                        pw.print(" (");
14341                        pw.print((timeUsed*100)/uptimeSince);
14342                        pw.println("%)");
14343                    }
14344                }
14345            }
14346        }
14347        return true;
14348    }
14349
14350    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14351            String[] args) {
14352        ArrayList<ProcessRecord> procs;
14353        synchronized (this) {
14354            if (args != null && args.length > start
14355                    && args[start].charAt(0) != '-') {
14356                procs = new ArrayList<ProcessRecord>();
14357                int pid = -1;
14358                try {
14359                    pid = Integer.parseInt(args[start]);
14360                } catch (NumberFormatException e) {
14361                }
14362                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14363                    ProcessRecord proc = mLruProcesses.get(i);
14364                    if (proc.pid == pid) {
14365                        procs.add(proc);
14366                    } else if (allPkgs && proc.pkgList != null
14367                            && proc.pkgList.containsKey(args[start])) {
14368                        procs.add(proc);
14369                    } else if (proc.processName.equals(args[start])) {
14370                        procs.add(proc);
14371                    }
14372                }
14373                if (procs.size() <= 0) {
14374                    return null;
14375                }
14376            } else {
14377                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14378            }
14379        }
14380        return procs;
14381    }
14382
14383    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14384            PrintWriter pw, String[] args) {
14385        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14386        if (procs == null) {
14387            pw.println("No process found for: " + args[0]);
14388            return;
14389        }
14390
14391        long uptime = SystemClock.uptimeMillis();
14392        long realtime = SystemClock.elapsedRealtime();
14393        pw.println("Applications Graphics Acceleration Info:");
14394        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14395
14396        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14397            ProcessRecord r = procs.get(i);
14398            if (r.thread != null) {
14399                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14400                pw.flush();
14401                try {
14402                    TransferPipe tp = new TransferPipe();
14403                    try {
14404                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14405                        tp.go(fd);
14406                    } finally {
14407                        tp.kill();
14408                    }
14409                } catch (IOException e) {
14410                    pw.println("Failure while dumping the app: " + r);
14411                    pw.flush();
14412                } catch (RemoteException e) {
14413                    pw.println("Got a RemoteException while dumping the app " + r);
14414                    pw.flush();
14415                }
14416            }
14417        }
14418    }
14419
14420    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14421        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14422        if (procs == null) {
14423            pw.println("No process found for: " + args[0]);
14424            return;
14425        }
14426
14427        pw.println("Applications Database Info:");
14428
14429        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14430            ProcessRecord r = procs.get(i);
14431            if (r.thread != null) {
14432                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14433                pw.flush();
14434                try {
14435                    TransferPipe tp = new TransferPipe();
14436                    try {
14437                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14438                        tp.go(fd);
14439                    } finally {
14440                        tp.kill();
14441                    }
14442                } catch (IOException e) {
14443                    pw.println("Failure while dumping the app: " + r);
14444                    pw.flush();
14445                } catch (RemoteException e) {
14446                    pw.println("Got a RemoteException while dumping the app " + r);
14447                    pw.flush();
14448                }
14449            }
14450        }
14451    }
14452
14453    final static class MemItem {
14454        final boolean isProc;
14455        final String label;
14456        final String shortLabel;
14457        final long pss;
14458        final int id;
14459        final boolean hasActivities;
14460        ArrayList<MemItem> subitems;
14461
14462        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14463                boolean _hasActivities) {
14464            isProc = true;
14465            label = _label;
14466            shortLabel = _shortLabel;
14467            pss = _pss;
14468            id = _id;
14469            hasActivities = _hasActivities;
14470        }
14471
14472        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14473            isProc = false;
14474            label = _label;
14475            shortLabel = _shortLabel;
14476            pss = _pss;
14477            id = _id;
14478            hasActivities = false;
14479        }
14480    }
14481
14482    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14483            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14484        if (sort && !isCompact) {
14485            Collections.sort(items, new Comparator<MemItem>() {
14486                @Override
14487                public int compare(MemItem lhs, MemItem rhs) {
14488                    if (lhs.pss < rhs.pss) {
14489                        return 1;
14490                    } else if (lhs.pss > rhs.pss) {
14491                        return -1;
14492                    }
14493                    return 0;
14494                }
14495            });
14496        }
14497
14498        for (int i=0; i<items.size(); i++) {
14499            MemItem mi = items.get(i);
14500            if (!isCompact) {
14501                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14502            } else if (mi.isProc) {
14503                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14504                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14505                pw.println(mi.hasActivities ? ",a" : ",e");
14506            } else {
14507                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14508                pw.println(mi.pss);
14509            }
14510            if (mi.subitems != null) {
14511                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14512                        true, isCompact);
14513            }
14514        }
14515    }
14516
14517    // These are in KB.
14518    static final long[] DUMP_MEM_BUCKETS = new long[] {
14519        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14520        120*1024, 160*1024, 200*1024,
14521        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14522        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14523    };
14524
14525    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14526            boolean stackLike) {
14527        int start = label.lastIndexOf('.');
14528        if (start >= 0) start++;
14529        else start = 0;
14530        int end = label.length();
14531        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14532            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14533                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14534                out.append(bucket);
14535                out.append(stackLike ? "MB." : "MB ");
14536                out.append(label, start, end);
14537                return;
14538            }
14539        }
14540        out.append(memKB/1024);
14541        out.append(stackLike ? "MB." : "MB ");
14542        out.append(label, start, end);
14543    }
14544
14545    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14546            ProcessList.NATIVE_ADJ,
14547            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14548            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14549            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14550            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14551            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14552            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14553    };
14554    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14555            "Native",
14556            "System", "Persistent", "Persistent Service", "Foreground",
14557            "Visible", "Perceptible",
14558            "Heavy Weight", "Backup",
14559            "A Services", "Home",
14560            "Previous", "B Services", "Cached"
14561    };
14562    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14563            "native",
14564            "sys", "pers", "persvc", "fore",
14565            "vis", "percept",
14566            "heavy", "backup",
14567            "servicea", "home",
14568            "prev", "serviceb", "cached"
14569    };
14570
14571    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14572            long realtime, boolean isCheckinRequest, boolean isCompact) {
14573        if (isCheckinRequest || isCompact) {
14574            // short checkin version
14575            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14576        } else {
14577            pw.println("Applications Memory Usage (kB):");
14578            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14579        }
14580    }
14581
14582    private static final int KSM_SHARED = 0;
14583    private static final int KSM_SHARING = 1;
14584    private static final int KSM_UNSHARED = 2;
14585    private static final int KSM_VOLATILE = 3;
14586
14587    private final long[] getKsmInfo() {
14588        long[] longOut = new long[4];
14589        final int[] SINGLE_LONG_FORMAT = new int[] {
14590            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14591        };
14592        long[] longTmp = new long[1];
14593        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14594                SINGLE_LONG_FORMAT, null, longTmp, null);
14595        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14596        longTmp[0] = 0;
14597        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14598                SINGLE_LONG_FORMAT, null, longTmp, null);
14599        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14600        longTmp[0] = 0;
14601        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14602                SINGLE_LONG_FORMAT, null, longTmp, null);
14603        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14604        longTmp[0] = 0;
14605        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14606                SINGLE_LONG_FORMAT, null, longTmp, null);
14607        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14608        return longOut;
14609    }
14610
14611    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14612            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14613        boolean dumpDetails = false;
14614        boolean dumpFullDetails = false;
14615        boolean dumpDalvik = false;
14616        boolean dumpSummaryOnly = false;
14617        boolean oomOnly = false;
14618        boolean isCompact = false;
14619        boolean localOnly = false;
14620        boolean packages = false;
14621
14622        int opti = 0;
14623        while (opti < args.length) {
14624            String opt = args[opti];
14625            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14626                break;
14627            }
14628            opti++;
14629            if ("-a".equals(opt)) {
14630                dumpDetails = true;
14631                dumpFullDetails = true;
14632                dumpDalvik = true;
14633            } else if ("-d".equals(opt)) {
14634                dumpDalvik = true;
14635            } else if ("-c".equals(opt)) {
14636                isCompact = true;
14637            } else if ("-s".equals(opt)) {
14638                dumpDetails = true;
14639                dumpSummaryOnly = true;
14640            } else if ("--oom".equals(opt)) {
14641                oomOnly = true;
14642            } else if ("--local".equals(opt)) {
14643                localOnly = true;
14644            } else if ("--package".equals(opt)) {
14645                packages = true;
14646            } else if ("-h".equals(opt)) {
14647                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14648                pw.println("  -a: include all available information for each process.");
14649                pw.println("  -d: include dalvik details.");
14650                pw.println("  -c: dump in a compact machine-parseable representation.");
14651                pw.println("  -s: dump only summary of application memory usage.");
14652                pw.println("  --oom: only show processes organized by oom adj.");
14653                pw.println("  --local: only collect details locally, don't call process.");
14654                pw.println("  --package: interpret process arg as package, dumping all");
14655                pw.println("             processes that have loaded that package.");
14656                pw.println("If [process] is specified it can be the name or ");
14657                pw.println("pid of a specific process to dump.");
14658                return;
14659            } else {
14660                pw.println("Unknown argument: " + opt + "; use -h for help");
14661            }
14662        }
14663
14664        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14665        long uptime = SystemClock.uptimeMillis();
14666        long realtime = SystemClock.elapsedRealtime();
14667        final long[] tmpLong = new long[1];
14668
14669        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14670        if (procs == null) {
14671            // No Java processes.  Maybe they want to print a native process.
14672            if (args != null && args.length > opti
14673                    && args[opti].charAt(0) != '-') {
14674                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14675                        = new ArrayList<ProcessCpuTracker.Stats>();
14676                updateCpuStatsNow();
14677                int findPid = -1;
14678                try {
14679                    findPid = Integer.parseInt(args[opti]);
14680                } catch (NumberFormatException e) {
14681                }
14682                synchronized (mProcessCpuTracker) {
14683                    final int N = mProcessCpuTracker.countStats();
14684                    for (int i=0; i<N; i++) {
14685                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14686                        if (st.pid == findPid || (st.baseName != null
14687                                && st.baseName.equals(args[opti]))) {
14688                            nativeProcs.add(st);
14689                        }
14690                    }
14691                }
14692                if (nativeProcs.size() > 0) {
14693                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14694                            isCompact);
14695                    Debug.MemoryInfo mi = null;
14696                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14697                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14698                        final int pid = r.pid;
14699                        if (!isCheckinRequest && dumpDetails) {
14700                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14701                        }
14702                        if (mi == null) {
14703                            mi = new Debug.MemoryInfo();
14704                        }
14705                        if (dumpDetails || (!brief && !oomOnly)) {
14706                            Debug.getMemoryInfo(pid, mi);
14707                        } else {
14708                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14709                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14710                        }
14711                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14712                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14713                        if (isCheckinRequest) {
14714                            pw.println();
14715                        }
14716                    }
14717                    return;
14718                }
14719            }
14720            pw.println("No process found for: " + args[opti]);
14721            return;
14722        }
14723
14724        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14725            dumpDetails = true;
14726        }
14727
14728        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14729
14730        String[] innerArgs = new String[args.length-opti];
14731        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14732
14733        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14734        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14735        long nativePss = 0;
14736        long dalvikPss = 0;
14737        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14738                EmptyArray.LONG;
14739        long otherPss = 0;
14740        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14741
14742        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14743        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14744                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14745
14746        long totalPss = 0;
14747        long cachedPss = 0;
14748
14749        Debug.MemoryInfo mi = null;
14750        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14751            final ProcessRecord r = procs.get(i);
14752            final IApplicationThread thread;
14753            final int pid;
14754            final int oomAdj;
14755            final boolean hasActivities;
14756            synchronized (this) {
14757                thread = r.thread;
14758                pid = r.pid;
14759                oomAdj = r.getSetAdjWithServices();
14760                hasActivities = r.activities.size() > 0;
14761            }
14762            if (thread != null) {
14763                if (!isCheckinRequest && dumpDetails) {
14764                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14765                }
14766                if (mi == null) {
14767                    mi = new Debug.MemoryInfo();
14768                }
14769                if (dumpDetails || (!brief && !oomOnly)) {
14770                    Debug.getMemoryInfo(pid, mi);
14771                } else {
14772                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14773                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14774                }
14775                if (dumpDetails) {
14776                    if (localOnly) {
14777                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14778                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14779                        if (isCheckinRequest) {
14780                            pw.println();
14781                        }
14782                    } else {
14783                        try {
14784                            pw.flush();
14785                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14786                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14787                        } catch (RemoteException e) {
14788                            if (!isCheckinRequest) {
14789                                pw.println("Got RemoteException!");
14790                                pw.flush();
14791                            }
14792                        }
14793                    }
14794                }
14795
14796                final long myTotalPss = mi.getTotalPss();
14797                final long myTotalUss = mi.getTotalUss();
14798
14799                synchronized (this) {
14800                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14801                        // Record this for posterity if the process has been stable.
14802                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14803                    }
14804                }
14805
14806                if (!isCheckinRequest && mi != null) {
14807                    totalPss += myTotalPss;
14808                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14809                            (hasActivities ? " / activities)" : ")"),
14810                            r.processName, myTotalPss, pid, hasActivities);
14811                    procMems.add(pssItem);
14812                    procMemsMap.put(pid, pssItem);
14813
14814                    nativePss += mi.nativePss;
14815                    dalvikPss += mi.dalvikPss;
14816                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14817                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14818                    }
14819                    otherPss += mi.otherPss;
14820                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14821                        long mem = mi.getOtherPss(j);
14822                        miscPss[j] += mem;
14823                        otherPss -= mem;
14824                    }
14825
14826                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14827                        cachedPss += myTotalPss;
14828                    }
14829
14830                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14831                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14832                                || oomIndex == (oomPss.length-1)) {
14833                            oomPss[oomIndex] += myTotalPss;
14834                            if (oomProcs[oomIndex] == null) {
14835                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14836                            }
14837                            oomProcs[oomIndex].add(pssItem);
14838                            break;
14839                        }
14840                    }
14841                }
14842            }
14843        }
14844
14845        long nativeProcTotalPss = 0;
14846
14847        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14848            // If we are showing aggregations, also look for native processes to
14849            // include so that our aggregations are more accurate.
14850            updateCpuStatsNow();
14851            mi = null;
14852            synchronized (mProcessCpuTracker) {
14853                final int N = mProcessCpuTracker.countStats();
14854                for (int i=0; i<N; i++) {
14855                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14856                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14857                        if (mi == null) {
14858                            mi = new Debug.MemoryInfo();
14859                        }
14860                        if (!brief && !oomOnly) {
14861                            Debug.getMemoryInfo(st.pid, mi);
14862                        } else {
14863                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14864                            mi.nativePrivateDirty = (int)tmpLong[0];
14865                        }
14866
14867                        final long myTotalPss = mi.getTotalPss();
14868                        totalPss += myTotalPss;
14869                        nativeProcTotalPss += myTotalPss;
14870
14871                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14872                                st.name, myTotalPss, st.pid, false);
14873                        procMems.add(pssItem);
14874
14875                        nativePss += mi.nativePss;
14876                        dalvikPss += mi.dalvikPss;
14877                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14878                            dalvikSubitemPss[j] += mi.getOtherPss(
14879                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14880                        }
14881                        otherPss += mi.otherPss;
14882                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14883                            long mem = mi.getOtherPss(j);
14884                            miscPss[j] += mem;
14885                            otherPss -= mem;
14886                        }
14887                        oomPss[0] += myTotalPss;
14888                        if (oomProcs[0] == null) {
14889                            oomProcs[0] = new ArrayList<MemItem>();
14890                        }
14891                        oomProcs[0].add(pssItem);
14892                    }
14893                }
14894            }
14895
14896            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14897
14898            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14899            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14900            if (dalvikSubitemPss.length > 0) {
14901                dalvikItem.subitems = new ArrayList<MemItem>();
14902                for (int j=0; j<dalvikSubitemPss.length; j++) {
14903                    final String name = Debug.MemoryInfo.getOtherLabel(
14904                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14905                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14906                }
14907            }
14908            catMems.add(dalvikItem);
14909            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14910            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14911                String label = Debug.MemoryInfo.getOtherLabel(j);
14912                catMems.add(new MemItem(label, label, miscPss[j], j));
14913            }
14914
14915            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14916            for (int j=0; j<oomPss.length; j++) {
14917                if (oomPss[j] != 0) {
14918                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14919                            : DUMP_MEM_OOM_LABEL[j];
14920                    MemItem item = new MemItem(label, label, oomPss[j],
14921                            DUMP_MEM_OOM_ADJ[j]);
14922                    item.subitems = oomProcs[j];
14923                    oomMems.add(item);
14924                }
14925            }
14926
14927            if (!brief && !oomOnly && !isCompact) {
14928                pw.println();
14929                pw.println("Total PSS by process:");
14930                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14931                pw.println();
14932            }
14933            if (!isCompact) {
14934                pw.println("Total PSS by OOM adjustment:");
14935            }
14936            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14937            if (!brief && !oomOnly) {
14938                PrintWriter out = categoryPw != null ? categoryPw : pw;
14939                if (!isCompact) {
14940                    out.println();
14941                    out.println("Total PSS by category:");
14942                }
14943                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14944            }
14945            if (!isCompact) {
14946                pw.println();
14947            }
14948            MemInfoReader memInfo = new MemInfoReader();
14949            memInfo.readMemInfo();
14950            if (nativeProcTotalPss > 0) {
14951                synchronized (this) {
14952                    final long cachedKb = memInfo.getCachedSizeKb();
14953                    final long freeKb = memInfo.getFreeSizeKb();
14954                    final long zramKb = memInfo.getZramTotalSizeKb();
14955                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14956                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14957                            kernelKb*1024, nativeProcTotalPss*1024);
14958                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14959                            nativeProcTotalPss);
14960                }
14961            }
14962            if (!brief) {
14963                if (!isCompact) {
14964                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14965                    pw.print(" kB (status ");
14966                    switch (mLastMemoryLevel) {
14967                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14968                            pw.println("normal)");
14969                            break;
14970                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14971                            pw.println("moderate)");
14972                            break;
14973                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14974                            pw.println("low)");
14975                            break;
14976                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14977                            pw.println("critical)");
14978                            break;
14979                        default:
14980                            pw.print(mLastMemoryLevel);
14981                            pw.println(")");
14982                            break;
14983                    }
14984                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14985                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14986                            pw.print(cachedPss); pw.print(" cached pss + ");
14987                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14988                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14989                } else {
14990                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14991                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14992                            + memInfo.getFreeSizeKb()); pw.print(",");
14993                    pw.println(totalPss - cachedPss);
14994                }
14995            }
14996            if (!isCompact) {
14997                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14998                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14999                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15000                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15001                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15002                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15003                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15004            }
15005            if (!brief) {
15006                if (memInfo.getZramTotalSizeKb() != 0) {
15007                    if (!isCompact) {
15008                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15009                                pw.print(" kB physical used for ");
15010                                pw.print(memInfo.getSwapTotalSizeKb()
15011                                        - memInfo.getSwapFreeSizeKb());
15012                                pw.print(" kB in swap (");
15013                                pw.print(memInfo.getSwapTotalSizeKb());
15014                                pw.println(" kB total swap)");
15015                    } else {
15016                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15017                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15018                                pw.println(memInfo.getSwapFreeSizeKb());
15019                    }
15020                }
15021                final long[] ksm = getKsmInfo();
15022                if (!isCompact) {
15023                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15024                            || ksm[KSM_VOLATILE] != 0) {
15025                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15026                                pw.print(" kB saved from shared ");
15027                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15028                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15029                                pw.print(" kB unshared; ");
15030                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15031                    }
15032                    pw.print("   Tuning: ");
15033                    pw.print(ActivityManager.staticGetMemoryClass());
15034                    pw.print(" (large ");
15035                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15036                    pw.print("), oom ");
15037                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15038                    pw.print(" kB");
15039                    pw.print(", restore limit ");
15040                    pw.print(mProcessList.getCachedRestoreThresholdKb());
15041                    pw.print(" kB");
15042                    if (ActivityManager.isLowRamDeviceStatic()) {
15043                        pw.print(" (low-ram)");
15044                    }
15045                    if (ActivityManager.isHighEndGfx()) {
15046                        pw.print(" (high-end-gfx)");
15047                    }
15048                    pw.println();
15049                } else {
15050                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15051                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15052                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15053                    pw.print("tuning,");
15054                    pw.print(ActivityManager.staticGetMemoryClass());
15055                    pw.print(',');
15056                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15057                    pw.print(',');
15058                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15059                    if (ActivityManager.isLowRamDeviceStatic()) {
15060                        pw.print(",low-ram");
15061                    }
15062                    if (ActivityManager.isHighEndGfx()) {
15063                        pw.print(",high-end-gfx");
15064                    }
15065                    pw.println();
15066                }
15067            }
15068        }
15069    }
15070
15071    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15072            long memtrack, String name) {
15073        sb.append("  ");
15074        sb.append(ProcessList.makeOomAdjString(oomAdj));
15075        sb.append(' ');
15076        sb.append(ProcessList.makeProcStateString(procState));
15077        sb.append(' ');
15078        ProcessList.appendRamKb(sb, pss);
15079        sb.append(" kB: ");
15080        sb.append(name);
15081        if (memtrack > 0) {
15082            sb.append(" (");
15083            sb.append(memtrack);
15084            sb.append(" kB memtrack)");
15085        }
15086    }
15087
15088    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15089        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15090        sb.append(" (pid ");
15091        sb.append(mi.pid);
15092        sb.append(") ");
15093        sb.append(mi.adjType);
15094        sb.append('\n');
15095        if (mi.adjReason != null) {
15096            sb.append("                      ");
15097            sb.append(mi.adjReason);
15098            sb.append('\n');
15099        }
15100    }
15101
15102    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15103        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15104        for (int i=0, N=memInfos.size(); i<N; i++) {
15105            ProcessMemInfo mi = memInfos.get(i);
15106            infoMap.put(mi.pid, mi);
15107        }
15108        updateCpuStatsNow();
15109        long[] memtrackTmp = new long[1];
15110        synchronized (mProcessCpuTracker) {
15111            final int N = mProcessCpuTracker.countStats();
15112            for (int i=0; i<N; i++) {
15113                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15114                if (st.vsize > 0) {
15115                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15116                    if (pss > 0) {
15117                        if (infoMap.indexOfKey(st.pid) < 0) {
15118                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15119                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15120                            mi.pss = pss;
15121                            mi.memtrack = memtrackTmp[0];
15122                            memInfos.add(mi);
15123                        }
15124                    }
15125                }
15126            }
15127        }
15128
15129        long totalPss = 0;
15130        long totalMemtrack = 0;
15131        for (int i=0, N=memInfos.size(); i<N; i++) {
15132            ProcessMemInfo mi = memInfos.get(i);
15133            if (mi.pss == 0) {
15134                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15135                mi.memtrack = memtrackTmp[0];
15136            }
15137            totalPss += mi.pss;
15138            totalMemtrack += mi.memtrack;
15139        }
15140        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15141            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15142                if (lhs.oomAdj != rhs.oomAdj) {
15143                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15144                }
15145                if (lhs.pss != rhs.pss) {
15146                    return lhs.pss < rhs.pss ? 1 : -1;
15147                }
15148                return 0;
15149            }
15150        });
15151
15152        StringBuilder tag = new StringBuilder(128);
15153        StringBuilder stack = new StringBuilder(128);
15154        tag.append("Low on memory -- ");
15155        appendMemBucket(tag, totalPss, "total", false);
15156        appendMemBucket(stack, totalPss, "total", true);
15157
15158        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15159        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15160        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15161
15162        boolean firstLine = true;
15163        int lastOomAdj = Integer.MIN_VALUE;
15164        long extraNativeRam = 0;
15165        long extraNativeMemtrack = 0;
15166        long cachedPss = 0;
15167        for (int i=0, N=memInfos.size(); i<N; i++) {
15168            ProcessMemInfo mi = memInfos.get(i);
15169
15170            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15171                cachedPss += mi.pss;
15172            }
15173
15174            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15175                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15176                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15177                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15178                if (lastOomAdj != mi.oomAdj) {
15179                    lastOomAdj = mi.oomAdj;
15180                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15181                        tag.append(" / ");
15182                    }
15183                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15184                        if (firstLine) {
15185                            stack.append(":");
15186                            firstLine = false;
15187                        }
15188                        stack.append("\n\t at ");
15189                    } else {
15190                        stack.append("$");
15191                    }
15192                } else {
15193                    tag.append(" ");
15194                    stack.append("$");
15195                }
15196                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15197                    appendMemBucket(tag, mi.pss, mi.name, false);
15198                }
15199                appendMemBucket(stack, mi.pss, mi.name, true);
15200                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15201                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15202                    stack.append("(");
15203                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15204                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15205                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15206                            stack.append(":");
15207                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15208                        }
15209                    }
15210                    stack.append(")");
15211                }
15212            }
15213
15214            appendMemInfo(fullNativeBuilder, mi);
15215            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15216                // The short form only has native processes that are >= 512K.
15217                if (mi.pss >= 512) {
15218                    appendMemInfo(shortNativeBuilder, mi);
15219                } else {
15220                    extraNativeRam += mi.pss;
15221                    extraNativeMemtrack += mi.memtrack;
15222                }
15223            } else {
15224                // Short form has all other details, but if we have collected RAM
15225                // from smaller native processes let's dump a summary of that.
15226                if (extraNativeRam > 0) {
15227                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15228                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15229                    shortNativeBuilder.append('\n');
15230                    extraNativeRam = 0;
15231                }
15232                appendMemInfo(fullJavaBuilder, mi);
15233            }
15234        }
15235
15236        fullJavaBuilder.append("           ");
15237        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15238        fullJavaBuilder.append(" kB: TOTAL");
15239        if (totalMemtrack > 0) {
15240            fullJavaBuilder.append(" (");
15241            fullJavaBuilder.append(totalMemtrack);
15242            fullJavaBuilder.append(" kB memtrack)");
15243        } else {
15244        }
15245        fullJavaBuilder.append("\n");
15246
15247        MemInfoReader memInfo = new MemInfoReader();
15248        memInfo.readMemInfo();
15249        final long[] infos = memInfo.getRawInfo();
15250
15251        StringBuilder memInfoBuilder = new StringBuilder(1024);
15252        Debug.getMemInfo(infos);
15253        memInfoBuilder.append("  MemInfo: ");
15254        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15255        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15256        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15257        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15258        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15259        memInfoBuilder.append("           ");
15260        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15261        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15262        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15263        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15264        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15265            memInfoBuilder.append("  ZRAM: ");
15266            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15267            memInfoBuilder.append(" kB RAM, ");
15268            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15269            memInfoBuilder.append(" kB swap total, ");
15270            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15271            memInfoBuilder.append(" kB swap free\n");
15272        }
15273        final long[] ksm = getKsmInfo();
15274        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15275                || ksm[KSM_VOLATILE] != 0) {
15276            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15277            memInfoBuilder.append(" kB saved from shared ");
15278            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15279            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15280            memInfoBuilder.append(" kB unshared; ");
15281            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15282        }
15283        memInfoBuilder.append("  Free RAM: ");
15284        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15285                + memInfo.getFreeSizeKb());
15286        memInfoBuilder.append(" kB\n");
15287        memInfoBuilder.append("  Used RAM: ");
15288        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15289        memInfoBuilder.append(" kB\n");
15290        memInfoBuilder.append("  Lost RAM: ");
15291        memInfoBuilder.append(memInfo.getTotalSizeKb()
15292                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15293                - memInfo.getKernelUsedSizeKb());
15294        memInfoBuilder.append(" kB\n");
15295        Slog.i(TAG, "Low on memory:");
15296        Slog.i(TAG, shortNativeBuilder.toString());
15297        Slog.i(TAG, fullJavaBuilder.toString());
15298        Slog.i(TAG, memInfoBuilder.toString());
15299
15300        StringBuilder dropBuilder = new StringBuilder(1024);
15301        /*
15302        StringWriter oomSw = new StringWriter();
15303        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15304        StringWriter catSw = new StringWriter();
15305        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15306        String[] emptyArgs = new String[] { };
15307        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15308        oomPw.flush();
15309        String oomString = oomSw.toString();
15310        */
15311        dropBuilder.append("Low on memory:");
15312        dropBuilder.append(stack);
15313        dropBuilder.append('\n');
15314        dropBuilder.append(fullNativeBuilder);
15315        dropBuilder.append(fullJavaBuilder);
15316        dropBuilder.append('\n');
15317        dropBuilder.append(memInfoBuilder);
15318        dropBuilder.append('\n');
15319        /*
15320        dropBuilder.append(oomString);
15321        dropBuilder.append('\n');
15322        */
15323        StringWriter catSw = new StringWriter();
15324        synchronized (ActivityManagerService.this) {
15325            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15326            String[] emptyArgs = new String[] { };
15327            catPw.println();
15328            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15329            catPw.println();
15330            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15331                    false, false, null);
15332            catPw.println();
15333            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15334            catPw.flush();
15335        }
15336        dropBuilder.append(catSw.toString());
15337        addErrorToDropBox("lowmem", null, "system_server", null,
15338                null, tag.toString(), dropBuilder.toString(), null, null);
15339        //Slog.i(TAG, "Sent to dropbox:");
15340        //Slog.i(TAG, dropBuilder.toString());
15341        synchronized (ActivityManagerService.this) {
15342            long now = SystemClock.uptimeMillis();
15343            if (mLastMemUsageReportTime < now) {
15344                mLastMemUsageReportTime = now;
15345            }
15346        }
15347    }
15348
15349    /**
15350     * Searches array of arguments for the specified string
15351     * @param args array of argument strings
15352     * @param value value to search for
15353     * @return true if the value is contained in the array
15354     */
15355    private static boolean scanArgs(String[] args, String value) {
15356        if (args != null) {
15357            for (String arg : args) {
15358                if (value.equals(arg)) {
15359                    return true;
15360                }
15361            }
15362        }
15363        return false;
15364    }
15365
15366    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15367            ContentProviderRecord cpr, boolean always) {
15368        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15369
15370        if (!inLaunching || always) {
15371            synchronized (cpr) {
15372                cpr.launchingApp = null;
15373                cpr.notifyAll();
15374            }
15375            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15376            String names[] = cpr.info.authority.split(";");
15377            for (int j = 0; j < names.length; j++) {
15378                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15379            }
15380        }
15381
15382        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15383            ContentProviderConnection conn = cpr.connections.get(i);
15384            if (conn.waiting) {
15385                // If this connection is waiting for the provider, then we don't
15386                // need to mess with its process unless we are always removing
15387                // or for some reason the provider is not currently launching.
15388                if (inLaunching && !always) {
15389                    continue;
15390                }
15391            }
15392            ProcessRecord capp = conn.client;
15393            conn.dead = true;
15394            if (conn.stableCount > 0) {
15395                if (!capp.persistent && capp.thread != null
15396                        && capp.pid != 0
15397                        && capp.pid != MY_PID) {
15398                    capp.kill("depends on provider "
15399                            + cpr.name.flattenToShortString()
15400                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15401                }
15402            } else if (capp.thread != null && conn.provider.provider != null) {
15403                try {
15404                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15405                } catch (RemoteException e) {
15406                }
15407                // In the protocol here, we don't expect the client to correctly
15408                // clean up this connection, we'll just remove it.
15409                cpr.connections.remove(i);
15410                if (conn.client.conProviders.remove(conn)) {
15411                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15412                }
15413            }
15414        }
15415
15416        if (inLaunching && always) {
15417            mLaunchingProviders.remove(cpr);
15418        }
15419        return inLaunching;
15420    }
15421
15422    /**
15423     * Main code for cleaning up a process when it has gone away.  This is
15424     * called both as a result of the process dying, or directly when stopping
15425     * a process when running in single process mode.
15426     *
15427     * @return Returns true if the given process has been restarted, so the
15428     * app that was passed in must remain on the process lists.
15429     */
15430    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15431            boolean restarting, boolean allowRestart, int index) {
15432        if (index >= 0) {
15433            removeLruProcessLocked(app);
15434            ProcessList.remove(app.pid);
15435        }
15436
15437        mProcessesToGc.remove(app);
15438        mPendingPssProcesses.remove(app);
15439
15440        // Dismiss any open dialogs.
15441        if (app.crashDialog != null && !app.forceCrashReport) {
15442            app.crashDialog.dismiss();
15443            app.crashDialog = null;
15444        }
15445        if (app.anrDialog != null) {
15446            app.anrDialog.dismiss();
15447            app.anrDialog = null;
15448        }
15449        if (app.waitDialog != null) {
15450            app.waitDialog.dismiss();
15451            app.waitDialog = null;
15452        }
15453
15454        app.crashing = false;
15455        app.notResponding = false;
15456
15457        app.resetPackageList(mProcessStats);
15458        app.unlinkDeathRecipient();
15459        app.makeInactive(mProcessStats);
15460        app.waitingToKill = null;
15461        app.forcingToForeground = null;
15462        updateProcessForegroundLocked(app, false, false);
15463        app.foregroundActivities = false;
15464        app.hasShownUi = false;
15465        app.treatLikeActivity = false;
15466        app.hasAboveClient = false;
15467        app.hasClientActivities = false;
15468
15469        mServices.killServicesLocked(app, allowRestart);
15470
15471        boolean restart = false;
15472
15473        // Remove published content providers.
15474        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15475            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15476            final boolean always = app.bad || !allowRestart;
15477            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15478            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15479                // We left the provider in the launching list, need to
15480                // restart it.
15481                restart = true;
15482            }
15483
15484            cpr.provider = null;
15485            cpr.proc = null;
15486        }
15487        app.pubProviders.clear();
15488
15489        // Take care of any launching providers waiting for this process.
15490        if (checkAppInLaunchingProvidersLocked(app, false)) {
15491            restart = true;
15492        }
15493
15494        // Unregister from connected content providers.
15495        if (!app.conProviders.isEmpty()) {
15496            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15497                ContentProviderConnection conn = app.conProviders.get(i);
15498                conn.provider.connections.remove(conn);
15499                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15500                        conn.provider.name);
15501            }
15502            app.conProviders.clear();
15503        }
15504
15505        // At this point there may be remaining entries in mLaunchingProviders
15506        // where we were the only one waiting, so they are no longer of use.
15507        // Look for these and clean up if found.
15508        // XXX Commented out for now.  Trying to figure out a way to reproduce
15509        // the actual situation to identify what is actually going on.
15510        if (false) {
15511            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15512                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15513                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15514                    synchronized (cpr) {
15515                        cpr.launchingApp = null;
15516                        cpr.notifyAll();
15517                    }
15518                }
15519            }
15520        }
15521
15522        skipCurrentReceiverLocked(app);
15523
15524        // Unregister any receivers.
15525        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15526            removeReceiverLocked(app.receivers.valueAt(i));
15527        }
15528        app.receivers.clear();
15529
15530        // If the app is undergoing backup, tell the backup manager about it
15531        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15532            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15533                    + mBackupTarget.appInfo + " died during backup");
15534            try {
15535                IBackupManager bm = IBackupManager.Stub.asInterface(
15536                        ServiceManager.getService(Context.BACKUP_SERVICE));
15537                bm.agentDisconnected(app.info.packageName);
15538            } catch (RemoteException e) {
15539                // can't happen; backup manager is local
15540            }
15541        }
15542
15543        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15544            ProcessChangeItem item = mPendingProcessChanges.get(i);
15545            if (item.pid == app.pid) {
15546                mPendingProcessChanges.remove(i);
15547                mAvailProcessChanges.add(item);
15548            }
15549        }
15550        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15551
15552        // If the caller is restarting this app, then leave it in its
15553        // current lists and let the caller take care of it.
15554        if (restarting) {
15555            return false;
15556        }
15557
15558        if (!app.persistent || app.isolated) {
15559            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15560                    "Removing non-persistent process during cleanup: " + app);
15561            removeProcessNameLocked(app.processName, app.uid);
15562            if (mHeavyWeightProcess == app) {
15563                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15564                        mHeavyWeightProcess.userId, 0));
15565                mHeavyWeightProcess = null;
15566            }
15567        } else if (!app.removed) {
15568            // This app is persistent, so we need to keep its record around.
15569            // If it is not already on the pending app list, add it there
15570            // and start a new process for it.
15571            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15572                mPersistentStartingProcesses.add(app);
15573                restart = true;
15574            }
15575        }
15576        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15577                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15578        mProcessesOnHold.remove(app);
15579
15580        if (app == mHomeProcess) {
15581            mHomeProcess = null;
15582        }
15583        if (app == mPreviousProcess) {
15584            mPreviousProcess = null;
15585        }
15586
15587        if (restart && !app.isolated) {
15588            // We have components that still need to be running in the
15589            // process, so re-launch it.
15590            if (index < 0) {
15591                ProcessList.remove(app.pid);
15592            }
15593            addProcessNameLocked(app);
15594            startProcessLocked(app, "restart", app.processName);
15595            return true;
15596        } else if (app.pid > 0 && app.pid != MY_PID) {
15597            // Goodbye!
15598            boolean removed;
15599            synchronized (mPidsSelfLocked) {
15600                mPidsSelfLocked.remove(app.pid);
15601                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15602            }
15603            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15604            if (app.isolated) {
15605                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15606            }
15607            app.setPid(0);
15608        }
15609        return false;
15610    }
15611
15612    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15613        // Look through the content providers we are waiting to have launched,
15614        // and if any run in this process then either schedule a restart of
15615        // the process or kill the client waiting for it if this process has
15616        // gone bad.
15617        boolean restart = false;
15618        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15619            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15620            if (cpr.launchingApp == app) {
15621                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15622                    restart = true;
15623                } else {
15624                    removeDyingProviderLocked(app, cpr, true);
15625                }
15626            }
15627        }
15628        return restart;
15629    }
15630
15631    // =========================================================
15632    // SERVICES
15633    // =========================================================
15634
15635    @Override
15636    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15637            int flags) {
15638        enforceNotIsolatedCaller("getServices");
15639        synchronized (this) {
15640            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15641        }
15642    }
15643
15644    @Override
15645    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15646        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15647        synchronized (this) {
15648            return mServices.getRunningServiceControlPanelLocked(name);
15649        }
15650    }
15651
15652    @Override
15653    public ComponentName startService(IApplicationThread caller, Intent service,
15654            String resolvedType, String callingPackage, int userId)
15655            throws TransactionTooLargeException {
15656        enforceNotIsolatedCaller("startService");
15657        // Refuse possible leaked file descriptors
15658        if (service != null && service.hasFileDescriptors() == true) {
15659            throw new IllegalArgumentException("File descriptors passed in Intent");
15660        }
15661
15662        if (callingPackage == null) {
15663            throw new IllegalArgumentException("callingPackage cannot be null");
15664        }
15665
15666        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15667                "startService: " + service + " type=" + resolvedType);
15668        synchronized(this) {
15669            final int callingPid = Binder.getCallingPid();
15670            final int callingUid = Binder.getCallingUid();
15671            final long origId = Binder.clearCallingIdentity();
15672            ComponentName res = mServices.startServiceLocked(caller, service,
15673                    resolvedType, callingPid, callingUid, callingPackage, userId);
15674            Binder.restoreCallingIdentity(origId);
15675            return res;
15676        }
15677    }
15678
15679    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15680            String callingPackage, int userId)
15681            throws TransactionTooLargeException {
15682        synchronized(this) {
15683            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15684                    "startServiceInPackage: " + service + " type=" + resolvedType);
15685            final long origId = Binder.clearCallingIdentity();
15686            ComponentName res = mServices.startServiceLocked(null, service,
15687                    resolvedType, -1, uid, callingPackage, userId);
15688            Binder.restoreCallingIdentity(origId);
15689            return res;
15690        }
15691    }
15692
15693    @Override
15694    public int stopService(IApplicationThread caller, Intent service,
15695            String resolvedType, int userId) {
15696        enforceNotIsolatedCaller("stopService");
15697        // Refuse possible leaked file descriptors
15698        if (service != null && service.hasFileDescriptors() == true) {
15699            throw new IllegalArgumentException("File descriptors passed in Intent");
15700        }
15701
15702        synchronized(this) {
15703            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15704        }
15705    }
15706
15707    @Override
15708    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15709        enforceNotIsolatedCaller("peekService");
15710        // Refuse possible leaked file descriptors
15711        if (service != null && service.hasFileDescriptors() == true) {
15712            throw new IllegalArgumentException("File descriptors passed in Intent");
15713        }
15714
15715        if (callingPackage == null) {
15716            throw new IllegalArgumentException("callingPackage cannot be null");
15717        }
15718
15719        synchronized(this) {
15720            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15721        }
15722    }
15723
15724    @Override
15725    public boolean stopServiceToken(ComponentName className, IBinder token,
15726            int startId) {
15727        synchronized(this) {
15728            return mServices.stopServiceTokenLocked(className, token, startId);
15729        }
15730    }
15731
15732    @Override
15733    public void setServiceForeground(ComponentName className, IBinder token,
15734            int id, Notification notification, boolean removeNotification) {
15735        synchronized(this) {
15736            mServices.setServiceForegroundLocked(className, token, id, notification,
15737                    removeNotification);
15738        }
15739    }
15740
15741    @Override
15742    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15743            boolean requireFull, String name, String callerPackage) {
15744        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15745                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15746    }
15747
15748    int unsafeConvertIncomingUser(int userId) {
15749        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15750                ? mCurrentUserId : userId;
15751    }
15752
15753    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15754            int allowMode, String name, String callerPackage) {
15755        final int callingUserId = UserHandle.getUserId(callingUid);
15756        if (callingUserId == userId) {
15757            return userId;
15758        }
15759
15760        // Note that we may be accessing mCurrentUserId outside of a lock...
15761        // shouldn't be a big deal, if this is being called outside
15762        // of a locked context there is intrinsically a race with
15763        // the value the caller will receive and someone else changing it.
15764        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15765        // we will switch to the calling user if access to the current user fails.
15766        int targetUserId = unsafeConvertIncomingUser(userId);
15767
15768        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15769            final boolean allow;
15770            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15771                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15772                // If the caller has this permission, they always pass go.  And collect $200.
15773                allow = true;
15774            } else if (allowMode == ALLOW_FULL_ONLY) {
15775                // We require full access, sucks to be you.
15776                allow = false;
15777            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15778                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15779                // If the caller does not have either permission, they are always doomed.
15780                allow = false;
15781            } else if (allowMode == ALLOW_NON_FULL) {
15782                // We are blanket allowing non-full access, you lucky caller!
15783                allow = true;
15784            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15785                // We may or may not allow this depending on whether the two users are
15786                // in the same profile.
15787                synchronized (mUserProfileGroupIdsSelfLocked) {
15788                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15789                            UserInfo.NO_PROFILE_GROUP_ID);
15790                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15791                            UserInfo.NO_PROFILE_GROUP_ID);
15792                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15793                            && callingProfile == targetProfile;
15794                }
15795            } else {
15796                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15797            }
15798            if (!allow) {
15799                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15800                    // In this case, they would like to just execute as their
15801                    // owner user instead of failing.
15802                    targetUserId = callingUserId;
15803                } else {
15804                    StringBuilder builder = new StringBuilder(128);
15805                    builder.append("Permission Denial: ");
15806                    builder.append(name);
15807                    if (callerPackage != null) {
15808                        builder.append(" from ");
15809                        builder.append(callerPackage);
15810                    }
15811                    builder.append(" asks to run as user ");
15812                    builder.append(userId);
15813                    builder.append(" but is calling from user ");
15814                    builder.append(UserHandle.getUserId(callingUid));
15815                    builder.append("; this requires ");
15816                    builder.append(INTERACT_ACROSS_USERS_FULL);
15817                    if (allowMode != ALLOW_FULL_ONLY) {
15818                        builder.append(" or ");
15819                        builder.append(INTERACT_ACROSS_USERS);
15820                    }
15821                    String msg = builder.toString();
15822                    Slog.w(TAG, msg);
15823                    throw new SecurityException(msg);
15824                }
15825            }
15826        }
15827        if (!allowAll && targetUserId < 0) {
15828            throw new IllegalArgumentException(
15829                    "Call does not support special user #" + targetUserId);
15830        }
15831        // Check shell permission
15832        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15833            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15834                    targetUserId)) {
15835                throw new SecurityException("Shell does not have permission to access user "
15836                        + targetUserId + "\n " + Debug.getCallers(3));
15837            }
15838        }
15839        return targetUserId;
15840    }
15841
15842    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15843            String className, int flags) {
15844        boolean result = false;
15845        // For apps that don't have pre-defined UIDs, check for permission
15846        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15847            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15848                if (ActivityManager.checkUidPermission(
15849                        INTERACT_ACROSS_USERS,
15850                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15851                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15852                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15853                            + " requests FLAG_SINGLE_USER, but app does not hold "
15854                            + INTERACT_ACROSS_USERS;
15855                    Slog.w(TAG, msg);
15856                    throw new SecurityException(msg);
15857                }
15858                // Permission passed
15859                result = true;
15860            }
15861        } else if ("system".equals(componentProcessName)) {
15862            result = true;
15863        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15864            // Phone app and persistent apps are allowed to export singleuser providers.
15865            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15866                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15867        }
15868        if (DEBUG_MU) Slog.v(TAG_MU,
15869                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15870                + Integer.toHexString(flags) + ") = " + result);
15871        return result;
15872    }
15873
15874    /**
15875     * Checks to see if the caller is in the same app as the singleton
15876     * component, or the component is in a special app. It allows special apps
15877     * to export singleton components but prevents exporting singleton
15878     * components for regular apps.
15879     */
15880    boolean isValidSingletonCall(int callingUid, int componentUid) {
15881        int componentAppId = UserHandle.getAppId(componentUid);
15882        return UserHandle.isSameApp(callingUid, componentUid)
15883                || componentAppId == Process.SYSTEM_UID
15884                || componentAppId == Process.PHONE_UID
15885                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15886                        == PackageManager.PERMISSION_GRANTED;
15887    }
15888
15889    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15890            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15891            int userId) throws TransactionTooLargeException {
15892        enforceNotIsolatedCaller("bindService");
15893
15894        // Refuse possible leaked file descriptors
15895        if (service != null && service.hasFileDescriptors() == true) {
15896            throw new IllegalArgumentException("File descriptors passed in Intent");
15897        }
15898
15899        if (callingPackage == null) {
15900            throw new IllegalArgumentException("callingPackage cannot be null");
15901        }
15902
15903        synchronized(this) {
15904            return mServices.bindServiceLocked(caller, token, service,
15905                    resolvedType, connection, flags, callingPackage, userId);
15906        }
15907    }
15908
15909    public boolean unbindService(IServiceConnection connection) {
15910        synchronized (this) {
15911            return mServices.unbindServiceLocked(connection);
15912        }
15913    }
15914
15915    public void publishService(IBinder token, Intent intent, IBinder service) {
15916        // Refuse possible leaked file descriptors
15917        if (intent != null && intent.hasFileDescriptors() == true) {
15918            throw new IllegalArgumentException("File descriptors passed in Intent");
15919        }
15920
15921        synchronized(this) {
15922            if (!(token instanceof ServiceRecord)) {
15923                throw new IllegalArgumentException("Invalid service token");
15924            }
15925            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15926        }
15927    }
15928
15929    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15930        // Refuse possible leaked file descriptors
15931        if (intent != null && intent.hasFileDescriptors() == true) {
15932            throw new IllegalArgumentException("File descriptors passed in Intent");
15933        }
15934
15935        synchronized(this) {
15936            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15937        }
15938    }
15939
15940    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15941        synchronized(this) {
15942            if (!(token instanceof ServiceRecord)) {
15943                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15944                throw new IllegalArgumentException("Invalid service token");
15945            }
15946            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15947        }
15948    }
15949
15950    // =========================================================
15951    // BACKUP AND RESTORE
15952    // =========================================================
15953
15954    // Cause the target app to be launched if necessary and its backup agent
15955    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15956    // activity manager to announce its creation.
15957    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15958        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15959                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15960        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15961
15962        synchronized(this) {
15963            // !!! TODO: currently no check here that we're already bound
15964            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15965            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15966            synchronized (stats) {
15967                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15968            }
15969
15970            // Backup agent is now in use, its package can't be stopped.
15971            try {
15972                AppGlobals.getPackageManager().setPackageStoppedState(
15973                        app.packageName, false, UserHandle.getUserId(app.uid));
15974            } catch (RemoteException e) {
15975            } catch (IllegalArgumentException e) {
15976                Slog.w(TAG, "Failed trying to unstop package "
15977                        + app.packageName + ": " + e);
15978            }
15979
15980            BackupRecord r = new BackupRecord(ss, app, backupMode);
15981            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15982                    ? new ComponentName(app.packageName, app.backupAgentName)
15983                    : new ComponentName("android", "FullBackupAgent");
15984            // startProcessLocked() returns existing proc's record if it's already running
15985            ProcessRecord proc = startProcessLocked(app.processName, app,
15986                    false, 0, "backup", hostingName, false, false, false);
15987            if (proc == null) {
15988                Slog.e(TAG, "Unable to start backup agent process " + r);
15989                return false;
15990            }
15991
15992            r.app = proc;
15993            mBackupTarget = r;
15994            mBackupAppName = app.packageName;
15995
15996            // Try not to kill the process during backup
15997            updateOomAdjLocked(proc);
15998
15999            // If the process is already attached, schedule the creation of the backup agent now.
16000            // If it is not yet live, this will be done when it attaches to the framework.
16001            if (proc.thread != null) {
16002                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16003                try {
16004                    proc.thread.scheduleCreateBackupAgent(app,
16005                            compatibilityInfoForPackageLocked(app), backupMode);
16006                } catch (RemoteException e) {
16007                    // Will time out on the backup manager side
16008                }
16009            } else {
16010                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16011            }
16012            // Invariants: at this point, the target app process exists and the application
16013            // is either already running or in the process of coming up.  mBackupTarget and
16014            // mBackupAppName describe the app, so that when it binds back to the AM we
16015            // know that it's scheduled for a backup-agent operation.
16016        }
16017
16018        return true;
16019    }
16020
16021    @Override
16022    public void clearPendingBackup() {
16023        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16024        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16025
16026        synchronized (this) {
16027            mBackupTarget = null;
16028            mBackupAppName = null;
16029        }
16030    }
16031
16032    // A backup agent has just come up
16033    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16034        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16035                + " = " + agent);
16036
16037        synchronized(this) {
16038            if (!agentPackageName.equals(mBackupAppName)) {
16039                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16040                return;
16041            }
16042        }
16043
16044        long oldIdent = Binder.clearCallingIdentity();
16045        try {
16046            IBackupManager bm = IBackupManager.Stub.asInterface(
16047                    ServiceManager.getService(Context.BACKUP_SERVICE));
16048            bm.agentConnected(agentPackageName, agent);
16049        } catch (RemoteException e) {
16050            // can't happen; the backup manager service is local
16051        } catch (Exception e) {
16052            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16053            e.printStackTrace();
16054        } finally {
16055            Binder.restoreCallingIdentity(oldIdent);
16056        }
16057    }
16058
16059    // done with this agent
16060    public void unbindBackupAgent(ApplicationInfo appInfo) {
16061        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16062        if (appInfo == null) {
16063            Slog.w(TAG, "unbind backup agent for null app");
16064            return;
16065        }
16066
16067        synchronized(this) {
16068            try {
16069                if (mBackupAppName == null) {
16070                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16071                    return;
16072                }
16073
16074                if (!mBackupAppName.equals(appInfo.packageName)) {
16075                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16076                    return;
16077                }
16078
16079                // Not backing this app up any more; reset its OOM adjustment
16080                final ProcessRecord proc = mBackupTarget.app;
16081                updateOomAdjLocked(proc);
16082
16083                // If the app crashed during backup, 'thread' will be null here
16084                if (proc.thread != null) {
16085                    try {
16086                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16087                                compatibilityInfoForPackageLocked(appInfo));
16088                    } catch (Exception e) {
16089                        Slog.e(TAG, "Exception when unbinding backup agent:");
16090                        e.printStackTrace();
16091                    }
16092                }
16093            } finally {
16094                mBackupTarget = null;
16095                mBackupAppName = null;
16096            }
16097        }
16098    }
16099    // =========================================================
16100    // BROADCASTS
16101    // =========================================================
16102
16103    boolean isPendingBroadcastProcessLocked(int pid) {
16104        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16105                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16106    }
16107
16108    void skipPendingBroadcastLocked(int pid) {
16109            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16110            for (BroadcastQueue queue : mBroadcastQueues) {
16111                queue.skipPendingBroadcastLocked(pid);
16112            }
16113    }
16114
16115    // The app just attached; send any pending broadcasts that it should receive
16116    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16117        boolean didSomething = false;
16118        for (BroadcastQueue queue : mBroadcastQueues) {
16119            didSomething |= queue.sendPendingBroadcastsLocked(app);
16120        }
16121        return didSomething;
16122    }
16123
16124    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16125            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16126        enforceNotIsolatedCaller("registerReceiver");
16127        ArrayList<Intent> stickyIntents = null;
16128        ProcessRecord callerApp = null;
16129        int callingUid;
16130        int callingPid;
16131        synchronized(this) {
16132            if (caller != null) {
16133                callerApp = getRecordForAppLocked(caller);
16134                if (callerApp == null) {
16135                    throw new SecurityException(
16136                            "Unable to find app for caller " + caller
16137                            + " (pid=" + Binder.getCallingPid()
16138                            + ") when registering receiver " + receiver);
16139                }
16140                if (callerApp.info.uid != Process.SYSTEM_UID &&
16141                        !callerApp.pkgList.containsKey(callerPackage) &&
16142                        !"android".equals(callerPackage)) {
16143                    throw new SecurityException("Given caller package " + callerPackage
16144                            + " is not running in process " + callerApp);
16145                }
16146                callingUid = callerApp.info.uid;
16147                callingPid = callerApp.pid;
16148            } else {
16149                callerPackage = null;
16150                callingUid = Binder.getCallingUid();
16151                callingPid = Binder.getCallingPid();
16152            }
16153
16154            userId = handleIncomingUser(callingPid, callingUid, userId,
16155                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16156
16157            Iterator<String> actions = filter.actionsIterator();
16158            if (actions == null) {
16159                ArrayList<String> noAction = new ArrayList<String>(1);
16160                noAction.add(null);
16161                actions = noAction.iterator();
16162            }
16163
16164            // Collect stickies of users
16165            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16166            while (actions.hasNext()) {
16167                String action = actions.next();
16168                for (int id : userIds) {
16169                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16170                    if (stickies != null) {
16171                        ArrayList<Intent> intents = stickies.get(action);
16172                        if (intents != null) {
16173                            if (stickyIntents == null) {
16174                                stickyIntents = new ArrayList<Intent>();
16175                            }
16176                            stickyIntents.addAll(intents);
16177                        }
16178                    }
16179                }
16180            }
16181        }
16182
16183        ArrayList<Intent> allSticky = null;
16184        if (stickyIntents != null) {
16185            final ContentResolver resolver = mContext.getContentResolver();
16186            // Look for any matching sticky broadcasts...
16187            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16188                Intent intent = stickyIntents.get(i);
16189                // If intent has scheme "content", it will need to acccess
16190                // provider that needs to lock mProviderMap in ActivityThread
16191                // and also it may need to wait application response, so we
16192                // cannot lock ActivityManagerService here.
16193                if (filter.match(resolver, intent, true, TAG) >= 0) {
16194                    if (allSticky == null) {
16195                        allSticky = new ArrayList<Intent>();
16196                    }
16197                    allSticky.add(intent);
16198                }
16199            }
16200        }
16201
16202        // The first sticky in the list is returned directly back to the client.
16203        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16204        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16205        if (receiver == null) {
16206            return sticky;
16207        }
16208
16209        synchronized (this) {
16210            if (callerApp != null && (callerApp.thread == null
16211                    || callerApp.thread.asBinder() != caller.asBinder())) {
16212                // Original caller already died
16213                return null;
16214            }
16215            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16216            if (rl == null) {
16217                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16218                        userId, receiver);
16219                if (rl.app != null) {
16220                    rl.app.receivers.add(rl);
16221                } else {
16222                    try {
16223                        receiver.asBinder().linkToDeath(rl, 0);
16224                    } catch (RemoteException e) {
16225                        return sticky;
16226                    }
16227                    rl.linkedToDeath = true;
16228                }
16229                mRegisteredReceivers.put(receiver.asBinder(), rl);
16230            } else if (rl.uid != callingUid) {
16231                throw new IllegalArgumentException(
16232                        "Receiver requested to register for uid " + callingUid
16233                        + " was previously registered for uid " + rl.uid);
16234            } else if (rl.pid != callingPid) {
16235                throw new IllegalArgumentException(
16236                        "Receiver requested to register for pid " + callingPid
16237                        + " was previously registered for pid " + rl.pid);
16238            } else if (rl.userId != userId) {
16239                throw new IllegalArgumentException(
16240                        "Receiver requested to register for user " + userId
16241                        + " was previously registered for user " + rl.userId);
16242            }
16243            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16244                    permission, callingUid, userId);
16245            rl.add(bf);
16246            if (!bf.debugCheck()) {
16247                Slog.w(TAG, "==> For Dynamic broadcast");
16248            }
16249            mReceiverResolver.addFilter(bf);
16250
16251            // Enqueue broadcasts for all existing stickies that match
16252            // this filter.
16253            if (allSticky != null) {
16254                ArrayList receivers = new ArrayList();
16255                receivers.add(bf);
16256
16257                final int stickyCount = allSticky.size();
16258                for (int i = 0; i < stickyCount; i++) {
16259                    Intent intent = allSticky.get(i);
16260                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16261                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16262                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16263                            null, 0, null, null, false, true, true, -1);
16264                    queue.enqueueParallelBroadcastLocked(r);
16265                    queue.scheduleBroadcastsLocked();
16266                }
16267            }
16268
16269            return sticky;
16270        }
16271    }
16272
16273    public void unregisterReceiver(IIntentReceiver receiver) {
16274        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16275
16276        final long origId = Binder.clearCallingIdentity();
16277        try {
16278            boolean doTrim = false;
16279
16280            synchronized(this) {
16281                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16282                if (rl != null) {
16283                    final BroadcastRecord r = rl.curBroadcast;
16284                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16285                        final boolean doNext = r.queue.finishReceiverLocked(
16286                                r, r.resultCode, r.resultData, r.resultExtras,
16287                                r.resultAbort, false);
16288                        if (doNext) {
16289                            doTrim = true;
16290                            r.queue.processNextBroadcast(false);
16291                        }
16292                    }
16293
16294                    if (rl.app != null) {
16295                        rl.app.receivers.remove(rl);
16296                    }
16297                    removeReceiverLocked(rl);
16298                    if (rl.linkedToDeath) {
16299                        rl.linkedToDeath = false;
16300                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16301                    }
16302                }
16303            }
16304
16305            // If we actually concluded any broadcasts, we might now be able
16306            // to trim the recipients' apps from our working set
16307            if (doTrim) {
16308                trimApplications();
16309                return;
16310            }
16311
16312        } finally {
16313            Binder.restoreCallingIdentity(origId);
16314        }
16315    }
16316
16317    void removeReceiverLocked(ReceiverList rl) {
16318        mRegisteredReceivers.remove(rl.receiver.asBinder());
16319        for (int i = rl.size() - 1; i >= 0; i--) {
16320            mReceiverResolver.removeFilter(rl.get(i));
16321        }
16322    }
16323
16324    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16325        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16326            ProcessRecord r = mLruProcesses.get(i);
16327            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16328                try {
16329                    r.thread.dispatchPackageBroadcast(cmd, packages);
16330                } catch (RemoteException ex) {
16331                }
16332            }
16333        }
16334    }
16335
16336    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16337            int callingUid, int[] users) {
16338        List<ResolveInfo> receivers = null;
16339        try {
16340            HashSet<ComponentName> singleUserReceivers = null;
16341            boolean scannedFirstReceivers = false;
16342            for (int user : users) {
16343                // Skip users that have Shell restrictions
16344                if (callingUid == Process.SHELL_UID
16345                        && getUserManagerLocked().hasUserRestriction(
16346                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16347                    continue;
16348                }
16349                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16350                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16351                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16352                    // If this is not the primary user, we need to check for
16353                    // any receivers that should be filtered out.
16354                    for (int i=0; i<newReceivers.size(); i++) {
16355                        ResolveInfo ri = newReceivers.get(i);
16356                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16357                            newReceivers.remove(i);
16358                            i--;
16359                        }
16360                    }
16361                }
16362                if (newReceivers != null && newReceivers.size() == 0) {
16363                    newReceivers = null;
16364                }
16365                if (receivers == null) {
16366                    receivers = newReceivers;
16367                } else if (newReceivers != null) {
16368                    // We need to concatenate the additional receivers
16369                    // found with what we have do far.  This would be easy,
16370                    // but we also need to de-dup any receivers that are
16371                    // singleUser.
16372                    if (!scannedFirstReceivers) {
16373                        // Collect any single user receivers we had already retrieved.
16374                        scannedFirstReceivers = true;
16375                        for (int i=0; i<receivers.size(); i++) {
16376                            ResolveInfo ri = receivers.get(i);
16377                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16378                                ComponentName cn = new ComponentName(
16379                                        ri.activityInfo.packageName, ri.activityInfo.name);
16380                                if (singleUserReceivers == null) {
16381                                    singleUserReceivers = new HashSet<ComponentName>();
16382                                }
16383                                singleUserReceivers.add(cn);
16384                            }
16385                        }
16386                    }
16387                    // Add the new results to the existing results, tracking
16388                    // and de-dupping single user receivers.
16389                    for (int i=0; i<newReceivers.size(); i++) {
16390                        ResolveInfo ri = newReceivers.get(i);
16391                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16392                            ComponentName cn = new ComponentName(
16393                                    ri.activityInfo.packageName, ri.activityInfo.name);
16394                            if (singleUserReceivers == null) {
16395                                singleUserReceivers = new HashSet<ComponentName>();
16396                            }
16397                            if (!singleUserReceivers.contains(cn)) {
16398                                singleUserReceivers.add(cn);
16399                                receivers.add(ri);
16400                            }
16401                        } else {
16402                            receivers.add(ri);
16403                        }
16404                    }
16405                }
16406            }
16407        } catch (RemoteException ex) {
16408            // pm is in same process, this will never happen.
16409        }
16410        return receivers;
16411    }
16412
16413    private final int broadcastIntentLocked(ProcessRecord callerApp,
16414            String callerPackage, Intent intent, String resolvedType,
16415            IIntentReceiver resultTo, int resultCode, String resultData,
16416            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16417            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16418        intent = new Intent(intent);
16419
16420        // By default broadcasts do not go to stopped apps.
16421        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16422
16423        // If we have not finished booting, don't allow this to launch new processes.
16424        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16425            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16426        }
16427
16428        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16429                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16430                + " ordered=" + ordered + " userid=" + userId);
16431        if ((resultTo != null) && !ordered) {
16432            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16433        }
16434
16435        userId = handleIncomingUser(callingPid, callingUid, userId,
16436                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16437
16438        // Make sure that the user who is receiving this broadcast is running.
16439        // If not, we will just skip it. Make an exception for shutdown broadcasts
16440        // and upgrade steps.
16441
16442        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16443            if ((callingUid != Process.SYSTEM_UID
16444                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16445                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16446                Slog.w(TAG, "Skipping broadcast of " + intent
16447                        + ": user " + userId + " is stopped");
16448                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16449            }
16450        }
16451
16452        BroadcastOptions brOptions = null;
16453        if (options != null) {
16454            brOptions = new BroadcastOptions(options);
16455            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16456                // See if the caller is allowed to do this.  Note we are checking against
16457                // the actual real caller (not whoever provided the operation as say a
16458                // PendingIntent), because that who is actually supplied the arguments.
16459                if (checkComponentPermission(
16460                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16461                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16462                        != PackageManager.PERMISSION_GRANTED) {
16463                    String msg = "Permission Denial: " + intent.getAction()
16464                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16465                            + ", uid=" + callingUid + ")"
16466                            + " requires "
16467                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16468                    Slog.w(TAG, msg);
16469                    throw new SecurityException(msg);
16470                }
16471            }
16472        }
16473
16474        /*
16475         * Prevent non-system code (defined here to be non-persistent
16476         * processes) from sending protected broadcasts.
16477         */
16478        int callingAppId = UserHandle.getAppId(callingUid);
16479        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16480            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16481            || callingAppId == Process.NFC_UID || callingUid == 0) {
16482            // Always okay.
16483        } else if (callerApp == null || !callerApp.persistent) {
16484            try {
16485                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16486                        intent.getAction())) {
16487                    String msg = "Permission Denial: not allowed to send broadcast "
16488                            + intent.getAction() + " from pid="
16489                            + callingPid + ", uid=" + callingUid;
16490                    Slog.w(TAG, msg);
16491                    throw new SecurityException(msg);
16492                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16493                    // Special case for compatibility: we don't want apps to send this,
16494                    // but historically it has not been protected and apps may be using it
16495                    // to poke their own app widget.  So, instead of making it protected,
16496                    // just limit it to the caller.
16497                    if (callerApp == null) {
16498                        String msg = "Permission Denial: not allowed to send broadcast "
16499                                + intent.getAction() + " from unknown caller.";
16500                        Slog.w(TAG, msg);
16501                        throw new SecurityException(msg);
16502                    } else if (intent.getComponent() != null) {
16503                        // They are good enough to send to an explicit component...  verify
16504                        // it is being sent to the calling app.
16505                        if (!intent.getComponent().getPackageName().equals(
16506                                callerApp.info.packageName)) {
16507                            String msg = "Permission Denial: not allowed to send broadcast "
16508                                    + intent.getAction() + " to "
16509                                    + intent.getComponent().getPackageName() + " from "
16510                                    + callerApp.info.packageName;
16511                            Slog.w(TAG, msg);
16512                            throw new SecurityException(msg);
16513                        }
16514                    } else {
16515                        // Limit broadcast to their own package.
16516                        intent.setPackage(callerApp.info.packageName);
16517                    }
16518                }
16519            } catch (RemoteException e) {
16520                Slog.w(TAG, "Remote exception", e);
16521                return ActivityManager.BROADCAST_SUCCESS;
16522            }
16523        }
16524
16525        final String action = intent.getAction();
16526        if (action != null) {
16527            switch (action) {
16528                case Intent.ACTION_UID_REMOVED:
16529                case Intent.ACTION_PACKAGE_REMOVED:
16530                case Intent.ACTION_PACKAGE_CHANGED:
16531                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16532                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16533                    // Handle special intents: if this broadcast is from the package
16534                    // manager about a package being removed, we need to remove all of
16535                    // its activities from the history stack.
16536                    if (checkComponentPermission(
16537                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16538                            callingPid, callingUid, -1, true)
16539                            != PackageManager.PERMISSION_GRANTED) {
16540                        String msg = "Permission Denial: " + intent.getAction()
16541                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16542                                + ", uid=" + callingUid + ")"
16543                                + " requires "
16544                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16545                        Slog.w(TAG, msg);
16546                        throw new SecurityException(msg);
16547                    }
16548                    switch (action) {
16549                        case Intent.ACTION_UID_REMOVED:
16550                            final Bundle intentExtras = intent.getExtras();
16551                            final int uid = intentExtras != null
16552                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16553                            if (uid >= 0) {
16554                                mBatteryStatsService.removeUid(uid);
16555                                mAppOpsService.uidRemoved(uid);
16556                            }
16557                            break;
16558                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16559                            // If resources are unavailable just force stop all those packages
16560                            // and flush the attribute cache as well.
16561                            String list[] =
16562                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16563                            if (list != null && list.length > 0) {
16564                                for (int i = 0; i < list.length; i++) {
16565                                    forceStopPackageLocked(list[i], -1, false, true, true,
16566                                            false, false, userId, "storage unmount");
16567                                }
16568                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16569                                sendPackageBroadcastLocked(
16570                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16571                                        userId);
16572                            }
16573                            break;
16574                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16575                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16576                            break;
16577                        case Intent.ACTION_PACKAGE_REMOVED:
16578                        case Intent.ACTION_PACKAGE_CHANGED:
16579                            Uri data = intent.getData();
16580                            String ssp;
16581                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16582                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16583                                boolean fullUninstall = removed &&
16584                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16585                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16586                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16587                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16588                                            false, true, true, false, fullUninstall, userId,
16589                                            removed ? "pkg removed" : "pkg changed");
16590                                }
16591                                if (removed) {
16592                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16593                                            new String[] {ssp}, userId);
16594                                    if (fullUninstall) {
16595                                        mAppOpsService.packageRemoved(
16596                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16597
16598                                        // Remove all permissions granted from/to this package
16599                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16600
16601                                        removeTasksByPackageNameLocked(ssp, userId);
16602                                        mBatteryStatsService.notePackageUninstalled(ssp);
16603                                    }
16604                                } else {
16605                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16606                                            intent.getStringArrayExtra(
16607                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16608                                }
16609                            }
16610                            break;
16611                    }
16612                    break;
16613                case Intent.ACTION_PACKAGE_ADDED:
16614                    // Special case for adding a package: by default turn on compatibility mode.
16615                    Uri data = intent.getData();
16616                    String ssp;
16617                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16618                        final boolean replacing =
16619                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16620                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16621
16622                        try {
16623                            ApplicationInfo ai = AppGlobals.getPackageManager().
16624                                    getApplicationInfo(ssp, 0, 0);
16625                            mBatteryStatsService.notePackageInstalled(ssp,
16626                                    ai != null ? ai.versionCode : 0);
16627                        } catch (RemoteException e) {
16628                        }
16629                    }
16630                    break;
16631                case Intent.ACTION_TIMEZONE_CHANGED:
16632                    // If this is the time zone changed action, queue up a message that will reset
16633                    // the timezone of all currently running processes. This message will get
16634                    // queued up before the broadcast happens.
16635                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16636                    break;
16637                case Intent.ACTION_TIME_CHANGED:
16638                    // If the user set the time, let all running processes know.
16639                    final int is24Hour =
16640                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16641                                    : 0;
16642                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16643                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16644                    synchronized (stats) {
16645                        stats.noteCurrentTimeChangedLocked();
16646                    }
16647                    break;
16648                case Intent.ACTION_CLEAR_DNS_CACHE:
16649                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16650                    break;
16651                case Proxy.PROXY_CHANGE_ACTION:
16652                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16653                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16654                    break;
16655            }
16656        }
16657
16658        // Add to the sticky list if requested.
16659        if (sticky) {
16660            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16661                    callingPid, callingUid)
16662                    != PackageManager.PERMISSION_GRANTED) {
16663                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16664                        + callingPid + ", uid=" + callingUid
16665                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16666                Slog.w(TAG, msg);
16667                throw new SecurityException(msg);
16668            }
16669            if (requiredPermissions != null && requiredPermissions.length > 0) {
16670                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16671                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16672                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16673            }
16674            if (intent.getComponent() != null) {
16675                throw new SecurityException(
16676                        "Sticky broadcasts can't target a specific component");
16677            }
16678            // We use userId directly here, since the "all" target is maintained
16679            // as a separate set of sticky broadcasts.
16680            if (userId != UserHandle.USER_ALL) {
16681                // But first, if this is not a broadcast to all users, then
16682                // make sure it doesn't conflict with an existing broadcast to
16683                // all users.
16684                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16685                        UserHandle.USER_ALL);
16686                if (stickies != null) {
16687                    ArrayList<Intent> list = stickies.get(intent.getAction());
16688                    if (list != null) {
16689                        int N = list.size();
16690                        int i;
16691                        for (i=0; i<N; i++) {
16692                            if (intent.filterEquals(list.get(i))) {
16693                                throw new IllegalArgumentException(
16694                                        "Sticky broadcast " + intent + " for user "
16695                                        + userId + " conflicts with existing global broadcast");
16696                            }
16697                        }
16698                    }
16699                }
16700            }
16701            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16702            if (stickies == null) {
16703                stickies = new ArrayMap<>();
16704                mStickyBroadcasts.put(userId, stickies);
16705            }
16706            ArrayList<Intent> list = stickies.get(intent.getAction());
16707            if (list == null) {
16708                list = new ArrayList<>();
16709                stickies.put(intent.getAction(), list);
16710            }
16711            final int stickiesCount = list.size();
16712            int i;
16713            for (i = 0; i < stickiesCount; i++) {
16714                if (intent.filterEquals(list.get(i))) {
16715                    // This sticky already exists, replace it.
16716                    list.set(i, new Intent(intent));
16717                    break;
16718                }
16719            }
16720            if (i >= stickiesCount) {
16721                list.add(new Intent(intent));
16722            }
16723        }
16724
16725        int[] users;
16726        if (userId == UserHandle.USER_ALL) {
16727            // Caller wants broadcast to go to all started users.
16728            users = mStartedUserArray;
16729        } else {
16730            // Caller wants broadcast to go to one specific user.
16731            users = new int[] {userId};
16732        }
16733
16734        // Figure out who all will receive this broadcast.
16735        List receivers = null;
16736        List<BroadcastFilter> registeredReceivers = null;
16737        // Need to resolve the intent to interested receivers...
16738        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16739                 == 0) {
16740            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16741        }
16742        if (intent.getComponent() == null) {
16743            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16744                // Query one target user at a time, excluding shell-restricted users
16745                UserManagerService ums = getUserManagerLocked();
16746                for (int i = 0; i < users.length; i++) {
16747                    if (ums.hasUserRestriction(
16748                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16749                        continue;
16750                    }
16751                    List<BroadcastFilter> registeredReceiversForUser =
16752                            mReceiverResolver.queryIntent(intent,
16753                                    resolvedType, false, users[i]);
16754                    if (registeredReceivers == null) {
16755                        registeredReceivers = registeredReceiversForUser;
16756                    } else if (registeredReceiversForUser != null) {
16757                        registeredReceivers.addAll(registeredReceiversForUser);
16758                    }
16759                }
16760            } else {
16761                registeredReceivers = mReceiverResolver.queryIntent(intent,
16762                        resolvedType, false, userId);
16763            }
16764        }
16765
16766        final boolean replacePending =
16767                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16768
16769        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16770                + " replacePending=" + replacePending);
16771
16772        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16773        if (!ordered && NR > 0) {
16774            // If we are not serializing this broadcast, then send the
16775            // registered receivers separately so they don't wait for the
16776            // components to be launched.
16777            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16778            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16779                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16780                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16781                    resultExtras, ordered, sticky, false, userId);
16782            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16783            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16784            if (!replaced) {
16785                queue.enqueueParallelBroadcastLocked(r);
16786                queue.scheduleBroadcastsLocked();
16787            }
16788            registeredReceivers = null;
16789            NR = 0;
16790        }
16791
16792        // Merge into one list.
16793        int ir = 0;
16794        if (receivers != null) {
16795            // A special case for PACKAGE_ADDED: do not allow the package
16796            // being added to see this broadcast.  This prevents them from
16797            // using this as a back door to get run as soon as they are
16798            // installed.  Maybe in the future we want to have a special install
16799            // broadcast or such for apps, but we'd like to deliberately make
16800            // this decision.
16801            String skipPackages[] = null;
16802            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16803                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16804                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16805                Uri data = intent.getData();
16806                if (data != null) {
16807                    String pkgName = data.getSchemeSpecificPart();
16808                    if (pkgName != null) {
16809                        skipPackages = new String[] { pkgName };
16810                    }
16811                }
16812            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16813                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16814            }
16815            if (skipPackages != null && (skipPackages.length > 0)) {
16816                for (String skipPackage : skipPackages) {
16817                    if (skipPackage != null) {
16818                        int NT = receivers.size();
16819                        for (int it=0; it<NT; it++) {
16820                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16821                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16822                                receivers.remove(it);
16823                                it--;
16824                                NT--;
16825                            }
16826                        }
16827                    }
16828                }
16829            }
16830
16831            int NT = receivers != null ? receivers.size() : 0;
16832            int it = 0;
16833            ResolveInfo curt = null;
16834            BroadcastFilter curr = null;
16835            while (it < NT && ir < NR) {
16836                if (curt == null) {
16837                    curt = (ResolveInfo)receivers.get(it);
16838                }
16839                if (curr == null) {
16840                    curr = registeredReceivers.get(ir);
16841                }
16842                if (curr.getPriority() >= curt.priority) {
16843                    // Insert this broadcast record into the final list.
16844                    receivers.add(it, curr);
16845                    ir++;
16846                    curr = null;
16847                    it++;
16848                    NT++;
16849                } else {
16850                    // Skip to the next ResolveInfo in the final list.
16851                    it++;
16852                    curt = null;
16853                }
16854            }
16855        }
16856        while (ir < NR) {
16857            if (receivers == null) {
16858                receivers = new ArrayList();
16859            }
16860            receivers.add(registeredReceivers.get(ir));
16861            ir++;
16862        }
16863
16864        if ((receivers != null && receivers.size() > 0)
16865                || resultTo != null) {
16866            BroadcastQueue queue = broadcastQueueForIntent(intent);
16867            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16868                    callerPackage, callingPid, callingUid, resolvedType,
16869                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16870                    resultData, resultExtras, ordered, sticky, false, userId);
16871
16872            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16873                    + ": prev had " + queue.mOrderedBroadcasts.size());
16874            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16875                    "Enqueueing broadcast " + r.intent.getAction());
16876
16877            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16878            if (!replaced) {
16879                queue.enqueueOrderedBroadcastLocked(r);
16880                queue.scheduleBroadcastsLocked();
16881            }
16882        }
16883
16884        return ActivityManager.BROADCAST_SUCCESS;
16885    }
16886
16887    final Intent verifyBroadcastLocked(Intent intent) {
16888        // Refuse possible leaked file descriptors
16889        if (intent != null && intent.hasFileDescriptors() == true) {
16890            throw new IllegalArgumentException("File descriptors passed in Intent");
16891        }
16892
16893        int flags = intent.getFlags();
16894
16895        if (!mProcessesReady) {
16896            // if the caller really truly claims to know what they're doing, go
16897            // ahead and allow the broadcast without launching any receivers
16898            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16899                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16900            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16901                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16902                        + " before boot completion");
16903                throw new IllegalStateException("Cannot broadcast before boot completed");
16904            }
16905        }
16906
16907        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16908            throw new IllegalArgumentException(
16909                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16910        }
16911
16912        return intent;
16913    }
16914
16915    public final int broadcastIntent(IApplicationThread caller,
16916            Intent intent, String resolvedType, IIntentReceiver resultTo,
16917            int resultCode, String resultData, Bundle resultExtras,
16918            String[] requiredPermissions, int appOp, Bundle options,
16919            boolean serialized, boolean sticky, int userId) {
16920        enforceNotIsolatedCaller("broadcastIntent");
16921        synchronized(this) {
16922            intent = verifyBroadcastLocked(intent);
16923
16924            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16925            final int callingPid = Binder.getCallingPid();
16926            final int callingUid = Binder.getCallingUid();
16927            final long origId = Binder.clearCallingIdentity();
16928            int res = broadcastIntentLocked(callerApp,
16929                    callerApp != null ? callerApp.info.packageName : null,
16930                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16931                    requiredPermissions, appOp, null, serialized, sticky,
16932                    callingPid, callingUid, userId);
16933            Binder.restoreCallingIdentity(origId);
16934            return res;
16935        }
16936    }
16937
16938
16939    int broadcastIntentInPackage(String packageName, int uid,
16940            Intent intent, String resolvedType, IIntentReceiver resultTo,
16941            int resultCode, String resultData, Bundle resultExtras,
16942            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16943            int userId) {
16944        synchronized(this) {
16945            intent = verifyBroadcastLocked(intent);
16946
16947            final long origId = Binder.clearCallingIdentity();
16948            String[] requiredPermissions = requiredPermission == null ? null
16949                    : new String[] {requiredPermission};
16950            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16951                    resultTo, resultCode, resultData, resultExtras,
16952                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16953                    sticky, -1, uid, userId);
16954            Binder.restoreCallingIdentity(origId);
16955            return res;
16956        }
16957    }
16958
16959    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16960        // Refuse possible leaked file descriptors
16961        if (intent != null && intent.hasFileDescriptors() == true) {
16962            throw new IllegalArgumentException("File descriptors passed in Intent");
16963        }
16964
16965        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16966                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16967
16968        synchronized(this) {
16969            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16970                    != PackageManager.PERMISSION_GRANTED) {
16971                String msg = "Permission Denial: unbroadcastIntent() from pid="
16972                        + Binder.getCallingPid()
16973                        + ", uid=" + Binder.getCallingUid()
16974                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16975                Slog.w(TAG, msg);
16976                throw new SecurityException(msg);
16977            }
16978            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16979            if (stickies != null) {
16980                ArrayList<Intent> list = stickies.get(intent.getAction());
16981                if (list != null) {
16982                    int N = list.size();
16983                    int i;
16984                    for (i=0; i<N; i++) {
16985                        if (intent.filterEquals(list.get(i))) {
16986                            list.remove(i);
16987                            break;
16988                        }
16989                    }
16990                    if (list.size() <= 0) {
16991                        stickies.remove(intent.getAction());
16992                    }
16993                }
16994                if (stickies.size() <= 0) {
16995                    mStickyBroadcasts.remove(userId);
16996                }
16997            }
16998        }
16999    }
17000
17001    void backgroundServicesFinishedLocked(int userId) {
17002        for (BroadcastQueue queue : mBroadcastQueues) {
17003            queue.backgroundServicesFinishedLocked(userId);
17004        }
17005    }
17006
17007    public void finishReceiver(IBinder who, int resultCode, String resultData,
17008            Bundle resultExtras, boolean resultAbort, int flags) {
17009        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17010
17011        // Refuse possible leaked file descriptors
17012        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17013            throw new IllegalArgumentException("File descriptors passed in Bundle");
17014        }
17015
17016        final long origId = Binder.clearCallingIdentity();
17017        try {
17018            boolean doNext = false;
17019            BroadcastRecord r;
17020
17021            synchronized(this) {
17022                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17023                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17024                r = queue.getMatchingOrderedReceiver(who);
17025                if (r != null) {
17026                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17027                        resultData, resultExtras, resultAbort, true);
17028                }
17029            }
17030
17031            if (doNext) {
17032                r.queue.processNextBroadcast(false);
17033            }
17034            trimApplications();
17035        } finally {
17036            Binder.restoreCallingIdentity(origId);
17037        }
17038    }
17039
17040    // =========================================================
17041    // INSTRUMENTATION
17042    // =========================================================
17043
17044    public boolean startInstrumentation(ComponentName className,
17045            String profileFile, int flags, Bundle arguments,
17046            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17047            int userId, String abiOverride) {
17048        enforceNotIsolatedCaller("startInstrumentation");
17049        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17050                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17051        // Refuse possible leaked file descriptors
17052        if (arguments != null && arguments.hasFileDescriptors()) {
17053            throw new IllegalArgumentException("File descriptors passed in Bundle");
17054        }
17055
17056        synchronized(this) {
17057            InstrumentationInfo ii = null;
17058            ApplicationInfo ai = null;
17059            try {
17060                ii = mContext.getPackageManager().getInstrumentationInfo(
17061                    className, STOCK_PM_FLAGS);
17062                ai = AppGlobals.getPackageManager().getApplicationInfo(
17063                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17064            } catch (PackageManager.NameNotFoundException e) {
17065            } catch (RemoteException e) {
17066            }
17067            if (ii == null) {
17068                reportStartInstrumentationFailure(watcher, className,
17069                        "Unable to find instrumentation info for: " + className);
17070                return false;
17071            }
17072            if (ai == null) {
17073                reportStartInstrumentationFailure(watcher, className,
17074                        "Unable to find instrumentation target package: " + ii.targetPackage);
17075                return false;
17076            }
17077
17078            int match = mContext.getPackageManager().checkSignatures(
17079                    ii.targetPackage, ii.packageName);
17080            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17081                String msg = "Permission Denial: starting instrumentation "
17082                        + className + " from pid="
17083                        + Binder.getCallingPid()
17084                        + ", uid=" + Binder.getCallingPid()
17085                        + " not allowed because package " + ii.packageName
17086                        + " does not have a signature matching the target "
17087                        + ii.targetPackage;
17088                reportStartInstrumentationFailure(watcher, className, msg);
17089                throw new SecurityException(msg);
17090            }
17091
17092            final long origId = Binder.clearCallingIdentity();
17093            // Instrumentation can kill and relaunch even persistent processes
17094            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17095                    "start instr");
17096            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17097            app.instrumentationClass = className;
17098            app.instrumentationInfo = ai;
17099            app.instrumentationProfileFile = profileFile;
17100            app.instrumentationArguments = arguments;
17101            app.instrumentationWatcher = watcher;
17102            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17103            app.instrumentationResultClass = className;
17104            Binder.restoreCallingIdentity(origId);
17105        }
17106
17107        return true;
17108    }
17109
17110    /**
17111     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17112     * error to the logs, but if somebody is watching, send the report there too.  This enables
17113     * the "am" command to report errors with more information.
17114     *
17115     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17116     * @param cn The component name of the instrumentation.
17117     * @param report The error report.
17118     */
17119    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17120            ComponentName cn, String report) {
17121        Slog.w(TAG, report);
17122        try {
17123            if (watcher != null) {
17124                Bundle results = new Bundle();
17125                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17126                results.putString("Error", report);
17127                watcher.instrumentationStatus(cn, -1, results);
17128            }
17129        } catch (RemoteException e) {
17130            Slog.w(TAG, e);
17131        }
17132    }
17133
17134    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17135        if (app.instrumentationWatcher != null) {
17136            try {
17137                // NOTE:  IInstrumentationWatcher *must* be oneway here
17138                app.instrumentationWatcher.instrumentationFinished(
17139                    app.instrumentationClass,
17140                    resultCode,
17141                    results);
17142            } catch (RemoteException e) {
17143            }
17144        }
17145
17146        // Can't call out of the system process with a lock held, so post a message.
17147        mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17148                app.instrumentationUiAutomationConnection).sendToTarget();
17149
17150        app.instrumentationWatcher = null;
17151        app.instrumentationUiAutomationConnection = null;
17152        app.instrumentationClass = null;
17153        app.instrumentationInfo = null;
17154        app.instrumentationProfileFile = null;
17155        app.instrumentationArguments = null;
17156
17157        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17158                "finished inst");
17159    }
17160
17161    public void finishInstrumentation(IApplicationThread target,
17162            int resultCode, Bundle results) {
17163        int userId = UserHandle.getCallingUserId();
17164        // Refuse possible leaked file descriptors
17165        if (results != null && results.hasFileDescriptors()) {
17166            throw new IllegalArgumentException("File descriptors passed in Intent");
17167        }
17168
17169        synchronized(this) {
17170            ProcessRecord app = getRecordForAppLocked(target);
17171            if (app == null) {
17172                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17173                return;
17174            }
17175            final long origId = Binder.clearCallingIdentity();
17176            finishInstrumentationLocked(app, resultCode, results);
17177            Binder.restoreCallingIdentity(origId);
17178        }
17179    }
17180
17181    // =========================================================
17182    // CONFIGURATION
17183    // =========================================================
17184
17185    public ConfigurationInfo getDeviceConfigurationInfo() {
17186        ConfigurationInfo config = new ConfigurationInfo();
17187        synchronized (this) {
17188            config.reqTouchScreen = mConfiguration.touchscreen;
17189            config.reqKeyboardType = mConfiguration.keyboard;
17190            config.reqNavigation = mConfiguration.navigation;
17191            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17192                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17193                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17194            }
17195            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17196                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17197                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17198            }
17199            config.reqGlEsVersion = GL_ES_VERSION;
17200        }
17201        return config;
17202    }
17203
17204    ActivityStack getFocusedStack() {
17205        return mStackSupervisor.getFocusedStack();
17206    }
17207
17208    @Override
17209    public int getFocusedStackId() throws RemoteException {
17210        ActivityStack focusedStack = getFocusedStack();
17211        if (focusedStack != null) {
17212            return focusedStack.getStackId();
17213        }
17214        return -1;
17215    }
17216
17217    public Configuration getConfiguration() {
17218        Configuration ci;
17219        synchronized(this) {
17220            ci = new Configuration(mConfiguration);
17221            ci.userSetLocale = false;
17222        }
17223        return ci;
17224    }
17225
17226    public void updatePersistentConfiguration(Configuration values) {
17227        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17228                "updateConfiguration()");
17229        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17230                "updateConfiguration()");
17231        if (values == null) {
17232            throw new NullPointerException("Configuration must not be null");
17233        }
17234
17235        synchronized(this) {
17236            final long origId = Binder.clearCallingIdentity();
17237            updateConfigurationLocked(values, null, true, false);
17238            Binder.restoreCallingIdentity(origId);
17239        }
17240    }
17241
17242    public void updateConfiguration(Configuration values) {
17243        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17244                "updateConfiguration()");
17245
17246        synchronized(this) {
17247            if (values == null && mWindowManager != null) {
17248                // sentinel: fetch the current configuration from the window manager
17249                values = mWindowManager.computeNewConfiguration();
17250            }
17251
17252            if (mWindowManager != null) {
17253                mProcessList.applyDisplaySize(mWindowManager);
17254            }
17255
17256            final long origId = Binder.clearCallingIdentity();
17257            if (values != null) {
17258                Settings.System.clearConfiguration(values);
17259            }
17260            updateConfigurationLocked(values, null, false, false);
17261            Binder.restoreCallingIdentity(origId);
17262        }
17263    }
17264
17265    /**
17266     * Do either or both things: (1) change the current configuration, and (2)
17267     * make sure the given activity is running with the (now) current
17268     * configuration.  Returns true if the activity has been left running, or
17269     * false if <var>starting</var> is being destroyed to match the new
17270     * configuration.
17271     * @param persistent TODO
17272     */
17273    boolean updateConfigurationLocked(Configuration values,
17274            ActivityRecord starting, boolean persistent, boolean initLocale) {
17275        int changes = 0;
17276
17277        if (values != null) {
17278            Configuration newConfig = new Configuration(mConfiguration);
17279            changes = newConfig.updateFrom(values);
17280            if (changes != 0) {
17281                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17282                        "Updating configuration to: " + values);
17283
17284                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17285
17286                if (!initLocale && values.locale != null && values.userSetLocale) {
17287                    final String languageTag = values.locale.toLanguageTag();
17288                    SystemProperties.set("persist.sys.locale", languageTag);
17289                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17290                            values.locale));
17291                }
17292
17293                mConfigurationSeq++;
17294                if (mConfigurationSeq <= 0) {
17295                    mConfigurationSeq = 1;
17296                }
17297                newConfig.seq = mConfigurationSeq;
17298                mConfiguration = newConfig;
17299                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17300                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17301                //mUsageStatsService.noteStartConfig(newConfig);
17302
17303                final Configuration configCopy = new Configuration(mConfiguration);
17304
17305                // TODO: If our config changes, should we auto dismiss any currently
17306                // showing dialogs?
17307                mShowDialogs = shouldShowDialogs(newConfig);
17308
17309                AttributeCache ac = AttributeCache.instance();
17310                if (ac != null) {
17311                    ac.updateConfiguration(configCopy);
17312                }
17313
17314                // Make sure all resources in our process are updated
17315                // right now, so that anyone who is going to retrieve
17316                // resource values after we return will be sure to get
17317                // the new ones.  This is especially important during
17318                // boot, where the first config change needs to guarantee
17319                // all resources have that config before following boot
17320                // code is executed.
17321                mSystemThread.applyConfigurationToResources(configCopy);
17322
17323                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17324                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17325                    msg.obj = new Configuration(configCopy);
17326                    mHandler.sendMessage(msg);
17327                }
17328
17329                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17330                    ProcessRecord app = mLruProcesses.get(i);
17331                    try {
17332                        if (app.thread != null) {
17333                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17334                                    + app.processName + " new config " + mConfiguration);
17335                            app.thread.scheduleConfigurationChanged(configCopy);
17336                        }
17337                    } catch (Exception e) {
17338                    }
17339                }
17340                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17341                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17342                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17343                        | Intent.FLAG_RECEIVER_FOREGROUND);
17344                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17345                        null, AppOpsManager.OP_NONE, null, false, false,
17346                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17347                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17348                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17349                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17350                    if (!mProcessesReady) {
17351                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17352                    }
17353                    broadcastIntentLocked(null, null, intent,
17354                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17355                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17356                }
17357            }
17358        }
17359
17360        boolean kept = true;
17361        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17362        // mainStack is null during startup.
17363        if (mainStack != null) {
17364            if (changes != 0 && starting == null) {
17365                // If the configuration changed, and the caller is not already
17366                // in the process of starting an activity, then find the top
17367                // activity to check if its configuration needs to change.
17368                starting = mainStack.topRunningActivityLocked(null);
17369            }
17370
17371            if (starting != null) {
17372                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17373                // And we need to make sure at this point that all other activities
17374                // are made visible with the correct configuration.
17375                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17376            }
17377        }
17378
17379        if (values != null && mWindowManager != null) {
17380            mWindowManager.setNewConfiguration(mConfiguration);
17381        }
17382
17383        return kept;
17384    }
17385
17386    /**
17387     * Decide based on the configuration whether we should shouw the ANR,
17388     * crash, etc dialogs.  The idea is that if there is no affordnace to
17389     * press the on-screen buttons, we shouldn't show the dialog.
17390     *
17391     * A thought: SystemUI might also want to get told about this, the Power
17392     * dialog / global actions also might want different behaviors.
17393     */
17394    private static final boolean shouldShowDialogs(Configuration config) {
17395        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17396                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17397                && config.navigation == Configuration.NAVIGATION_NONAV);
17398    }
17399
17400    @Override
17401    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17402        synchronized (this) {
17403            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17404            if (srec != null) {
17405                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17406            }
17407        }
17408        return false;
17409    }
17410
17411    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17412            Intent resultData) {
17413
17414        synchronized (this) {
17415            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17416            if (r != null) {
17417                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17418            }
17419            return false;
17420        }
17421    }
17422
17423    public int getLaunchedFromUid(IBinder activityToken) {
17424        ActivityRecord srec;
17425        synchronized (this) {
17426            srec = ActivityRecord.forTokenLocked(activityToken);
17427        }
17428        if (srec == null) {
17429            return -1;
17430        }
17431        return srec.launchedFromUid;
17432    }
17433
17434    public String getLaunchedFromPackage(IBinder activityToken) {
17435        ActivityRecord srec;
17436        synchronized (this) {
17437            srec = ActivityRecord.forTokenLocked(activityToken);
17438        }
17439        if (srec == null) {
17440            return null;
17441        }
17442        return srec.launchedFromPackage;
17443    }
17444
17445    // =========================================================
17446    // LIFETIME MANAGEMENT
17447    // =========================================================
17448
17449    // Returns which broadcast queue the app is the current [or imminent] receiver
17450    // on, or 'null' if the app is not an active broadcast recipient.
17451    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17452        BroadcastRecord r = app.curReceiver;
17453        if (r != null) {
17454            return r.queue;
17455        }
17456
17457        // It's not the current receiver, but it might be starting up to become one
17458        synchronized (this) {
17459            for (BroadcastQueue queue : mBroadcastQueues) {
17460                r = queue.mPendingBroadcast;
17461                if (r != null && r.curApp == app) {
17462                    // found it; report which queue it's in
17463                    return queue;
17464                }
17465            }
17466        }
17467
17468        return null;
17469    }
17470
17471    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17472            ComponentName targetComponent, String targetProcess) {
17473        if (!mTrackingAssociations) {
17474            return null;
17475        }
17476        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17477                = mAssociations.get(targetUid);
17478        if (components == null) {
17479            components = new ArrayMap<>();
17480            mAssociations.put(targetUid, components);
17481        }
17482        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17483        if (sourceUids == null) {
17484            sourceUids = new SparseArray<>();
17485            components.put(targetComponent, sourceUids);
17486        }
17487        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17488        if (sourceProcesses == null) {
17489            sourceProcesses = new ArrayMap<>();
17490            sourceUids.put(sourceUid, sourceProcesses);
17491        }
17492        Association ass = sourceProcesses.get(sourceProcess);
17493        if (ass == null) {
17494            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17495                    targetProcess);
17496            sourceProcesses.put(sourceProcess, ass);
17497        }
17498        ass.mCount++;
17499        ass.mNesting++;
17500        if (ass.mNesting == 1) {
17501            ass.mStartTime = SystemClock.uptimeMillis();
17502        }
17503        return ass;
17504    }
17505
17506    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17507            ComponentName targetComponent) {
17508        if (!mTrackingAssociations) {
17509            return;
17510        }
17511        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17512                = mAssociations.get(targetUid);
17513        if (components == null) {
17514            return;
17515        }
17516        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17517        if (sourceUids == null) {
17518            return;
17519        }
17520        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17521        if (sourceProcesses == null) {
17522            return;
17523        }
17524        Association ass = sourceProcesses.get(sourceProcess);
17525        if (ass == null || ass.mNesting <= 0) {
17526            return;
17527        }
17528        ass.mNesting--;
17529        if (ass.mNesting == 0) {
17530            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17531        }
17532    }
17533
17534    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17535            boolean doingAll, long now) {
17536        if (mAdjSeq == app.adjSeq) {
17537            // This adjustment has already been computed.
17538            return app.curRawAdj;
17539        }
17540
17541        if (app.thread == null) {
17542            app.adjSeq = mAdjSeq;
17543            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17544            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17545            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17546        }
17547
17548        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17549        app.adjSource = null;
17550        app.adjTarget = null;
17551        app.empty = false;
17552        app.cached = false;
17553
17554        final int activitiesSize = app.activities.size();
17555
17556        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17557            // The max adjustment doesn't allow this app to be anything
17558            // below foreground, so it is not worth doing work for it.
17559            app.adjType = "fixed";
17560            app.adjSeq = mAdjSeq;
17561            app.curRawAdj = app.maxAdj;
17562            app.foregroundActivities = false;
17563            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17564            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17565            // System processes can do UI, and when they do we want to have
17566            // them trim their memory after the user leaves the UI.  To
17567            // facilitate this, here we need to determine whether or not it
17568            // is currently showing UI.
17569            app.systemNoUi = true;
17570            if (app == TOP_APP) {
17571                app.systemNoUi = false;
17572            } else if (activitiesSize > 0) {
17573                for (int j = 0; j < activitiesSize; j++) {
17574                    final ActivityRecord r = app.activities.get(j);
17575                    if (r.visible) {
17576                        app.systemNoUi = false;
17577                    }
17578                }
17579            }
17580            if (!app.systemNoUi) {
17581                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17582            }
17583            return (app.curAdj=app.maxAdj);
17584        }
17585
17586        app.systemNoUi = false;
17587
17588        final int PROCESS_STATE_TOP = mTopProcessState;
17589
17590        // Determine the importance of the process, starting with most
17591        // important to least, and assign an appropriate OOM adjustment.
17592        int adj;
17593        int schedGroup;
17594        int procState;
17595        boolean foregroundActivities = false;
17596        BroadcastQueue queue;
17597        if (app == TOP_APP) {
17598            // The last app on the list is the foreground app.
17599            adj = ProcessList.FOREGROUND_APP_ADJ;
17600            schedGroup = Process.THREAD_GROUP_DEFAULT;
17601            app.adjType = "top-activity";
17602            foregroundActivities = true;
17603            procState = PROCESS_STATE_TOP;
17604        } else if (app.instrumentationClass != null) {
17605            // Don't want to kill running instrumentation.
17606            adj = ProcessList.FOREGROUND_APP_ADJ;
17607            schedGroup = Process.THREAD_GROUP_DEFAULT;
17608            app.adjType = "instrumentation";
17609            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17610        } else if ((queue = isReceivingBroadcast(app)) != null) {
17611            // An app that is currently receiving a broadcast also
17612            // counts as being in the foreground for OOM killer purposes.
17613            // It's placed in a sched group based on the nature of the
17614            // broadcast as reflected by which queue it's active in.
17615            adj = ProcessList.FOREGROUND_APP_ADJ;
17616            schedGroup = (queue == mFgBroadcastQueue)
17617                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17618            app.adjType = "broadcast";
17619            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17620        } else if (app.executingServices.size() > 0) {
17621            // An app that is currently executing a service callback also
17622            // counts as being in the foreground.
17623            adj = ProcessList.FOREGROUND_APP_ADJ;
17624            schedGroup = app.execServicesFg ?
17625                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17626            app.adjType = "exec-service";
17627            procState = ActivityManager.PROCESS_STATE_SERVICE;
17628            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17629        } else {
17630            // As far as we know the process is empty.  We may change our mind later.
17631            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17632            // At this point we don't actually know the adjustment.  Use the cached adj
17633            // value that the caller wants us to.
17634            adj = cachedAdj;
17635            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17636            app.cached = true;
17637            app.empty = true;
17638            app.adjType = "cch-empty";
17639        }
17640
17641        // Examine all activities if not already foreground.
17642        if (!foregroundActivities && activitiesSize > 0) {
17643            for (int j = 0; j < activitiesSize; j++) {
17644                final ActivityRecord r = app.activities.get(j);
17645                if (r.app != app) {
17646                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17647                            + app + "?!? Using " + r.app + " instead.");
17648                    continue;
17649                }
17650                if (r.visible) {
17651                    // App has a visible activity; only upgrade adjustment.
17652                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17653                        adj = ProcessList.VISIBLE_APP_ADJ;
17654                        app.adjType = "visible";
17655                    }
17656                    if (procState > PROCESS_STATE_TOP) {
17657                        procState = PROCESS_STATE_TOP;
17658                    }
17659                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17660                    app.cached = false;
17661                    app.empty = false;
17662                    foregroundActivities = true;
17663                    break;
17664                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17665                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17666                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17667                        app.adjType = "pausing";
17668                    }
17669                    if (procState > PROCESS_STATE_TOP) {
17670                        procState = PROCESS_STATE_TOP;
17671                    }
17672                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17673                    app.cached = false;
17674                    app.empty = false;
17675                    foregroundActivities = true;
17676                } else if (r.state == ActivityState.STOPPING) {
17677                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17678                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17679                        app.adjType = "stopping";
17680                    }
17681                    // For the process state, we will at this point consider the
17682                    // process to be cached.  It will be cached either as an activity
17683                    // or empty depending on whether the activity is finishing.  We do
17684                    // this so that we can treat the process as cached for purposes of
17685                    // memory trimming (determing current memory level, trim command to
17686                    // send to process) since there can be an arbitrary number of stopping
17687                    // processes and they should soon all go into the cached state.
17688                    if (!r.finishing) {
17689                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17690                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17691                        }
17692                    }
17693                    app.cached = false;
17694                    app.empty = false;
17695                    foregroundActivities = true;
17696                } else {
17697                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17698                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17699                        app.adjType = "cch-act";
17700                    }
17701                }
17702            }
17703        }
17704
17705        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17706            if (app.foregroundServices) {
17707                // The user is aware of this app, so make it visible.
17708                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17709                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17710                app.cached = false;
17711                app.adjType = "fg-service";
17712                schedGroup = Process.THREAD_GROUP_DEFAULT;
17713            } else if (app.forcingToForeground != null) {
17714                // The user is aware of this app, so make it visible.
17715                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17716                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17717                app.cached = false;
17718                app.adjType = "force-fg";
17719                app.adjSource = app.forcingToForeground;
17720                schedGroup = Process.THREAD_GROUP_DEFAULT;
17721            }
17722        }
17723
17724        if (app == mHeavyWeightProcess) {
17725            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17726                // We don't want to kill the current heavy-weight process.
17727                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17728                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17729                app.cached = false;
17730                app.adjType = "heavy";
17731            }
17732            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17733                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17734            }
17735        }
17736
17737        if (app == mHomeProcess) {
17738            if (adj > ProcessList.HOME_APP_ADJ) {
17739                // This process is hosting what we currently consider to be the
17740                // home app, so we don't want to let it go into the background.
17741                adj = ProcessList.HOME_APP_ADJ;
17742                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17743                app.cached = false;
17744                app.adjType = "home";
17745            }
17746            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17747                procState = ActivityManager.PROCESS_STATE_HOME;
17748            }
17749        }
17750
17751        if (app == mPreviousProcess && app.activities.size() > 0) {
17752            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17753                // This was the previous process that showed UI to the user.
17754                // We want to try to keep it around more aggressively, to give
17755                // a good experience around switching between two apps.
17756                adj = ProcessList.PREVIOUS_APP_ADJ;
17757                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17758                app.cached = false;
17759                app.adjType = "previous";
17760            }
17761            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17762                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17763            }
17764        }
17765
17766        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17767                + " reason=" + app.adjType);
17768
17769        // By default, we use the computed adjustment.  It may be changed if
17770        // there are applications dependent on our services or providers, but
17771        // this gives us a baseline and makes sure we don't get into an
17772        // infinite recursion.
17773        app.adjSeq = mAdjSeq;
17774        app.curRawAdj = adj;
17775        app.hasStartedServices = false;
17776
17777        if (mBackupTarget != null && app == mBackupTarget.app) {
17778            // If possible we want to avoid killing apps while they're being backed up
17779            if (adj > ProcessList.BACKUP_APP_ADJ) {
17780                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17781                adj = ProcessList.BACKUP_APP_ADJ;
17782                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17783                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17784                }
17785                app.adjType = "backup";
17786                app.cached = false;
17787            }
17788            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17789                procState = ActivityManager.PROCESS_STATE_BACKUP;
17790            }
17791        }
17792
17793        boolean mayBeTop = false;
17794
17795        for (int is = app.services.size()-1;
17796                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17797                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17798                        || procState > ActivityManager.PROCESS_STATE_TOP);
17799                is--) {
17800            ServiceRecord s = app.services.valueAt(is);
17801            if (s.startRequested) {
17802                app.hasStartedServices = true;
17803                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17804                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17805                }
17806                if (app.hasShownUi && app != mHomeProcess) {
17807                    // If this process has shown some UI, let it immediately
17808                    // go to the LRU list because it may be pretty heavy with
17809                    // UI stuff.  We'll tag it with a label just to help
17810                    // debug and understand what is going on.
17811                    if (adj > ProcessList.SERVICE_ADJ) {
17812                        app.adjType = "cch-started-ui-services";
17813                    }
17814                } else {
17815                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17816                        // This service has seen some activity within
17817                        // recent memory, so we will keep its process ahead
17818                        // of the background processes.
17819                        if (adj > ProcessList.SERVICE_ADJ) {
17820                            adj = ProcessList.SERVICE_ADJ;
17821                            app.adjType = "started-services";
17822                            app.cached = false;
17823                        }
17824                    }
17825                    // If we have let the service slide into the background
17826                    // state, still have some text describing what it is doing
17827                    // even though the service no longer has an impact.
17828                    if (adj > ProcessList.SERVICE_ADJ) {
17829                        app.adjType = "cch-started-services";
17830                    }
17831                }
17832            }
17833            for (int conni = s.connections.size()-1;
17834                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17835                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17836                            || procState > ActivityManager.PROCESS_STATE_TOP);
17837                    conni--) {
17838                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17839                for (int i = 0;
17840                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17841                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17842                                || procState > ActivityManager.PROCESS_STATE_TOP);
17843                        i++) {
17844                    // XXX should compute this based on the max of
17845                    // all connected clients.
17846                    ConnectionRecord cr = clist.get(i);
17847                    if (cr.binding.client == app) {
17848                        // Binding to ourself is not interesting.
17849                        continue;
17850                    }
17851                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17852                        ProcessRecord client = cr.binding.client;
17853                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17854                                TOP_APP, doingAll, now);
17855                        int clientProcState = client.curProcState;
17856                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17857                            // If the other app is cached for any reason, for purposes here
17858                            // we are going to consider it empty.  The specific cached state
17859                            // doesn't propagate except under certain conditions.
17860                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17861                        }
17862                        String adjType = null;
17863                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17864                            // Not doing bind OOM management, so treat
17865                            // this guy more like a started service.
17866                            if (app.hasShownUi && app != mHomeProcess) {
17867                                // If this process has shown some UI, let it immediately
17868                                // go to the LRU list because it may be pretty heavy with
17869                                // UI stuff.  We'll tag it with a label just to help
17870                                // debug and understand what is going on.
17871                                if (adj > clientAdj) {
17872                                    adjType = "cch-bound-ui-services";
17873                                }
17874                                app.cached = false;
17875                                clientAdj = adj;
17876                                clientProcState = procState;
17877                            } else {
17878                                if (now >= (s.lastActivity
17879                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17880                                    // This service has not seen activity within
17881                                    // recent memory, so allow it to drop to the
17882                                    // LRU list if there is no other reason to keep
17883                                    // it around.  We'll also tag it with a label just
17884                                    // to help debug and undertand what is going on.
17885                                    if (adj > clientAdj) {
17886                                        adjType = "cch-bound-services";
17887                                    }
17888                                    clientAdj = adj;
17889                                }
17890                            }
17891                        }
17892                        if (adj > clientAdj) {
17893                            // If this process has recently shown UI, and
17894                            // the process that is binding to it is less
17895                            // important than being visible, then we don't
17896                            // care about the binding as much as we care
17897                            // about letting this process get into the LRU
17898                            // list to be killed and restarted if needed for
17899                            // memory.
17900                            if (app.hasShownUi && app != mHomeProcess
17901                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17902                                adjType = "cch-bound-ui-services";
17903                            } else {
17904                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17905                                        |Context.BIND_IMPORTANT)) != 0) {
17906                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17907                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17908                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17909                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17910                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17911                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17912                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17913                                    adj = clientAdj;
17914                                } else {
17915                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17916                                        adj = ProcessList.VISIBLE_APP_ADJ;
17917                                    }
17918                                }
17919                                if (!client.cached) {
17920                                    app.cached = false;
17921                                }
17922                                adjType = "service";
17923                            }
17924                        }
17925                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17926                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17927                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17928                            }
17929                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17930                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17931                                    // Special handling of clients who are in the top state.
17932                                    // We *may* want to consider this process to be in the
17933                                    // top state as well, but only if there is not another
17934                                    // reason for it to be running.  Being on the top is a
17935                                    // special state, meaning you are specifically running
17936                                    // for the current top app.  If the process is already
17937                                    // running in the background for some other reason, it
17938                                    // is more important to continue considering it to be
17939                                    // in the background state.
17940                                    mayBeTop = true;
17941                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17942                                } else {
17943                                    // Special handling for above-top states (persistent
17944                                    // processes).  These should not bring the current process
17945                                    // into the top state, since they are not on top.  Instead
17946                                    // give them the best state after that.
17947                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17948                                        clientProcState =
17949                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17950                                    } else if (mWakefulness
17951                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17952                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17953                                                    != 0) {
17954                                        clientProcState =
17955                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17956                                    } else {
17957                                        clientProcState =
17958                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17959                                    }
17960                                }
17961                            }
17962                        } else {
17963                            if (clientProcState <
17964                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17965                                clientProcState =
17966                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17967                            }
17968                        }
17969                        if (procState > clientProcState) {
17970                            procState = clientProcState;
17971                        }
17972                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17973                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17974                            app.pendingUiClean = true;
17975                        }
17976                        if (adjType != null) {
17977                            app.adjType = adjType;
17978                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17979                                    .REASON_SERVICE_IN_USE;
17980                            app.adjSource = cr.binding.client;
17981                            app.adjSourceProcState = clientProcState;
17982                            app.adjTarget = s.name;
17983                        }
17984                    }
17985                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17986                        app.treatLikeActivity = true;
17987                    }
17988                    final ActivityRecord a = cr.activity;
17989                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17990                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17991                                (a.visible || a.state == ActivityState.RESUMED
17992                                 || a.state == ActivityState.PAUSING)) {
17993                            adj = ProcessList.FOREGROUND_APP_ADJ;
17994                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17995                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17996                            }
17997                            app.cached = false;
17998                            app.adjType = "service";
17999                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18000                                    .REASON_SERVICE_IN_USE;
18001                            app.adjSource = a;
18002                            app.adjSourceProcState = procState;
18003                            app.adjTarget = s.name;
18004                        }
18005                    }
18006                }
18007            }
18008        }
18009
18010        for (int provi = app.pubProviders.size()-1;
18011                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18012                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18013                        || procState > ActivityManager.PROCESS_STATE_TOP);
18014                provi--) {
18015            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18016            for (int i = cpr.connections.size()-1;
18017                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18018                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18019                            || procState > ActivityManager.PROCESS_STATE_TOP);
18020                    i--) {
18021                ContentProviderConnection conn = cpr.connections.get(i);
18022                ProcessRecord client = conn.client;
18023                if (client == app) {
18024                    // Being our own client is not interesting.
18025                    continue;
18026                }
18027                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18028                int clientProcState = client.curProcState;
18029                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18030                    // If the other app is cached for any reason, for purposes here
18031                    // we are going to consider it empty.
18032                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18033                }
18034                if (adj > clientAdj) {
18035                    if (app.hasShownUi && app != mHomeProcess
18036                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18037                        app.adjType = "cch-ui-provider";
18038                    } else {
18039                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18040                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18041                        app.adjType = "provider";
18042                    }
18043                    app.cached &= client.cached;
18044                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18045                            .REASON_PROVIDER_IN_USE;
18046                    app.adjSource = client;
18047                    app.adjSourceProcState = clientProcState;
18048                    app.adjTarget = cpr.name;
18049                }
18050                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18051                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18052                        // Special handling of clients who are in the top state.
18053                        // We *may* want to consider this process to be in the
18054                        // top state as well, but only if there is not another
18055                        // reason for it to be running.  Being on the top is a
18056                        // special state, meaning you are specifically running
18057                        // for the current top app.  If the process is already
18058                        // running in the background for some other reason, it
18059                        // is more important to continue considering it to be
18060                        // in the background state.
18061                        mayBeTop = true;
18062                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18063                    } else {
18064                        // Special handling for above-top states (persistent
18065                        // processes).  These should not bring the current process
18066                        // into the top state, since they are not on top.  Instead
18067                        // give them the best state after that.
18068                        clientProcState =
18069                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18070                    }
18071                }
18072                if (procState > clientProcState) {
18073                    procState = clientProcState;
18074                }
18075                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18076                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18077                }
18078            }
18079            // If the provider has external (non-framework) process
18080            // dependencies, ensure that its adjustment is at least
18081            // FOREGROUND_APP_ADJ.
18082            if (cpr.hasExternalProcessHandles()) {
18083                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18084                    adj = ProcessList.FOREGROUND_APP_ADJ;
18085                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18086                    app.cached = false;
18087                    app.adjType = "provider";
18088                    app.adjTarget = cpr.name;
18089                }
18090                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18091                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18092                }
18093            }
18094        }
18095
18096        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18097            // A client of one of our services or providers is in the top state.  We
18098            // *may* want to be in the top state, but not if we are already running in
18099            // the background for some other reason.  For the decision here, we are going
18100            // to pick out a few specific states that we want to remain in when a client
18101            // is top (states that tend to be longer-term) and otherwise allow it to go
18102            // to the top state.
18103            switch (procState) {
18104                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18105                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18106                case ActivityManager.PROCESS_STATE_SERVICE:
18107                    // These all are longer-term states, so pull them up to the top
18108                    // of the background states, but not all the way to the top state.
18109                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18110                    break;
18111                default:
18112                    // Otherwise, top is a better choice, so take it.
18113                    procState = ActivityManager.PROCESS_STATE_TOP;
18114                    break;
18115            }
18116        }
18117
18118        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18119            if (app.hasClientActivities) {
18120                // This is a cached process, but with client activities.  Mark it so.
18121                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18122                app.adjType = "cch-client-act";
18123            } else if (app.treatLikeActivity) {
18124                // This is a cached process, but somebody wants us to treat it like it has
18125                // an activity, okay!
18126                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18127                app.adjType = "cch-as-act";
18128            }
18129        }
18130
18131        if (adj == ProcessList.SERVICE_ADJ) {
18132            if (doingAll) {
18133                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18134                mNewNumServiceProcs++;
18135                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18136                if (!app.serviceb) {
18137                    // This service isn't far enough down on the LRU list to
18138                    // normally be a B service, but if we are low on RAM and it
18139                    // is large we want to force it down since we would prefer to
18140                    // keep launcher over it.
18141                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18142                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18143                        app.serviceHighRam = true;
18144                        app.serviceb = true;
18145                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18146                    } else {
18147                        mNewNumAServiceProcs++;
18148                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18149                    }
18150                } else {
18151                    app.serviceHighRam = false;
18152                }
18153            }
18154            if (app.serviceb) {
18155                adj = ProcessList.SERVICE_B_ADJ;
18156            }
18157        }
18158
18159        app.curRawAdj = adj;
18160
18161        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18162        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18163        if (adj > app.maxAdj) {
18164            adj = app.maxAdj;
18165            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18166                schedGroup = Process.THREAD_GROUP_DEFAULT;
18167            }
18168        }
18169
18170        // Do final modification to adj.  Everything we do between here and applying
18171        // the final setAdj must be done in this function, because we will also use
18172        // it when computing the final cached adj later.  Note that we don't need to
18173        // worry about this for max adj above, since max adj will always be used to
18174        // keep it out of the cached vaues.
18175        app.curAdj = app.modifyRawOomAdj(adj);
18176        app.curSchedGroup = schedGroup;
18177        app.curProcState = procState;
18178        app.foregroundActivities = foregroundActivities;
18179
18180        return app.curRawAdj;
18181    }
18182
18183    /**
18184     * Record new PSS sample for a process.
18185     */
18186    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18187        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18188        proc.lastPssTime = now;
18189        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18190        if (DEBUG_PSS) Slog.d(TAG_PSS,
18191                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18192                + " state=" + ProcessList.makeProcStateString(procState));
18193        if (proc.initialIdlePss == 0) {
18194            proc.initialIdlePss = pss;
18195        }
18196        proc.lastPss = pss;
18197        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18198            proc.lastCachedPss = pss;
18199        }
18200
18201        final SparseArray<Pair<Long, String>> watchUids
18202                = mMemWatchProcesses.getMap().get(proc.processName);
18203        Long check = null;
18204        if (watchUids != null) {
18205            Pair<Long, String> val = watchUids.get(proc.uid);
18206            if (val == null) {
18207                val = watchUids.get(0);
18208            }
18209            if (val != null) {
18210                check = val.first;
18211            }
18212        }
18213        if (check != null) {
18214            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18215                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18216                if (!isDebuggable) {
18217                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18218                        isDebuggable = true;
18219                    }
18220                }
18221                if (isDebuggable) {
18222                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18223                    final ProcessRecord myProc = proc;
18224                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18225                    mMemWatchDumpProcName = proc.processName;
18226                    mMemWatchDumpFile = heapdumpFile.toString();
18227                    mMemWatchDumpPid = proc.pid;
18228                    mMemWatchDumpUid = proc.uid;
18229                    BackgroundThread.getHandler().post(new Runnable() {
18230                        @Override
18231                        public void run() {
18232                            revokeUriPermission(ActivityThread.currentActivityThread()
18233                                            .getApplicationThread(),
18234                                    DumpHeapActivity.JAVA_URI,
18235                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18236                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18237                                    UserHandle.myUserId());
18238                            ParcelFileDescriptor fd = null;
18239                            try {
18240                                heapdumpFile.delete();
18241                                fd = ParcelFileDescriptor.open(heapdumpFile,
18242                                        ParcelFileDescriptor.MODE_CREATE |
18243                                                ParcelFileDescriptor.MODE_TRUNCATE |
18244                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18245                                                ParcelFileDescriptor.MODE_APPEND);
18246                                IApplicationThread thread = myProc.thread;
18247                                if (thread != null) {
18248                                    try {
18249                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18250                                                "Requesting dump heap from "
18251                                                + myProc + " to " + heapdumpFile);
18252                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18253                                    } catch (RemoteException e) {
18254                                    }
18255                                }
18256                            } catch (FileNotFoundException e) {
18257                                e.printStackTrace();
18258                            } finally {
18259                                if (fd != null) {
18260                                    try {
18261                                        fd.close();
18262                                    } catch (IOException e) {
18263                                    }
18264                                }
18265                            }
18266                        }
18267                    });
18268                } else {
18269                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18270                            + ", but debugging not enabled");
18271                }
18272            }
18273        }
18274    }
18275
18276    /**
18277     * Schedule PSS collection of a process.
18278     */
18279    void requestPssLocked(ProcessRecord proc, int procState) {
18280        if (mPendingPssProcesses.contains(proc)) {
18281            return;
18282        }
18283        if (mPendingPssProcesses.size() == 0) {
18284            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18285        }
18286        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18287        proc.pssProcState = procState;
18288        mPendingPssProcesses.add(proc);
18289    }
18290
18291    /**
18292     * Schedule PSS collection of all processes.
18293     */
18294    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18295        if (!always) {
18296            if (now < (mLastFullPssTime +
18297                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18298                return;
18299            }
18300        }
18301        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18302        mLastFullPssTime = now;
18303        mFullPssPending = true;
18304        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18305        mPendingPssProcesses.clear();
18306        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18307            ProcessRecord app = mLruProcesses.get(i);
18308            if (app.thread == null
18309                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18310                continue;
18311            }
18312            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18313                app.pssProcState = app.setProcState;
18314                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18315                        mTestPssMode, isSleeping(), now);
18316                mPendingPssProcesses.add(app);
18317            }
18318        }
18319        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18320    }
18321
18322    public void setTestPssMode(boolean enabled) {
18323        synchronized (this) {
18324            mTestPssMode = enabled;
18325            if (enabled) {
18326                // Whenever we enable the mode, we want to take a snapshot all of current
18327                // process mem use.
18328                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18329            }
18330        }
18331    }
18332
18333    /**
18334     * Ask a given process to GC right now.
18335     */
18336    final void performAppGcLocked(ProcessRecord app) {
18337        try {
18338            app.lastRequestedGc = SystemClock.uptimeMillis();
18339            if (app.thread != null) {
18340                if (app.reportLowMemory) {
18341                    app.reportLowMemory = false;
18342                    app.thread.scheduleLowMemory();
18343                } else {
18344                    app.thread.processInBackground();
18345                }
18346            }
18347        } catch (Exception e) {
18348            // whatever.
18349        }
18350    }
18351
18352    /**
18353     * Returns true if things are idle enough to perform GCs.
18354     */
18355    private final boolean canGcNowLocked() {
18356        boolean processingBroadcasts = false;
18357        for (BroadcastQueue q : mBroadcastQueues) {
18358            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18359                processingBroadcasts = true;
18360            }
18361        }
18362        return !processingBroadcasts
18363                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18364    }
18365
18366    /**
18367     * Perform GCs on all processes that are waiting for it, but only
18368     * if things are idle.
18369     */
18370    final void performAppGcsLocked() {
18371        final int N = mProcessesToGc.size();
18372        if (N <= 0) {
18373            return;
18374        }
18375        if (canGcNowLocked()) {
18376            while (mProcessesToGc.size() > 0) {
18377                ProcessRecord proc = mProcessesToGc.remove(0);
18378                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18379                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18380                            <= SystemClock.uptimeMillis()) {
18381                        // To avoid spamming the system, we will GC processes one
18382                        // at a time, waiting a few seconds between each.
18383                        performAppGcLocked(proc);
18384                        scheduleAppGcsLocked();
18385                        return;
18386                    } else {
18387                        // It hasn't been long enough since we last GCed this
18388                        // process...  put it in the list to wait for its time.
18389                        addProcessToGcListLocked(proc);
18390                        break;
18391                    }
18392                }
18393            }
18394
18395            scheduleAppGcsLocked();
18396        }
18397    }
18398
18399    /**
18400     * If all looks good, perform GCs on all processes waiting for them.
18401     */
18402    final void performAppGcsIfAppropriateLocked() {
18403        if (canGcNowLocked()) {
18404            performAppGcsLocked();
18405            return;
18406        }
18407        // Still not idle, wait some more.
18408        scheduleAppGcsLocked();
18409    }
18410
18411    /**
18412     * Schedule the execution of all pending app GCs.
18413     */
18414    final void scheduleAppGcsLocked() {
18415        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18416
18417        if (mProcessesToGc.size() > 0) {
18418            // Schedule a GC for the time to the next process.
18419            ProcessRecord proc = mProcessesToGc.get(0);
18420            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18421
18422            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18423            long now = SystemClock.uptimeMillis();
18424            if (when < (now+GC_TIMEOUT)) {
18425                when = now + GC_TIMEOUT;
18426            }
18427            mHandler.sendMessageAtTime(msg, when);
18428        }
18429    }
18430
18431    /**
18432     * Add a process to the array of processes waiting to be GCed.  Keeps the
18433     * list in sorted order by the last GC time.  The process can't already be
18434     * on the list.
18435     */
18436    final void addProcessToGcListLocked(ProcessRecord proc) {
18437        boolean added = false;
18438        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18439            if (mProcessesToGc.get(i).lastRequestedGc <
18440                    proc.lastRequestedGc) {
18441                added = true;
18442                mProcessesToGc.add(i+1, proc);
18443                break;
18444            }
18445        }
18446        if (!added) {
18447            mProcessesToGc.add(0, proc);
18448        }
18449    }
18450
18451    /**
18452     * Set up to ask a process to GC itself.  This will either do it
18453     * immediately, or put it on the list of processes to gc the next
18454     * time things are idle.
18455     */
18456    final void scheduleAppGcLocked(ProcessRecord app) {
18457        long now = SystemClock.uptimeMillis();
18458        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18459            return;
18460        }
18461        if (!mProcessesToGc.contains(app)) {
18462            addProcessToGcListLocked(app);
18463            scheduleAppGcsLocked();
18464        }
18465    }
18466
18467    final void checkExcessivePowerUsageLocked(boolean doKills) {
18468        updateCpuStatsNow();
18469
18470        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18471        boolean doWakeKills = doKills;
18472        boolean doCpuKills = doKills;
18473        if (mLastPowerCheckRealtime == 0) {
18474            doWakeKills = false;
18475        }
18476        if (mLastPowerCheckUptime == 0) {
18477            doCpuKills = false;
18478        }
18479        if (stats.isScreenOn()) {
18480            doWakeKills = false;
18481        }
18482        final long curRealtime = SystemClock.elapsedRealtime();
18483        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18484        final long curUptime = SystemClock.uptimeMillis();
18485        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18486        mLastPowerCheckRealtime = curRealtime;
18487        mLastPowerCheckUptime = curUptime;
18488        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18489            doWakeKills = false;
18490        }
18491        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18492            doCpuKills = false;
18493        }
18494        int i = mLruProcesses.size();
18495        while (i > 0) {
18496            i--;
18497            ProcessRecord app = mLruProcesses.get(i);
18498            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18499                long wtime;
18500                synchronized (stats) {
18501                    wtime = stats.getProcessWakeTime(app.info.uid,
18502                            app.pid, curRealtime);
18503                }
18504                long wtimeUsed = wtime - app.lastWakeTime;
18505                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18506                if (DEBUG_POWER) {
18507                    StringBuilder sb = new StringBuilder(128);
18508                    sb.append("Wake for ");
18509                    app.toShortString(sb);
18510                    sb.append(": over ");
18511                    TimeUtils.formatDuration(realtimeSince, sb);
18512                    sb.append(" used ");
18513                    TimeUtils.formatDuration(wtimeUsed, sb);
18514                    sb.append(" (");
18515                    sb.append((wtimeUsed*100)/realtimeSince);
18516                    sb.append("%)");
18517                    Slog.i(TAG_POWER, sb.toString());
18518                    sb.setLength(0);
18519                    sb.append("CPU for ");
18520                    app.toShortString(sb);
18521                    sb.append(": over ");
18522                    TimeUtils.formatDuration(uptimeSince, sb);
18523                    sb.append(" used ");
18524                    TimeUtils.formatDuration(cputimeUsed, sb);
18525                    sb.append(" (");
18526                    sb.append((cputimeUsed*100)/uptimeSince);
18527                    sb.append("%)");
18528                    Slog.i(TAG_POWER, sb.toString());
18529                }
18530                // If a process has held a wake lock for more
18531                // than 50% of the time during this period,
18532                // that sounds bad.  Kill!
18533                if (doWakeKills && realtimeSince > 0
18534                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18535                    synchronized (stats) {
18536                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18537                                realtimeSince, wtimeUsed);
18538                    }
18539                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18540                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18541                } else if (doCpuKills && uptimeSince > 0
18542                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18543                    synchronized (stats) {
18544                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18545                                uptimeSince, cputimeUsed);
18546                    }
18547                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18548                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18549                } else {
18550                    app.lastWakeTime = wtime;
18551                    app.lastCpuTime = app.curCpuTime;
18552                }
18553            }
18554        }
18555    }
18556
18557    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18558        boolean success = true;
18559
18560        if (app.curRawAdj != app.setRawAdj) {
18561            app.setRawAdj = app.curRawAdj;
18562        }
18563
18564        int changes = 0;
18565
18566        if (app.curAdj != app.setAdj) {
18567            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18568            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18569                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18570                    + app.adjType);
18571            app.setAdj = app.curAdj;
18572        }
18573
18574        if (app.setSchedGroup != app.curSchedGroup) {
18575            app.setSchedGroup = app.curSchedGroup;
18576            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18577                    "Setting process group of " + app.processName
18578                    + " to " + app.curSchedGroup);
18579            if (app.waitingToKill != null && app.curReceiver == null
18580                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18581                app.kill(app.waitingToKill, true);
18582                success = false;
18583            } else {
18584                if (true) {
18585                    long oldId = Binder.clearCallingIdentity();
18586                    try {
18587                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18588                    } catch (Exception e) {
18589                        Slog.w(TAG, "Failed setting process group of " + app.pid
18590                                + " to " + app.curSchedGroup);
18591                        e.printStackTrace();
18592                    } finally {
18593                        Binder.restoreCallingIdentity(oldId);
18594                    }
18595                } else {
18596                    if (app.thread != null) {
18597                        try {
18598                            app.thread.setSchedulingGroup(app.curSchedGroup);
18599                        } catch (RemoteException e) {
18600                        }
18601                    }
18602                }
18603                Process.setSwappiness(app.pid,
18604                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18605            }
18606        }
18607        if (app.repForegroundActivities != app.foregroundActivities) {
18608            app.repForegroundActivities = app.foregroundActivities;
18609            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18610        }
18611        if (app.repProcState != app.curProcState) {
18612            app.repProcState = app.curProcState;
18613            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18614            if (app.thread != null) {
18615                try {
18616                    if (false) {
18617                        //RuntimeException h = new RuntimeException("here");
18618                        Slog.i(TAG, "Sending new process state " + app.repProcState
18619                                + " to " + app /*, h*/);
18620                    }
18621                    app.thread.setProcessState(app.repProcState);
18622                } catch (RemoteException e) {
18623                }
18624            }
18625        }
18626        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18627                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18628            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18629                // Experimental code to more aggressively collect pss while
18630                // running test...  the problem is that this tends to collect
18631                // the data right when a process is transitioning between process
18632                // states, which well tend to give noisy data.
18633                long start = SystemClock.uptimeMillis();
18634                long pss = Debug.getPss(app.pid, mTmpLong, null);
18635                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18636                mPendingPssProcesses.remove(app);
18637                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18638                        + " to " + app.curProcState + ": "
18639                        + (SystemClock.uptimeMillis()-start) + "ms");
18640            }
18641            app.lastStateTime = now;
18642            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18643                    mTestPssMode, isSleeping(), now);
18644            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18645                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18646                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18647                    + (app.nextPssTime-now) + ": " + app);
18648        } else {
18649            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18650                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18651                    mTestPssMode)))) {
18652                requestPssLocked(app, app.setProcState);
18653                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18654                        mTestPssMode, isSleeping(), now);
18655            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18656                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18657        }
18658        if (app.setProcState != app.curProcState) {
18659            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18660                    "Proc state change of " + app.processName
18661                    + " to " + app.curProcState);
18662            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18663            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18664            if (setImportant && !curImportant) {
18665                // This app is no longer something we consider important enough to allow to
18666                // use arbitrary amounts of battery power.  Note
18667                // its current wake lock time to later know to kill it if
18668                // it is not behaving well.
18669                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18670                synchronized (stats) {
18671                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18672                            app.pid, SystemClock.elapsedRealtime());
18673                }
18674                app.lastCpuTime = app.curCpuTime;
18675
18676            }
18677            // Inform UsageStats of important process state change
18678            // Must be called before updating setProcState
18679            maybeUpdateUsageStatsLocked(app);
18680
18681            app.setProcState = app.curProcState;
18682            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18683                app.notCachedSinceIdle = false;
18684            }
18685            if (!doingAll) {
18686                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18687            } else {
18688                app.procStateChanged = true;
18689            }
18690        }
18691
18692        if (changes != 0) {
18693            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18694                    "Changes in " + app + ": " + changes);
18695            int i = mPendingProcessChanges.size()-1;
18696            ProcessChangeItem item = null;
18697            while (i >= 0) {
18698                item = mPendingProcessChanges.get(i);
18699                if (item.pid == app.pid) {
18700                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18701                            "Re-using existing item: " + item);
18702                    break;
18703                }
18704                i--;
18705            }
18706            if (i < 0) {
18707                // No existing item in pending changes; need a new one.
18708                final int NA = mAvailProcessChanges.size();
18709                if (NA > 0) {
18710                    item = mAvailProcessChanges.remove(NA-1);
18711                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18712                            "Retrieving available item: " + item);
18713                } else {
18714                    item = new ProcessChangeItem();
18715                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18716                            "Allocating new item: " + item);
18717                }
18718                item.changes = 0;
18719                item.pid = app.pid;
18720                item.uid = app.info.uid;
18721                if (mPendingProcessChanges.size() == 0) {
18722                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18723                            "*** Enqueueing dispatch processes changed!");
18724                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18725                }
18726                mPendingProcessChanges.add(item);
18727            }
18728            item.changes |= changes;
18729            item.processState = app.repProcState;
18730            item.foregroundActivities = app.repForegroundActivities;
18731            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18732                    "Item " + Integer.toHexString(System.identityHashCode(item))
18733                    + " " + app.toShortString() + ": changes=" + item.changes
18734                    + " procState=" + item.processState
18735                    + " foreground=" + item.foregroundActivities
18736                    + " type=" + app.adjType + " source=" + app.adjSource
18737                    + " target=" + app.adjTarget);
18738        }
18739
18740        return success;
18741    }
18742
18743    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18744        if (uidRec.pendingChange == null) {
18745            if (mPendingUidChanges.size() == 0) {
18746                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18747                        "*** Enqueueing dispatch uid changed!");
18748                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18749            }
18750            final int NA = mAvailUidChanges.size();
18751            if (NA > 0) {
18752                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18753                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18754                        "Retrieving available item: " + uidRec.pendingChange);
18755            } else {
18756                uidRec.pendingChange = new UidRecord.ChangeItem();
18757                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18758                        "Allocating new item: " + uidRec.pendingChange);
18759            }
18760            uidRec.pendingChange.uidRecord = uidRec;
18761            uidRec.pendingChange.uid = uidRec.uid;
18762            mPendingUidChanges.add(uidRec.pendingChange);
18763        }
18764        uidRec.pendingChange.gone = gone;
18765        uidRec.pendingChange.processState = uidRec.setProcState;
18766    }
18767
18768    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18769            String authority) {
18770        if (app == null) return;
18771        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18772            UserState userState = mStartedUsers.get(app.userId);
18773            if (userState == null) return;
18774            final long now = SystemClock.elapsedRealtime();
18775            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18776            if (lastReported == null || lastReported < now - 60 * 1000L) {
18777                mUsageStatsService.reportContentProviderUsage(
18778                        authority, providerPkgName, app.userId);
18779                userState.mProviderLastReportedFg.put(authority, now);
18780            }
18781        }
18782    }
18783
18784    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18785        if (DEBUG_USAGE_STATS) {
18786            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18787                    + "] state changes: old = " + app.setProcState + ", new = "
18788                    + app.curProcState);
18789        }
18790        if (mUsageStatsService == null) {
18791            return;
18792        }
18793        boolean isInteraction;
18794        // To avoid some abuse patterns, we are going to be careful about what we consider
18795        // to be an app interaction.  Being the top activity doesn't count while the display
18796        // is sleeping, nor do short foreground services.
18797        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18798            isInteraction = true;
18799            app.fgInteractionTime = 0;
18800        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18801            final long now = SystemClock.elapsedRealtime();
18802            if (app.fgInteractionTime == 0) {
18803                app.fgInteractionTime = now;
18804                isInteraction = false;
18805            } else {
18806                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18807            }
18808        } else {
18809            isInteraction = app.curProcState
18810                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18811            app.fgInteractionTime = 0;
18812        }
18813        if (isInteraction && !app.reportedInteraction) {
18814            String[] packages = app.getPackageList();
18815            if (packages != null) {
18816                for (int i = 0; i < packages.length; i++) {
18817                    mUsageStatsService.reportEvent(packages[i], app.userId,
18818                            UsageEvents.Event.SYSTEM_INTERACTION);
18819                }
18820            }
18821        }
18822        app.reportedInteraction = isInteraction;
18823    }
18824
18825    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18826        if (proc.thread != null) {
18827            if (proc.baseProcessTracker != null) {
18828                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18829            }
18830            if (proc.repProcState >= 0) {
18831                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18832                        proc.repProcState);
18833            }
18834        }
18835    }
18836
18837    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18838            ProcessRecord TOP_APP, boolean doingAll, long now) {
18839        if (app.thread == null) {
18840            return false;
18841        }
18842
18843        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18844
18845        return applyOomAdjLocked(app, doingAll, now);
18846    }
18847
18848    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18849            boolean oomAdj) {
18850        if (isForeground != proc.foregroundServices) {
18851            proc.foregroundServices = isForeground;
18852            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18853                    proc.info.uid);
18854            if (isForeground) {
18855                if (curProcs == null) {
18856                    curProcs = new ArrayList<ProcessRecord>();
18857                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18858                }
18859                if (!curProcs.contains(proc)) {
18860                    curProcs.add(proc);
18861                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18862                            proc.info.packageName, proc.info.uid);
18863                }
18864            } else {
18865                if (curProcs != null) {
18866                    if (curProcs.remove(proc)) {
18867                        mBatteryStatsService.noteEvent(
18868                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18869                                proc.info.packageName, proc.info.uid);
18870                        if (curProcs.size() <= 0) {
18871                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18872                        }
18873                    }
18874                }
18875            }
18876            if (oomAdj) {
18877                updateOomAdjLocked();
18878            }
18879        }
18880    }
18881
18882    private final ActivityRecord resumedAppLocked() {
18883        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18884        String pkg;
18885        int uid;
18886        if (act != null) {
18887            pkg = act.packageName;
18888            uid = act.info.applicationInfo.uid;
18889        } else {
18890            pkg = null;
18891            uid = -1;
18892        }
18893        // Has the UID or resumed package name changed?
18894        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18895                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18896            if (mCurResumedPackage != null) {
18897                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18898                        mCurResumedPackage, mCurResumedUid);
18899            }
18900            mCurResumedPackage = pkg;
18901            mCurResumedUid = uid;
18902            if (mCurResumedPackage != null) {
18903                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18904                        mCurResumedPackage, mCurResumedUid);
18905            }
18906        }
18907        return act;
18908    }
18909
18910    final boolean updateOomAdjLocked(ProcessRecord app) {
18911        final ActivityRecord TOP_ACT = resumedAppLocked();
18912        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18913        final boolean wasCached = app.cached;
18914
18915        mAdjSeq++;
18916
18917        // This is the desired cached adjusment we want to tell it to use.
18918        // If our app is currently cached, we know it, and that is it.  Otherwise,
18919        // we don't know it yet, and it needs to now be cached we will then
18920        // need to do a complete oom adj.
18921        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18922                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18923        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18924                SystemClock.uptimeMillis());
18925        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18926            // Changed to/from cached state, so apps after it in the LRU
18927            // list may also be changed.
18928            updateOomAdjLocked();
18929        }
18930        return success;
18931    }
18932
18933    final void updateOomAdjLocked() {
18934        final ActivityRecord TOP_ACT = resumedAppLocked();
18935        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18936        final long now = SystemClock.uptimeMillis();
18937        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18938        final int N = mLruProcesses.size();
18939
18940        if (false) {
18941            RuntimeException e = new RuntimeException();
18942            e.fillInStackTrace();
18943            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18944        }
18945
18946        // Reset state in all uid records.
18947        for (int i=mActiveUids.size()-1; i>=0; i--) {
18948            final UidRecord uidRec = mActiveUids.valueAt(i);
18949            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18950                    "Starting update of " + uidRec);
18951            uidRec.reset();
18952        }
18953
18954        mAdjSeq++;
18955        mNewNumServiceProcs = 0;
18956        mNewNumAServiceProcs = 0;
18957
18958        final int emptyProcessLimit;
18959        final int cachedProcessLimit;
18960        if (mProcessLimit <= 0) {
18961            emptyProcessLimit = cachedProcessLimit = 0;
18962        } else if (mProcessLimit == 1) {
18963            emptyProcessLimit = 1;
18964            cachedProcessLimit = 0;
18965        } else {
18966            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18967            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18968        }
18969
18970        // Let's determine how many processes we have running vs.
18971        // how many slots we have for background processes; we may want
18972        // to put multiple processes in a slot of there are enough of
18973        // them.
18974        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18975                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18976        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18977        if (numEmptyProcs > cachedProcessLimit) {
18978            // If there are more empty processes than our limit on cached
18979            // processes, then use the cached process limit for the factor.
18980            // This ensures that the really old empty processes get pushed
18981            // down to the bottom, so if we are running low on memory we will
18982            // have a better chance at keeping around more cached processes
18983            // instead of a gazillion empty processes.
18984            numEmptyProcs = cachedProcessLimit;
18985        }
18986        int emptyFactor = numEmptyProcs/numSlots;
18987        if (emptyFactor < 1) emptyFactor = 1;
18988        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18989        if (cachedFactor < 1) cachedFactor = 1;
18990        int stepCached = 0;
18991        int stepEmpty = 0;
18992        int numCached = 0;
18993        int numEmpty = 0;
18994        int numTrimming = 0;
18995
18996        mNumNonCachedProcs = 0;
18997        mNumCachedHiddenProcs = 0;
18998
18999        // First update the OOM adjustment for each of the
19000        // application processes based on their current state.
19001        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19002        int nextCachedAdj = curCachedAdj+1;
19003        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19004        int nextEmptyAdj = curEmptyAdj+2;
19005        for (int i=N-1; i>=0; i--) {
19006            ProcessRecord app = mLruProcesses.get(i);
19007            if (!app.killedByAm && app.thread != null) {
19008                app.procStateChanged = false;
19009                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19010
19011                // If we haven't yet assigned the final cached adj
19012                // to the process, do that now.
19013                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19014                    switch (app.curProcState) {
19015                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19016                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19017                            // This process is a cached process holding activities...
19018                            // assign it the next cached value for that type, and then
19019                            // step that cached level.
19020                            app.curRawAdj = curCachedAdj;
19021                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19022                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19023                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19024                                    + ")");
19025                            if (curCachedAdj != nextCachedAdj) {
19026                                stepCached++;
19027                                if (stepCached >= cachedFactor) {
19028                                    stepCached = 0;
19029                                    curCachedAdj = nextCachedAdj;
19030                                    nextCachedAdj += 2;
19031                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19032                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19033                                    }
19034                                }
19035                            }
19036                            break;
19037                        default:
19038                            // For everything else, assign next empty cached process
19039                            // level and bump that up.  Note that this means that
19040                            // long-running services that have dropped down to the
19041                            // cached level will be treated as empty (since their process
19042                            // state is still as a service), which is what we want.
19043                            app.curRawAdj = curEmptyAdj;
19044                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19045                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19046                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19047                                    + ")");
19048                            if (curEmptyAdj != nextEmptyAdj) {
19049                                stepEmpty++;
19050                                if (stepEmpty >= emptyFactor) {
19051                                    stepEmpty = 0;
19052                                    curEmptyAdj = nextEmptyAdj;
19053                                    nextEmptyAdj += 2;
19054                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19055                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19056                                    }
19057                                }
19058                            }
19059                            break;
19060                    }
19061                }
19062
19063                applyOomAdjLocked(app, true, now);
19064
19065                // Count the number of process types.
19066                switch (app.curProcState) {
19067                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19068                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19069                        mNumCachedHiddenProcs++;
19070                        numCached++;
19071                        if (numCached > cachedProcessLimit) {
19072                            app.kill("cached #" + numCached, true);
19073                        }
19074                        break;
19075                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19076                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19077                                && app.lastActivityTime < oldTime) {
19078                            app.kill("empty for "
19079                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19080                                    / 1000) + "s", true);
19081                        } else {
19082                            numEmpty++;
19083                            if (numEmpty > emptyProcessLimit) {
19084                                app.kill("empty #" + numEmpty, true);
19085                            }
19086                        }
19087                        break;
19088                    default:
19089                        mNumNonCachedProcs++;
19090                        break;
19091                }
19092
19093                if (app.isolated && app.services.size() <= 0) {
19094                    // If this is an isolated process, and there are no
19095                    // services running in it, then the process is no longer
19096                    // needed.  We agressively kill these because we can by
19097                    // definition not re-use the same process again, and it is
19098                    // good to avoid having whatever code was running in them
19099                    // left sitting around after no longer needed.
19100                    app.kill("isolated not needed", true);
19101                } else {
19102                    // Keeping this process, update its uid.
19103                    final UidRecord uidRec = app.uidRecord;
19104                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19105                        uidRec.curProcState = app.curProcState;
19106                    }
19107                }
19108
19109                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19110                        && !app.killedByAm) {
19111                    numTrimming++;
19112                }
19113            }
19114        }
19115
19116        mNumServiceProcs = mNewNumServiceProcs;
19117
19118        // Now determine the memory trimming level of background processes.
19119        // Unfortunately we need to start at the back of the list to do this
19120        // properly.  We only do this if the number of background apps we
19121        // are managing to keep around is less than half the maximum we desire;
19122        // if we are keeping a good number around, we'll let them use whatever
19123        // memory they want.
19124        final int numCachedAndEmpty = numCached + numEmpty;
19125        int memFactor;
19126        if (numCached <= ProcessList.TRIM_CACHED_APPS
19127                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19128            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19129                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19130            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19131                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19132            } else {
19133                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19134            }
19135        } else {
19136            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19137        }
19138        // We always allow the memory level to go up (better).  We only allow it to go
19139        // down if we are in a state where that is allowed, *and* the total number of processes
19140        // has gone down since last time.
19141        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19142                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19143                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19144        if (memFactor > mLastMemoryLevel) {
19145            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19146                memFactor = mLastMemoryLevel;
19147                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19148            }
19149        }
19150        mLastMemoryLevel = memFactor;
19151        mLastNumProcesses = mLruProcesses.size();
19152        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19153        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19154        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19155            if (mLowRamStartTime == 0) {
19156                mLowRamStartTime = now;
19157            }
19158            int step = 0;
19159            int fgTrimLevel;
19160            switch (memFactor) {
19161                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19162                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19163                    break;
19164                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19165                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19166                    break;
19167                default:
19168                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19169                    break;
19170            }
19171            int factor = numTrimming/3;
19172            int minFactor = 2;
19173            if (mHomeProcess != null) minFactor++;
19174            if (mPreviousProcess != null) minFactor++;
19175            if (factor < minFactor) factor = minFactor;
19176            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19177            for (int i=N-1; i>=0; i--) {
19178                ProcessRecord app = mLruProcesses.get(i);
19179                if (allChanged || app.procStateChanged) {
19180                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19181                    app.procStateChanged = false;
19182                }
19183                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19184                        && !app.killedByAm) {
19185                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19186                        try {
19187                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19188                                    "Trimming memory of " + app.processName + " to " + curLevel);
19189                            app.thread.scheduleTrimMemory(curLevel);
19190                        } catch (RemoteException e) {
19191                        }
19192                        if (false) {
19193                            // For now we won't do this; our memory trimming seems
19194                            // to be good enough at this point that destroying
19195                            // activities causes more harm than good.
19196                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19197                                    && app != mHomeProcess && app != mPreviousProcess) {
19198                                // Need to do this on its own message because the stack may not
19199                                // be in a consistent state at this point.
19200                                // For these apps we will also finish their activities
19201                                // to help them free memory.
19202                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19203                            }
19204                        }
19205                    }
19206                    app.trimMemoryLevel = curLevel;
19207                    step++;
19208                    if (step >= factor) {
19209                        step = 0;
19210                        switch (curLevel) {
19211                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19212                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19213                                break;
19214                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19215                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19216                                break;
19217                        }
19218                    }
19219                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19220                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19221                            && app.thread != null) {
19222                        try {
19223                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19224                                    "Trimming memory of heavy-weight " + app.processName
19225                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19226                            app.thread.scheduleTrimMemory(
19227                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19228                        } catch (RemoteException e) {
19229                        }
19230                    }
19231                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19232                } else {
19233                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19234                            || app.systemNoUi) && app.pendingUiClean) {
19235                        // If this application is now in the background and it
19236                        // had done UI, then give it the special trim level to
19237                        // have it free UI resources.
19238                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19239                        if (app.trimMemoryLevel < level && app.thread != null) {
19240                            try {
19241                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19242                                        "Trimming memory of bg-ui " + app.processName
19243                                        + " to " + level);
19244                                app.thread.scheduleTrimMemory(level);
19245                            } catch (RemoteException e) {
19246                            }
19247                        }
19248                        app.pendingUiClean = false;
19249                    }
19250                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19251                        try {
19252                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19253                                    "Trimming memory of fg " + app.processName
19254                                    + " to " + fgTrimLevel);
19255                            app.thread.scheduleTrimMemory(fgTrimLevel);
19256                        } catch (RemoteException e) {
19257                        }
19258                    }
19259                    app.trimMemoryLevel = fgTrimLevel;
19260                }
19261            }
19262        } else {
19263            if (mLowRamStartTime != 0) {
19264                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19265                mLowRamStartTime = 0;
19266            }
19267            for (int i=N-1; i>=0; i--) {
19268                ProcessRecord app = mLruProcesses.get(i);
19269                if (allChanged || app.procStateChanged) {
19270                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19271                    app.procStateChanged = false;
19272                }
19273                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19274                        || app.systemNoUi) && app.pendingUiClean) {
19275                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19276                            && app.thread != null) {
19277                        try {
19278                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19279                                    "Trimming memory of ui hidden " + app.processName
19280                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19281                            app.thread.scheduleTrimMemory(
19282                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19283                        } catch (RemoteException e) {
19284                        }
19285                    }
19286                    app.pendingUiClean = false;
19287                }
19288                app.trimMemoryLevel = 0;
19289            }
19290        }
19291
19292        if (mAlwaysFinishActivities) {
19293            // Need to do this on its own message because the stack may not
19294            // be in a consistent state at this point.
19295            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19296        }
19297
19298        if (allChanged) {
19299            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19300        }
19301
19302        // Update from any uid changes.
19303        for (int i=mActiveUids.size()-1; i>=0; i--) {
19304            final UidRecord uidRec = mActiveUids.valueAt(i);
19305            if (uidRec.setProcState != uidRec.curProcState) {
19306                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19307                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19308                        + " to " + uidRec.curProcState);
19309                uidRec.setProcState = uidRec.curProcState;
19310                enqueueUidChangeLocked(uidRec, false);
19311            }
19312        }
19313
19314        if (mProcessStats.shouldWriteNowLocked(now)) {
19315            mHandler.post(new Runnable() {
19316                @Override public void run() {
19317                    synchronized (ActivityManagerService.this) {
19318                        mProcessStats.writeStateAsyncLocked();
19319                    }
19320                }
19321            });
19322        }
19323
19324        if (DEBUG_OOM_ADJ) {
19325            final long duration = SystemClock.uptimeMillis() - now;
19326            if (false) {
19327                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19328                        new RuntimeException("here").fillInStackTrace());
19329            } else {
19330                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19331            }
19332        }
19333    }
19334
19335    final void trimApplications() {
19336        synchronized (this) {
19337            int i;
19338
19339            // First remove any unused application processes whose package
19340            // has been removed.
19341            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19342                final ProcessRecord app = mRemovedProcesses.get(i);
19343                if (app.activities.size() == 0
19344                        && app.curReceiver == null && app.services.size() == 0) {
19345                    Slog.i(
19346                        TAG, "Exiting empty application process "
19347                        + app.processName + " ("
19348                        + (app.thread != null ? app.thread.asBinder() : null)
19349                        + ")\n");
19350                    if (app.pid > 0 && app.pid != MY_PID) {
19351                        app.kill("empty", false);
19352                    } else {
19353                        try {
19354                            app.thread.scheduleExit();
19355                        } catch (Exception e) {
19356                            // Ignore exceptions.
19357                        }
19358                    }
19359                    cleanUpApplicationRecordLocked(app, false, true, -1);
19360                    mRemovedProcesses.remove(i);
19361
19362                    if (app.persistent) {
19363                        addAppLocked(app.info, false, null /* ABI override */);
19364                    }
19365                }
19366            }
19367
19368            // Now update the oom adj for all processes.
19369            updateOomAdjLocked();
19370        }
19371    }
19372
19373    /** This method sends the specified signal to each of the persistent apps */
19374    public void signalPersistentProcesses(int sig) throws RemoteException {
19375        if (sig != Process.SIGNAL_USR1) {
19376            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19377        }
19378
19379        synchronized (this) {
19380            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19381                    != PackageManager.PERMISSION_GRANTED) {
19382                throw new SecurityException("Requires permission "
19383                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19384            }
19385
19386            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19387                ProcessRecord r = mLruProcesses.get(i);
19388                if (r.thread != null && r.persistent) {
19389                    Process.sendSignal(r.pid, sig);
19390                }
19391            }
19392        }
19393    }
19394
19395    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19396        if (proc == null || proc == mProfileProc) {
19397            proc = mProfileProc;
19398            profileType = mProfileType;
19399            clearProfilerLocked();
19400        }
19401        if (proc == null) {
19402            return;
19403        }
19404        try {
19405            proc.thread.profilerControl(false, null, profileType);
19406        } catch (RemoteException e) {
19407            throw new IllegalStateException("Process disappeared");
19408        }
19409    }
19410
19411    private void clearProfilerLocked() {
19412        if (mProfileFd != null) {
19413            try {
19414                mProfileFd.close();
19415            } catch (IOException e) {
19416            }
19417        }
19418        mProfileApp = null;
19419        mProfileProc = null;
19420        mProfileFile = null;
19421        mProfileType = 0;
19422        mAutoStopProfiler = false;
19423        mSamplingInterval = 0;
19424    }
19425
19426    public boolean profileControl(String process, int userId, boolean start,
19427            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19428
19429        try {
19430            synchronized (this) {
19431                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19432                // its own permission.
19433                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19434                        != PackageManager.PERMISSION_GRANTED) {
19435                    throw new SecurityException("Requires permission "
19436                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19437                }
19438
19439                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19440                    throw new IllegalArgumentException("null profile info or fd");
19441                }
19442
19443                ProcessRecord proc = null;
19444                if (process != null) {
19445                    proc = findProcessLocked(process, userId, "profileControl");
19446                }
19447
19448                if (start && (proc == null || proc.thread == null)) {
19449                    throw new IllegalArgumentException("Unknown process: " + process);
19450                }
19451
19452                if (start) {
19453                    stopProfilerLocked(null, 0);
19454                    setProfileApp(proc.info, proc.processName, profilerInfo);
19455                    mProfileProc = proc;
19456                    mProfileType = profileType;
19457                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19458                    try {
19459                        fd = fd.dup();
19460                    } catch (IOException e) {
19461                        fd = null;
19462                    }
19463                    profilerInfo.profileFd = fd;
19464                    proc.thread.profilerControl(start, profilerInfo, profileType);
19465                    fd = null;
19466                    mProfileFd = null;
19467                } else {
19468                    stopProfilerLocked(proc, profileType);
19469                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19470                        try {
19471                            profilerInfo.profileFd.close();
19472                        } catch (IOException e) {
19473                        }
19474                    }
19475                }
19476
19477                return true;
19478            }
19479        } catch (RemoteException e) {
19480            throw new IllegalStateException("Process disappeared");
19481        } finally {
19482            if (profilerInfo != null && profilerInfo.profileFd != null) {
19483                try {
19484                    profilerInfo.profileFd.close();
19485                } catch (IOException e) {
19486                }
19487            }
19488        }
19489    }
19490
19491    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19492        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19493                userId, true, ALLOW_FULL_ONLY, callName, null);
19494        ProcessRecord proc = null;
19495        try {
19496            int pid = Integer.parseInt(process);
19497            synchronized (mPidsSelfLocked) {
19498                proc = mPidsSelfLocked.get(pid);
19499            }
19500        } catch (NumberFormatException e) {
19501        }
19502
19503        if (proc == null) {
19504            ArrayMap<String, SparseArray<ProcessRecord>> all
19505                    = mProcessNames.getMap();
19506            SparseArray<ProcessRecord> procs = all.get(process);
19507            if (procs != null && procs.size() > 0) {
19508                proc = procs.valueAt(0);
19509                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19510                    for (int i=1; i<procs.size(); i++) {
19511                        ProcessRecord thisProc = procs.valueAt(i);
19512                        if (thisProc.userId == userId) {
19513                            proc = thisProc;
19514                            break;
19515                        }
19516                    }
19517                }
19518            }
19519        }
19520
19521        return proc;
19522    }
19523
19524    public boolean dumpHeap(String process, int userId, boolean managed,
19525            String path, ParcelFileDescriptor fd) throws RemoteException {
19526
19527        try {
19528            synchronized (this) {
19529                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19530                // its own permission (same as profileControl).
19531                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19532                        != PackageManager.PERMISSION_GRANTED) {
19533                    throw new SecurityException("Requires permission "
19534                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19535                }
19536
19537                if (fd == null) {
19538                    throw new IllegalArgumentException("null fd");
19539                }
19540
19541                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19542                if (proc == null || proc.thread == null) {
19543                    throw new IllegalArgumentException("Unknown process: " + process);
19544                }
19545
19546                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19547                if (!isDebuggable) {
19548                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19549                        throw new SecurityException("Process not debuggable: " + proc);
19550                    }
19551                }
19552
19553                proc.thread.dumpHeap(managed, path, fd);
19554                fd = null;
19555                return true;
19556            }
19557        } catch (RemoteException e) {
19558            throw new IllegalStateException("Process disappeared");
19559        } finally {
19560            if (fd != null) {
19561                try {
19562                    fd.close();
19563                } catch (IOException e) {
19564                }
19565            }
19566        }
19567    }
19568
19569    @Override
19570    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19571            String reportPackage) {
19572        if (processName != null) {
19573            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19574                    "setDumpHeapDebugLimit()");
19575        } else {
19576            synchronized (mPidsSelfLocked) {
19577                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19578                if (proc == null) {
19579                    throw new SecurityException("No process found for calling pid "
19580                            + Binder.getCallingPid());
19581                }
19582                if (!Build.IS_DEBUGGABLE
19583                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19584                    throw new SecurityException("Not running a debuggable build");
19585                }
19586                processName = proc.processName;
19587                uid = proc.uid;
19588                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19589                    throw new SecurityException("Package " + reportPackage + " is not running in "
19590                            + proc);
19591                }
19592            }
19593        }
19594        synchronized (this) {
19595            if (maxMemSize > 0) {
19596                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19597            } else {
19598                if (uid != 0) {
19599                    mMemWatchProcesses.remove(processName, uid);
19600                } else {
19601                    mMemWatchProcesses.getMap().remove(processName);
19602                }
19603            }
19604        }
19605    }
19606
19607    @Override
19608    public void dumpHeapFinished(String path) {
19609        synchronized (this) {
19610            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19611                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19612                        + " does not match last pid " + mMemWatchDumpPid);
19613                return;
19614            }
19615            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19616                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19617                        + " does not match last path " + mMemWatchDumpFile);
19618                return;
19619            }
19620            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19621            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19622        }
19623    }
19624
19625    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19626    public void monitor() {
19627        synchronized (this) { }
19628    }
19629
19630    void onCoreSettingsChange(Bundle settings) {
19631        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19632            ProcessRecord processRecord = mLruProcesses.get(i);
19633            try {
19634                if (processRecord.thread != null) {
19635                    processRecord.thread.setCoreSettings(settings);
19636                }
19637            } catch (RemoteException re) {
19638                /* ignore */
19639            }
19640        }
19641    }
19642
19643    // Multi-user methods
19644
19645    /**
19646     * Start user, if its not already running, but don't bring it to foreground.
19647     */
19648    @Override
19649    public boolean startUserInBackground(final int userId) {
19650        return startUser(userId, /* foreground */ false);
19651    }
19652
19653    /**
19654     * Start user, if its not already running, and bring it to foreground.
19655     */
19656    boolean startUserInForeground(final int userId, Dialog dlg) {
19657        boolean result = startUser(userId, /* foreground */ true);
19658        dlg.dismiss();
19659        return result;
19660    }
19661
19662    /**
19663     * Refreshes the list of users related to the current user when either a
19664     * user switch happens or when a new related user is started in the
19665     * background.
19666     */
19667    private void updateCurrentProfileIdsLocked() {
19668        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19669                mCurrentUserId, false /* enabledOnly */);
19670        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19671        for (int i = 0; i < currentProfileIds.length; i++) {
19672            currentProfileIds[i] = profiles.get(i).id;
19673        }
19674        mCurrentProfileIds = currentProfileIds;
19675
19676        synchronized (mUserProfileGroupIdsSelfLocked) {
19677            mUserProfileGroupIdsSelfLocked.clear();
19678            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19679            for (int i = 0; i < users.size(); i++) {
19680                UserInfo user = users.get(i);
19681                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19682                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19683                }
19684            }
19685        }
19686    }
19687
19688    private Set<Integer> getProfileIdsLocked(int userId) {
19689        Set<Integer> userIds = new HashSet<Integer>();
19690        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19691                userId, false /* enabledOnly */);
19692        for (UserInfo user : profiles) {
19693            userIds.add(Integer.valueOf(user.id));
19694        }
19695        return userIds;
19696    }
19697
19698    @Override
19699    public boolean switchUser(final int userId) {
19700        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19701        String userName;
19702        synchronized (this) {
19703            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19704            if (userInfo == null) {
19705                Slog.w(TAG, "No user info for user #" + userId);
19706                return false;
19707            }
19708            if (userInfo.isManagedProfile()) {
19709                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19710                return false;
19711            }
19712            userName = userInfo.name;
19713            mTargetUserId = userId;
19714        }
19715        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19716        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19717        return true;
19718    }
19719
19720    private void showUserSwitchDialog(int userId, String userName) {
19721        // The dialog will show and then initiate the user switch by calling startUserInForeground
19722        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19723                true /* above system */);
19724        d.show();
19725    }
19726
19727    private boolean startUser(final int userId, final boolean foreground) {
19728        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19729                != PackageManager.PERMISSION_GRANTED) {
19730            String msg = "Permission Denial: switchUser() from pid="
19731                    + Binder.getCallingPid()
19732                    + ", uid=" + Binder.getCallingUid()
19733                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19734            Slog.w(TAG, msg);
19735            throw new SecurityException(msg);
19736        }
19737
19738        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19739
19740        final long ident = Binder.clearCallingIdentity();
19741        try {
19742            synchronized (this) {
19743                final int oldUserId = mCurrentUserId;
19744                if (oldUserId == userId) {
19745                    return true;
19746                }
19747
19748                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19749                        "startUser", false);
19750
19751                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19752                if (userInfo == null) {
19753                    Slog.w(TAG, "No user info for user #" + userId);
19754                    return false;
19755                }
19756                if (foreground && userInfo.isManagedProfile()) {
19757                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19758                    return false;
19759                }
19760
19761                if (foreground) {
19762                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19763                            R.anim.screen_user_enter);
19764                }
19765
19766                boolean needStart = false;
19767
19768                // If the user we are switching to is not currently started, then
19769                // we need to start it now.
19770                if (mStartedUsers.get(userId) == null) {
19771                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19772                    updateStartedUserArrayLocked();
19773                    needStart = true;
19774                }
19775
19776                final Integer userIdInt = Integer.valueOf(userId);
19777                mUserLru.remove(userIdInt);
19778                mUserLru.add(userIdInt);
19779
19780                if (foreground) {
19781                    mCurrentUserId = userId;
19782                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19783                    updateCurrentProfileIdsLocked();
19784                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19785                    // Once the internal notion of the active user has switched, we lock the device
19786                    // with the option to show the user switcher on the keyguard.
19787                    mWindowManager.lockNow(null);
19788                } else {
19789                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19790                    updateCurrentProfileIdsLocked();
19791                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19792                    mUserLru.remove(currentUserIdInt);
19793                    mUserLru.add(currentUserIdInt);
19794                }
19795
19796                final UserState uss = mStartedUsers.get(userId);
19797
19798                // Make sure user is in the started state.  If it is currently
19799                // stopping, we need to knock that off.
19800                if (uss.mState == UserState.STATE_STOPPING) {
19801                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19802                    // so we can just fairly silently bring the user back from
19803                    // the almost-dead.
19804                    uss.mState = UserState.STATE_RUNNING;
19805                    updateStartedUserArrayLocked();
19806                    needStart = true;
19807                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19808                    // This means ACTION_SHUTDOWN has been sent, so we will
19809                    // need to treat this as a new boot of the user.
19810                    uss.mState = UserState.STATE_BOOTING;
19811                    updateStartedUserArrayLocked();
19812                    needStart = true;
19813                }
19814
19815                if (uss.mState == UserState.STATE_BOOTING) {
19816                    // Booting up a new user, need to tell system services about it.
19817                    // Note that this is on the same handler as scheduling of broadcasts,
19818                    // which is important because it needs to go first.
19819                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19820                }
19821
19822                if (foreground) {
19823                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19824                            oldUserId));
19825                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19826                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19827                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19828                            oldUserId, userId, uss));
19829                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19830                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19831                }
19832
19833                if (needStart) {
19834                    // Send USER_STARTED broadcast
19835                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19836                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19837                            | Intent.FLAG_RECEIVER_FOREGROUND);
19838                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19839                    broadcastIntentLocked(null, null, intent,
19840                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19841                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19842                }
19843
19844                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19845                    if (userId != UserHandle.USER_OWNER) {
19846                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19847                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19848                        broadcastIntentLocked(null, null, intent, null,
19849                                new IIntentReceiver.Stub() {
19850                                    public void performReceive(Intent intent, int resultCode,
19851                                            String data, Bundle extras, boolean ordered,
19852                                            boolean sticky, int sendingUser) {
19853                                        onUserInitialized(uss, foreground, oldUserId, userId);
19854                                    }
19855                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19856                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19857                        uss.initializing = true;
19858                    } else {
19859                        getUserManagerLocked().makeInitialized(userInfo.id);
19860                    }
19861                }
19862
19863                if (foreground) {
19864                    if (!uss.initializing) {
19865                        moveUserToForeground(uss, oldUserId, userId);
19866                    }
19867                } else {
19868                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19869                }
19870
19871                if (needStart) {
19872                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19873                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19874                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19875                    broadcastIntentLocked(null, null, intent,
19876                            null, new IIntentReceiver.Stub() {
19877                                @Override
19878                                public void performReceive(Intent intent, int resultCode,
19879                                        String data, Bundle extras, boolean ordered, boolean sticky,
19880                                        int sendingUser) throws RemoteException {
19881                                }
19882                            }, 0, null, null,
19883                            new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19884                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19885                }
19886            }
19887        } finally {
19888            Binder.restoreCallingIdentity(ident);
19889        }
19890
19891        return true;
19892    }
19893
19894    void dispatchForegroundProfileChanged(int userId) {
19895        final int N = mUserSwitchObservers.beginBroadcast();
19896        for (int i = 0; i < N; i++) {
19897            try {
19898                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19899            } catch (RemoteException e) {
19900                // Ignore
19901            }
19902        }
19903        mUserSwitchObservers.finishBroadcast();
19904    }
19905
19906    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19907        long ident = Binder.clearCallingIdentity();
19908        try {
19909            Intent intent;
19910            if (oldUserId >= 0) {
19911                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19912                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19913                int count = profiles.size();
19914                for (int i = 0; i < count; i++) {
19915                    int profileUserId = profiles.get(i).id;
19916                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19917                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19918                            | Intent.FLAG_RECEIVER_FOREGROUND);
19919                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19920                    broadcastIntentLocked(null, null, intent,
19921                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19922                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19923                }
19924            }
19925            if (newUserId >= 0) {
19926                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19927                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19928                int count = profiles.size();
19929                for (int i = 0; i < count; i++) {
19930                    int profileUserId = profiles.get(i).id;
19931                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19932                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19933                            | Intent.FLAG_RECEIVER_FOREGROUND);
19934                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19935                    broadcastIntentLocked(null, null, intent,
19936                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19937                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19938                }
19939                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19940                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19941                        | Intent.FLAG_RECEIVER_FOREGROUND);
19942                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19943                broadcastIntentLocked(null, null, intent,
19944                        null, null, 0, null, null,
19945                        new String[] {android.Manifest.permission.MANAGE_USERS},
19946                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19947                        UserHandle.USER_ALL);
19948            }
19949        } finally {
19950            Binder.restoreCallingIdentity(ident);
19951        }
19952    }
19953
19954    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19955            final int newUserId) {
19956        final int N = mUserSwitchObservers.beginBroadcast();
19957        if (N > 0) {
19958            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19959                int mCount = 0;
19960                @Override
19961                public void sendResult(Bundle data) throws RemoteException {
19962                    synchronized (ActivityManagerService.this) {
19963                        if (mCurUserSwitchCallback == this) {
19964                            mCount++;
19965                            if (mCount == N) {
19966                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19967                            }
19968                        }
19969                    }
19970                }
19971            };
19972            synchronized (this) {
19973                uss.switching = true;
19974                mCurUserSwitchCallback = callback;
19975            }
19976            for (int i=0; i<N; i++) {
19977                try {
19978                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19979                            newUserId, callback);
19980                } catch (RemoteException e) {
19981                }
19982            }
19983        } else {
19984            synchronized (this) {
19985                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19986            }
19987        }
19988        mUserSwitchObservers.finishBroadcast();
19989    }
19990
19991    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19992        synchronized (this) {
19993            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19994            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19995        }
19996    }
19997
19998    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19999        mCurUserSwitchCallback = null;
20000        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20001        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20002                oldUserId, newUserId, uss));
20003    }
20004
20005    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20006        synchronized (this) {
20007            if (foreground) {
20008                moveUserToForeground(uss, oldUserId, newUserId);
20009            }
20010        }
20011
20012        completeSwitchAndInitialize(uss, newUserId, true, false);
20013    }
20014
20015    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20016        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20017        if (homeInFront) {
20018            startHomeActivityLocked(newUserId, "moveUserToFroreground");
20019        } else {
20020            mStackSupervisor.resumeTopActivitiesLocked();
20021        }
20022        EventLogTags.writeAmSwitchUser(newUserId);
20023        getUserManagerLocked().onUserForeground(newUserId);
20024        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20025    }
20026
20027    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20028        completeSwitchAndInitialize(uss, newUserId, false, true);
20029    }
20030
20031    void completeSwitchAndInitialize(UserState uss, int newUserId,
20032            boolean clearInitializing, boolean clearSwitching) {
20033        boolean unfrozen = false;
20034        synchronized (this) {
20035            if (clearInitializing) {
20036                uss.initializing = false;
20037                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20038            }
20039            if (clearSwitching) {
20040                uss.switching = false;
20041            }
20042            if (!uss.switching && !uss.initializing) {
20043                mWindowManager.stopFreezingScreen();
20044                unfrozen = true;
20045            }
20046        }
20047        if (unfrozen) {
20048            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20049            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20050                    newUserId, 0));
20051        }
20052        stopGuestUserIfBackground();
20053    }
20054
20055    /** Called on handler thread */
20056    void dispatchUserSwitchComplete(int userId) {
20057        final int observerCount = mUserSwitchObservers.beginBroadcast();
20058        for (int i = 0; i < observerCount; i++) {
20059            try {
20060                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20061            } catch (RemoteException e) {
20062            }
20063        }
20064        mUserSwitchObservers.finishBroadcast();
20065    }
20066
20067    /**
20068     * Stops the guest user if it has gone to the background.
20069     */
20070    private void stopGuestUserIfBackground() {
20071        synchronized (this) {
20072            final int num = mUserLru.size();
20073            for (int i = 0; i < num; i++) {
20074                Integer oldUserId = mUserLru.get(i);
20075                UserState oldUss = mStartedUsers.get(oldUserId);
20076                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20077                        || oldUss.mState == UserState.STATE_STOPPING
20078                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20079                    continue;
20080                }
20081                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20082                if (userInfo.isGuest()) {
20083                    // This is a user to be stopped.
20084                    stopUserLocked(oldUserId, null);
20085                    break;
20086                }
20087            }
20088        }
20089    }
20090
20091    void scheduleStartProfilesLocked() {
20092        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20093            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20094                    DateUtils.SECOND_IN_MILLIS);
20095        }
20096    }
20097
20098    void startProfilesLocked() {
20099        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20100        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20101                mCurrentUserId, false /* enabledOnly */);
20102        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20103        for (UserInfo user : profiles) {
20104            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20105                    && user.id != mCurrentUserId) {
20106                toStart.add(user);
20107            }
20108        }
20109        final int n = toStart.size();
20110        int i = 0;
20111        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20112            startUserInBackground(toStart.get(i).id);
20113        }
20114        if (i < n) {
20115            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20116        }
20117    }
20118
20119    void finishUserBoot(UserState uss) {
20120        synchronized (this) {
20121            if (uss.mState == UserState.STATE_BOOTING
20122                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20123                uss.mState = UserState.STATE_RUNNING;
20124                final int userId = uss.mHandle.getIdentifier();
20125                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20126                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20127                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20128                broadcastIntentLocked(null, null, intent,
20129                        null, null, 0, null, null,
20130                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20131                        AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20132                        userId);
20133            }
20134        }
20135    }
20136
20137    void finishUserSwitch(UserState uss) {
20138        synchronized (this) {
20139            finishUserBoot(uss);
20140
20141            startProfilesLocked();
20142
20143            int num = mUserLru.size();
20144            int i = 0;
20145            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20146                Integer oldUserId = mUserLru.get(i);
20147                UserState oldUss = mStartedUsers.get(oldUserId);
20148                if (oldUss == null) {
20149                    // Shouldn't happen, but be sane if it does.
20150                    mUserLru.remove(i);
20151                    num--;
20152                    continue;
20153                }
20154                if (oldUss.mState == UserState.STATE_STOPPING
20155                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20156                    // This user is already stopping, doesn't count.
20157                    num--;
20158                    i++;
20159                    continue;
20160                }
20161                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20162                    // Owner and current can't be stopped, but count as running.
20163                    i++;
20164                    continue;
20165                }
20166                // This is a user to be stopped.
20167                stopUserLocked(oldUserId, null);
20168                num--;
20169                i++;
20170            }
20171        }
20172    }
20173
20174    @Override
20175    public int stopUser(final int userId, final IStopUserCallback callback) {
20176        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20177                != PackageManager.PERMISSION_GRANTED) {
20178            String msg = "Permission Denial: switchUser() from pid="
20179                    + Binder.getCallingPid()
20180                    + ", uid=" + Binder.getCallingUid()
20181                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20182            Slog.w(TAG, msg);
20183            throw new SecurityException(msg);
20184        }
20185        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20186            throw new IllegalArgumentException("Can't stop primary user " + userId);
20187        }
20188        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20189        synchronized (this) {
20190            return stopUserLocked(userId, callback);
20191        }
20192    }
20193
20194    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20195        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20196        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20197            return ActivityManager.USER_OP_IS_CURRENT;
20198        }
20199
20200        final UserState uss = mStartedUsers.get(userId);
20201        if (uss == null) {
20202            // User is not started, nothing to do...  but we do need to
20203            // callback if requested.
20204            if (callback != null) {
20205                mHandler.post(new Runnable() {
20206                    @Override
20207                    public void run() {
20208                        try {
20209                            callback.userStopped(userId);
20210                        } catch (RemoteException e) {
20211                        }
20212                    }
20213                });
20214            }
20215            return ActivityManager.USER_OP_SUCCESS;
20216        }
20217
20218        if (callback != null) {
20219            uss.mStopCallbacks.add(callback);
20220        }
20221
20222        if (uss.mState != UserState.STATE_STOPPING
20223                && uss.mState != UserState.STATE_SHUTDOWN) {
20224            uss.mState = UserState.STATE_STOPPING;
20225            updateStartedUserArrayLocked();
20226
20227            long ident = Binder.clearCallingIdentity();
20228            try {
20229                // We are going to broadcast ACTION_USER_STOPPING and then
20230                // once that is done send a final ACTION_SHUTDOWN and then
20231                // stop the user.
20232                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20233                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20234                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20235                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20236                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20237                // This is the result receiver for the final shutdown broadcast.
20238                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20239                    @Override
20240                    public void performReceive(Intent intent, int resultCode, String data,
20241                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20242                        finishUserStop(uss);
20243                    }
20244                };
20245                // This is the result receiver for the initial stopping broadcast.
20246                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20247                    @Override
20248                    public void performReceive(Intent intent, int resultCode, String data,
20249                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20250                        // On to the next.
20251                        synchronized (ActivityManagerService.this) {
20252                            if (uss.mState != UserState.STATE_STOPPING) {
20253                                // Whoops, we are being started back up.  Abort, abort!
20254                                return;
20255                            }
20256                            uss.mState = UserState.STATE_SHUTDOWN;
20257                        }
20258                        mBatteryStatsService.noteEvent(
20259                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20260                                Integer.toString(userId), userId);
20261                        mSystemServiceManager.stopUser(userId);
20262                        broadcastIntentLocked(null, null, shutdownIntent,
20263                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20264                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20265                    }
20266                };
20267                // Kick things off.
20268                broadcastIntentLocked(null, null, stoppingIntent,
20269                        null, stoppingReceiver, 0, null, null,
20270                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20271                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20272            } finally {
20273                Binder.restoreCallingIdentity(ident);
20274            }
20275        }
20276
20277        return ActivityManager.USER_OP_SUCCESS;
20278    }
20279
20280    void finishUserStop(UserState uss) {
20281        final int userId = uss.mHandle.getIdentifier();
20282        boolean stopped;
20283        ArrayList<IStopUserCallback> callbacks;
20284        synchronized (this) {
20285            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20286            if (mStartedUsers.get(userId) != uss) {
20287                stopped = false;
20288            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20289                stopped = false;
20290            } else {
20291                stopped = true;
20292                // User can no longer run.
20293                mStartedUsers.remove(userId);
20294                mUserLru.remove(Integer.valueOf(userId));
20295                updateStartedUserArrayLocked();
20296
20297                // Clean up all state and processes associated with the user.
20298                // Kill all the processes for the user.
20299                forceStopUserLocked(userId, "finish user");
20300            }
20301
20302            // Explicitly remove the old information in mRecentTasks.
20303            mRecentTasks.removeTasksForUserLocked(userId);
20304        }
20305
20306        for (int i=0; i<callbacks.size(); i++) {
20307            try {
20308                if (stopped) callbacks.get(i).userStopped(userId);
20309                else callbacks.get(i).userStopAborted(userId);
20310            } catch (RemoteException e) {
20311            }
20312        }
20313
20314        if (stopped) {
20315            mSystemServiceManager.cleanupUser(userId);
20316            synchronized (this) {
20317                mStackSupervisor.removeUserLocked(userId);
20318            }
20319        }
20320    }
20321
20322    @Override
20323    public UserInfo getCurrentUser() {
20324        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20325                != PackageManager.PERMISSION_GRANTED) && (
20326                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20327                != PackageManager.PERMISSION_GRANTED)) {
20328            String msg = "Permission Denial: getCurrentUser() from pid="
20329                    + Binder.getCallingPid()
20330                    + ", uid=" + Binder.getCallingUid()
20331                    + " requires " + INTERACT_ACROSS_USERS;
20332            Slog.w(TAG, msg);
20333            throw new SecurityException(msg);
20334        }
20335        synchronized (this) {
20336            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20337            return getUserManagerLocked().getUserInfo(userId);
20338        }
20339    }
20340
20341    int getCurrentUserIdLocked() {
20342        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20343    }
20344
20345    @Override
20346    public boolean isUserRunning(int userId, boolean orStopped) {
20347        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20348                != PackageManager.PERMISSION_GRANTED) {
20349            String msg = "Permission Denial: isUserRunning() from pid="
20350                    + Binder.getCallingPid()
20351                    + ", uid=" + Binder.getCallingUid()
20352                    + " requires " + INTERACT_ACROSS_USERS;
20353            Slog.w(TAG, msg);
20354            throw new SecurityException(msg);
20355        }
20356        synchronized (this) {
20357            return isUserRunningLocked(userId, orStopped);
20358        }
20359    }
20360
20361    boolean isUserRunningLocked(int userId, boolean orStopped) {
20362        UserState state = mStartedUsers.get(userId);
20363        if (state == null) {
20364            return false;
20365        }
20366        if (orStopped) {
20367            return true;
20368        }
20369        return state.mState != UserState.STATE_STOPPING
20370                && state.mState != UserState.STATE_SHUTDOWN;
20371    }
20372
20373    @Override
20374    public int[] getRunningUserIds() {
20375        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20376                != PackageManager.PERMISSION_GRANTED) {
20377            String msg = "Permission Denial: isUserRunning() from pid="
20378                    + Binder.getCallingPid()
20379                    + ", uid=" + Binder.getCallingUid()
20380                    + " requires " + INTERACT_ACROSS_USERS;
20381            Slog.w(TAG, msg);
20382            throw new SecurityException(msg);
20383        }
20384        synchronized (this) {
20385            return mStartedUserArray;
20386        }
20387    }
20388
20389    private void updateStartedUserArrayLocked() {
20390        int num = 0;
20391        for (int i=0; i<mStartedUsers.size();  i++) {
20392            UserState uss = mStartedUsers.valueAt(i);
20393            // This list does not include stopping users.
20394            if (uss.mState != UserState.STATE_STOPPING
20395                    && uss.mState != UserState.STATE_SHUTDOWN) {
20396                num++;
20397            }
20398        }
20399        mStartedUserArray = new int[num];
20400        num = 0;
20401        for (int i=0; i<mStartedUsers.size();  i++) {
20402            UserState uss = mStartedUsers.valueAt(i);
20403            if (uss.mState != UserState.STATE_STOPPING
20404                    && uss.mState != UserState.STATE_SHUTDOWN) {
20405                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20406                num++;
20407            }
20408        }
20409    }
20410
20411    @Override
20412    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20413        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20414                != PackageManager.PERMISSION_GRANTED) {
20415            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20416                    + Binder.getCallingPid()
20417                    + ", uid=" + Binder.getCallingUid()
20418                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20419            Slog.w(TAG, msg);
20420            throw new SecurityException(msg);
20421        }
20422
20423        mUserSwitchObservers.register(observer);
20424    }
20425
20426    @Override
20427    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20428        mUserSwitchObservers.unregister(observer);
20429    }
20430
20431    int[] getUsersLocked() {
20432        UserManagerService ums = getUserManagerLocked();
20433        return ums != null ? ums.getUserIds() : new int[] { 0 };
20434    }
20435
20436    UserManagerService getUserManagerLocked() {
20437        if (mUserManager == null) {
20438            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20439            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20440        }
20441        return mUserManager;
20442    }
20443
20444    private int applyUserId(int uid, int userId) {
20445        return UserHandle.getUid(userId, uid);
20446    }
20447
20448    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20449        if (info == null) return null;
20450        ApplicationInfo newInfo = new ApplicationInfo(info);
20451        newInfo.uid = applyUserId(info.uid, userId);
20452        newInfo.dataDir = Environment
20453                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20454                .getAbsolutePath();
20455        return newInfo;
20456    }
20457
20458    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20459        if (aInfo == null
20460                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20461            return aInfo;
20462        }
20463
20464        ActivityInfo info = new ActivityInfo(aInfo);
20465        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20466        return info;
20467    }
20468
20469    private final class LocalService extends ActivityManagerInternal {
20470        @Override
20471        public void onWakefulnessChanged(int wakefulness) {
20472            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20473        }
20474
20475        @Override
20476        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20477                String processName, String abiOverride, int uid, Runnable crashHandler) {
20478            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20479                    processName, abiOverride, uid, crashHandler);
20480        }
20481
20482        @Override
20483        public SleepToken acquireSleepToken(String tag) {
20484            Preconditions.checkNotNull(tag);
20485
20486            synchronized (ActivityManagerService.this) {
20487                SleepTokenImpl token = new SleepTokenImpl(tag);
20488                mSleepTokens.add(token);
20489                updateSleepIfNeededLocked();
20490                return token;
20491            }
20492        }
20493
20494        @Override
20495        public ComponentName getHomeActivityForUser(int userId) {
20496            synchronized (ActivityManagerService.this) {
20497                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20498                return homeActivity == null ? null : homeActivity.realActivity;
20499            }
20500        }
20501    }
20502
20503    private final class SleepTokenImpl extends SleepToken {
20504        private final String mTag;
20505        private final long mAcquireTime;
20506
20507        public SleepTokenImpl(String tag) {
20508            mTag = tag;
20509            mAcquireTime = SystemClock.uptimeMillis();
20510        }
20511
20512        @Override
20513        public void release() {
20514            synchronized (ActivityManagerService.this) {
20515                if (mSleepTokens.remove(this)) {
20516                    updateSleepIfNeededLocked();
20517                }
20518            }
20519        }
20520
20521        @Override
20522        public String toString() {
20523            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20524        }
20525    }
20526
20527    /**
20528     * An implementation of IAppTask, that allows an app to manage its own tasks via
20529     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20530     * only the process that calls getAppTasks() can call the AppTask methods.
20531     */
20532    class AppTaskImpl extends IAppTask.Stub {
20533        private int mTaskId;
20534        private int mCallingUid;
20535
20536        public AppTaskImpl(int taskId, int callingUid) {
20537            mTaskId = taskId;
20538            mCallingUid = callingUid;
20539        }
20540
20541        private void checkCaller() {
20542            if (mCallingUid != Binder.getCallingUid()) {
20543                throw new SecurityException("Caller " + mCallingUid
20544                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20545            }
20546        }
20547
20548        @Override
20549        public void finishAndRemoveTask() {
20550            checkCaller();
20551
20552            synchronized (ActivityManagerService.this) {
20553                long origId = Binder.clearCallingIdentity();
20554                try {
20555                    if (!removeTaskByIdLocked(mTaskId, false)) {
20556                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20557                    }
20558                } finally {
20559                    Binder.restoreCallingIdentity(origId);
20560                }
20561            }
20562        }
20563
20564        @Override
20565        public ActivityManager.RecentTaskInfo getTaskInfo() {
20566            checkCaller();
20567
20568            synchronized (ActivityManagerService.this) {
20569                long origId = Binder.clearCallingIdentity();
20570                try {
20571                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20572                    if (tr == null) {
20573                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20574                    }
20575                    return createRecentTaskInfoFromTaskRecord(tr);
20576                } finally {
20577                    Binder.restoreCallingIdentity(origId);
20578                }
20579            }
20580        }
20581
20582        @Override
20583        public void moveToFront() {
20584            checkCaller();
20585            // Will bring task to front if it already has a root activity.
20586            startActivityFromRecentsInner(mTaskId, null);
20587        }
20588
20589        @Override
20590        public int startActivity(IBinder whoThread, String callingPackage,
20591                Intent intent, String resolvedType, Bundle options) {
20592            checkCaller();
20593
20594            int callingUser = UserHandle.getCallingUserId();
20595            TaskRecord tr;
20596            IApplicationThread appThread;
20597            synchronized (ActivityManagerService.this) {
20598                tr = mRecentTasks.taskForIdLocked(mTaskId);
20599                if (tr == null) {
20600                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20601                }
20602                appThread = ApplicationThreadNative.asInterface(whoThread);
20603                if (appThread == null) {
20604                    throw new IllegalArgumentException("Bad app thread " + appThread);
20605                }
20606            }
20607            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20608                    resolvedType, null, null, null, null, 0, 0, null, null,
20609                    null, options, false, callingUser, null, tr);
20610        }
20611
20612        @Override
20613        public void setExcludeFromRecents(boolean exclude) {
20614            checkCaller();
20615
20616            synchronized (ActivityManagerService.this) {
20617                long origId = Binder.clearCallingIdentity();
20618                try {
20619                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20620                    if (tr == null) {
20621                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20622                    }
20623                    Intent intent = tr.getBaseIntent();
20624                    if (exclude) {
20625                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20626                    } else {
20627                        intent.setFlags(intent.getFlags()
20628                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20629                    }
20630                } finally {
20631                    Binder.restoreCallingIdentity(origId);
20632                }
20633            }
20634        }
20635    }
20636}
20637