ActivityManagerService.java revision 280d332bd4dbf13bb05102f86c70b7ee299e0704
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.app.ActivityManager.StackId.DOCKED_STACK_ID;
23import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
24import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
25import static android.app.ActivityManager.StackId.HOME_STACK_ID;
26import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
27import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
28import static android.content.pm.PackageManager.PERMISSION_GRANTED;
29import static com.android.internal.util.XmlUtils.readBooleanAttribute;
30import static com.android.internal.util.XmlUtils.readIntAttribute;
31import static com.android.internal.util.XmlUtils.readLongAttribute;
32import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
33import static com.android.internal.util.XmlUtils.writeIntAttribute;
34import static com.android.internal.util.XmlUtils.writeLongAttribute;
35import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
36import static com.android.server.am.ActivityManagerDebugConfig.*;
37import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
38import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
39import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
40import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
41import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
42import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
43import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
44import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
45import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
46import static org.xmlpull.v1.XmlPullParser.START_TAG;
47
48import android.Manifest;
49import android.app.ActivityManager.StackId;
50import android.app.AppOpsManager;
51import android.app.ApplicationThreadNative;
52import android.app.BroadcastOptions;
53import android.app.IActivityContainer;
54import android.app.IActivityContainerCallback;
55import android.app.IAppTask;
56import android.app.ITaskStackListener;
57import android.app.ProfilerInfo;
58import android.app.assist.AssistContent;
59import android.app.assist.AssistStructure;
60import android.app.usage.UsageEvents;
61import android.app.usage.UsageStatsManagerInternal;
62import android.appwidget.AppWidgetManager;
63import android.content.pm.AppsQueryHelper;
64import android.content.pm.PermissionInfo;
65import android.content.res.Resources;
66import android.graphics.Bitmap;
67import android.graphics.Point;
68import android.graphics.Rect;
69import android.os.BatteryStats;
70import android.os.PersistableBundle;
71import android.os.PowerManager;
72import android.os.ResultReceiver;
73import android.os.Trace;
74import android.os.TransactionTooLargeException;
75import android.os.WorkSource;
76import android.os.storage.IMountService;
77import android.os.storage.MountServiceInternal;
78import android.os.storage.StorageManager;
79import android.provider.Settings.Global;
80import android.service.voice.IVoiceInteractionSession;
81import android.service.voice.VoiceInteractionSession;
82import android.util.ArrayMap;
83import android.util.ArraySet;
84import android.util.DebugUtils;
85import android.view.Display;
86
87import com.android.internal.R;
88import com.android.internal.annotations.GuardedBy;
89import com.android.internal.app.AssistUtils;
90import com.android.internal.app.DumpHeapActivity;
91import com.android.internal.app.IAppOpsService;
92import com.android.internal.app.IVoiceInteractor;
93import com.android.internal.app.ProcessMap;
94import com.android.internal.app.ProcessStats;
95import com.android.internal.os.BackgroundThread;
96import com.android.internal.os.BatteryStatsImpl;
97import com.android.internal.os.IResultReceiver;
98import com.android.internal.os.ProcessCpuTracker;
99import com.android.internal.os.TransferPipe;
100import com.android.internal.os.Zygote;
101import com.android.internal.util.ArrayUtils;
102import com.android.internal.util.FastPrintWriter;
103import com.android.internal.util.FastXmlSerializer;
104import com.android.internal.util.MemInfoReader;
105import com.android.internal.util.Preconditions;
106import com.android.server.AppOpsService;
107import com.android.server.AttributeCache;
108import com.android.server.DeviceIdleController;
109import com.android.server.IntentResolver;
110import com.android.server.LocalServices;
111import com.android.server.ServiceThread;
112import com.android.server.SystemConfig;
113import com.android.server.SystemService;
114import com.android.server.SystemServiceManager;
115import com.android.server.Watchdog;
116import com.android.server.am.ActivityStack.ActivityState;
117import com.android.server.firewall.IntentFirewall;
118import com.android.server.pm.Installer;
119import com.android.server.pm.UserManagerService;
120import com.android.server.statusbar.StatusBarManagerInternal;
121import com.android.server.wm.AppTransition;
122import com.android.server.wm.WindowManagerService;
123import com.google.android.collect.Lists;
124import com.google.android.collect.Maps;
125
126import libcore.io.IoUtils;
127import libcore.util.EmptyArray;
128
129import org.xmlpull.v1.XmlPullParser;
130import org.xmlpull.v1.XmlPullParserException;
131import org.xmlpull.v1.XmlSerializer;
132
133import android.app.Activity;
134import android.app.ActivityManager;
135import android.app.ActivityManager.RunningTaskInfo;
136import android.app.ActivityManager.StackInfo;
137import android.app.ActivityManagerInternal;
138import android.app.ActivityManagerInternal.SleepToken;
139import android.app.ActivityManagerNative;
140import android.app.ActivityOptions;
141import android.app.ActivityThread;
142import android.app.AlertDialog;
143import android.app.AppGlobals;
144import android.app.ApplicationErrorReport;
145import android.app.Dialog;
146import android.app.IActivityController;
147import android.app.IApplicationThread;
148import android.app.IInstrumentationWatcher;
149import android.app.INotificationManager;
150import android.app.IProcessObserver;
151import android.app.IServiceConnection;
152import android.app.IStopUserCallback;
153import android.app.IUidObserver;
154import android.app.IUiAutomationConnection;
155import android.app.IUserSwitchObserver;
156import android.app.Instrumentation;
157import android.app.Notification;
158import android.app.NotificationManager;
159import android.app.PendingIntent;
160import android.app.backup.IBackupManager;
161import android.app.admin.DevicePolicyManager;
162import android.content.ActivityNotFoundException;
163import android.content.BroadcastReceiver;
164import android.content.ClipData;
165import android.content.ComponentCallbacks2;
166import android.content.ComponentName;
167import android.content.ContentProvider;
168import android.content.ContentResolver;
169import android.content.Context;
170import android.content.DialogInterface;
171import android.content.IContentProvider;
172import android.content.IIntentReceiver;
173import android.content.IIntentSender;
174import android.content.Intent;
175import android.content.IntentFilter;
176import android.content.IntentSender;
177import android.content.pm.ActivityInfo;
178import android.content.pm.ApplicationInfo;
179import android.content.pm.ConfigurationInfo;
180import android.content.pm.IPackageDataObserver;
181import android.content.pm.IPackageManager;
182import android.content.pm.InstrumentationInfo;
183import android.content.pm.PackageInfo;
184import android.content.pm.PackageManager;
185import android.content.pm.ParceledListSlice;
186import android.content.pm.UserInfo;
187import android.content.pm.PackageManager.NameNotFoundException;
188import android.content.pm.PathPermission;
189import android.content.pm.ProviderInfo;
190import android.content.pm.ResolveInfo;
191import android.content.pm.ServiceInfo;
192import android.content.res.CompatibilityInfo;
193import android.content.res.Configuration;
194import android.net.Proxy;
195import android.net.ProxyInfo;
196import android.net.Uri;
197import android.os.Binder;
198import android.os.Build;
199import android.os.Bundle;
200import android.os.Debug;
201import android.os.DropBoxManager;
202import android.os.Environment;
203import android.os.FactoryTest;
204import android.os.FileObserver;
205import android.os.FileUtils;
206import android.os.Handler;
207import android.os.IBinder;
208import android.os.IPermissionController;
209import android.os.IProcessInfoService;
210import android.os.Looper;
211import android.os.Message;
212import android.os.Parcel;
213import android.os.ParcelFileDescriptor;
214import android.os.PowerManagerInternal;
215import android.os.Process;
216import android.os.RemoteCallbackList;
217import android.os.RemoteException;
218import android.os.ServiceManager;
219import android.os.StrictMode;
220import android.os.SystemClock;
221import android.os.SystemProperties;
222import android.os.UpdateLock;
223import android.os.UserHandle;
224import android.os.UserManager;
225import android.provider.Settings;
226import android.text.format.DateUtils;
227import android.text.format.Time;
228import android.util.AtomicFile;
229import android.util.EventLog;
230import android.util.Log;
231import android.util.Pair;
232import android.util.PrintWriterPrinter;
233import android.util.Slog;
234import android.util.SparseArray;
235import android.util.TimeUtils;
236import android.util.Xml;
237import android.view.Gravity;
238import android.view.LayoutInflater;
239import android.view.View;
240import android.view.WindowManager;
241
242import dalvik.system.VMRuntime;
243
244import java.io.BufferedInputStream;
245import java.io.BufferedOutputStream;
246import java.io.DataInputStream;
247import java.io.DataOutputStream;
248import java.io.File;
249import java.io.FileDescriptor;
250import java.io.FileInputStream;
251import java.io.FileNotFoundException;
252import java.io.FileOutputStream;
253import java.io.IOException;
254import java.io.InputStreamReader;
255import java.io.PrintWriter;
256import java.io.StringWriter;
257import java.lang.ref.WeakReference;
258import java.nio.charset.StandardCharsets;
259import java.util.ArrayList;
260import java.util.Arrays;
261import java.util.Collections;
262import java.util.Comparator;
263import java.util.HashMap;
264import java.util.HashSet;
265import java.util.Iterator;
266import java.util.List;
267import java.util.Locale;
268import java.util.Map;
269import java.util.Set;
270import java.util.concurrent.atomic.AtomicBoolean;
271import java.util.concurrent.atomic.AtomicLong;
272
273public final class ActivityManagerService extends ActivityManagerNative
274        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
275
276    // File that stores last updated system version and called preboot receivers
277    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
278
279    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
280    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
281    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
282    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
283    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
284    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
285    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
286    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
287    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
288    private static final String TAG_LRU = TAG + POSTFIX_LRU;
289    private static final String TAG_MU = TAG + POSTFIX_MU;
290    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
291    private static final String TAG_POWER = TAG + POSTFIX_POWER;
292    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
293    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
294    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
295    private static final String TAG_PSS = TAG + POSTFIX_PSS;
296    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
297    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
298    private static final String TAG_STACK = TAG + POSTFIX_STACK;
299    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
300    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
301    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
302    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
303    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
304
305    /** Control over CPU and battery monitoring */
306    // write battery stats every 30 minutes.
307    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
308    static final boolean MONITOR_CPU_USAGE = true;
309    // don't sample cpu less than every 5 seconds.
310    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
311    // wait possibly forever for next cpu sample.
312    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
313    static final boolean MONITOR_THREAD_CPU_USAGE = false;
314
315    // The flags that are set for all calls we make to the package manager.
316    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
317
318    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
319
320    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
321
322    // Amount of time after a call to stopAppSwitches() during which we will
323    // prevent further untrusted switches from happening.
324    static final long APP_SWITCH_DELAY_TIME = 5*1000;
325
326    // How long we wait for a launched process to attach to the activity manager
327    // before we decide it's never going to come up for real.
328    static final int PROC_START_TIMEOUT = 10*1000;
329    // How long we wait for an attached process to publish its content providers
330    // before we decide it must be hung.
331    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
332
333    // How long we wait for a launched process to attach to the activity manager
334    // before we decide it's never going to come up for real, when the process was
335    // started with a wrapper for instrumentation (such as Valgrind) because it
336    // could take much longer than usual.
337    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
338
339    // How long to wait after going idle before forcing apps to GC.
340    static final int GC_TIMEOUT = 5*1000;
341
342    // The minimum amount of time between successive GC requests for a process.
343    static final int GC_MIN_INTERVAL = 60*1000;
344
345    // The minimum amount of time between successive PSS requests for a process.
346    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
347
348    // The minimum amount of time between successive PSS requests for a process
349    // when the request is due to the memory state being lowered.
350    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
351
352    // The rate at which we check for apps using excessive power -- 15 mins.
353    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
354
355    // The minimum sample duration we will allow before deciding we have
356    // enough data on wake locks to start killing things.
357    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
358
359    // The minimum sample duration we will allow before deciding we have
360    // enough data on CPU usage to start killing things.
361    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
362
363    // How long we allow a receiver to run before giving up on it.
364    static final int BROADCAST_FG_TIMEOUT = 10*1000;
365    static final int BROADCAST_BG_TIMEOUT = 60*1000;
366
367    // How long we wait until we timeout on key dispatching.
368    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
369
370    // How long we wait until we timeout on key dispatching during instrumentation.
371    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
372
373    // This is the amount of time an app needs to be running a foreground service before
374    // we will consider it to be doing interaction for usage stats.
375    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
376
377    // Maximum amount of time we will allow to elapse before re-reporting usage stats
378    // interaction with foreground processes.
379    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
380
381    // Maximum number of users we allow to be running at a time.
382    static final int MAX_RUNNING_USERS = 3;
383
384    // How long to wait in getAssistContextExtras for the activity and foreground services
385    // to respond with the result.
386    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
387
388    // How long top wait when going through the modern assist (which doesn't need to block
389    // on getting this result before starting to launch its UI).
390    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
391
392    // Maximum number of persisted Uri grants a package is allowed
393    static final int MAX_PERSISTED_URI_GRANTS = 128;
394
395    static final int MY_PID = Process.myPid();
396
397    static final String[] EMPTY_STRING_ARRAY = new String[0];
398
399    // How many bytes to write into the dropbox log before truncating
400    static final int DROPBOX_MAX_SIZE = 256 * 1024;
401
402    // Access modes for handleIncomingUser.
403    static final int ALLOW_NON_FULL = 0;
404    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
405    static final int ALLOW_FULL_ONLY = 2;
406
407    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
408
409    // Delay in notifying task stack change listeners (in millis)
410    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
411
412    // Necessary ApplicationInfo flags to mark an app as persistent
413    private static final int PERSISTENT_MASK =
414            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
415
416
417    // Delay to disable app launch boost
418    static final int APP_BOOST_MESSAGE_DELAY = 3000;
419    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
420    static final int APP_BOOST_TIMEOUT = 2500;
421
422    // Used to indicate that a task is removed it should also be removed from recents.
423    private static final boolean REMOVE_FROM_RECENTS = true;
424
425    private static native int nativeMigrateToBoost();
426    private static native int nativeMigrateFromBoost();
427    private boolean mIsBoosted = false;
428    private long mBoostStartTime = 0;
429
430    /** All system services */
431    SystemServiceManager mSystemServiceManager;
432
433    private Installer mInstaller;
434
435    /** Run all ActivityStacks through this */
436    ActivityStackSupervisor mStackSupervisor;
437
438    /** Task stack change listeners. */
439    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
440            new RemoteCallbackList<ITaskStackListener>();
441
442    public IntentFirewall mIntentFirewall;
443
444    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
445    // default actuion automatically.  Important for devices without direct input
446    // devices.
447    private boolean mShowDialogs = true;
448
449    BroadcastQueue mFgBroadcastQueue;
450    BroadcastQueue mBgBroadcastQueue;
451    // Convenient for easy iteration over the queues. Foreground is first
452    // so that dispatch of foreground broadcasts gets precedence.
453    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
454
455    BroadcastQueue broadcastQueueForIntent(Intent intent) {
456        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
457        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
458                "Broadcast intent " + intent + " on "
459                + (isFg ? "foreground" : "background") + " queue");
460        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
461    }
462
463    /**
464     * Activity we have told the window manager to have key focus.
465     */
466    ActivityRecord mFocusedActivity = null;
467
468    /**
469     * User id of the last activity mFocusedActivity was set to.
470     */
471    private int mLastFocusedUserId;
472
473    /**
474     * If non-null, we are tracking the time the user spends in the currently focused app.
475     */
476    private AppTimeTracker mCurAppTimeTracker;
477
478    /**
479     * List of intents that were used to start the most recent tasks.
480     */
481    private final RecentTasks mRecentTasks;
482
483    /**
484     * For addAppTask: cached of the last activity component that was added.
485     */
486    ComponentName mLastAddedTaskComponent;
487
488    /**
489     * For addAppTask: cached of the last activity uid that was added.
490     */
491    int mLastAddedTaskUid;
492
493    /**
494     * For addAppTask: cached of the last ActivityInfo that was added.
495     */
496    ActivityInfo mLastAddedTaskActivity;
497
498    /**
499     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
500     */
501    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
502
503    /**
504     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
505     */
506    String mDeviceOwnerName;
507
508    final UserController mUserController;
509
510    public class PendingAssistExtras extends Binder implements Runnable {
511        public final ActivityRecord activity;
512        public final Bundle extras;
513        public final Intent intent;
514        public final String hint;
515        public final IResultReceiver receiver;
516        public final int userHandle;
517        public boolean haveResult = false;
518        public Bundle result = null;
519        public AssistStructure structure = null;
520        public AssistContent content = null;
521        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
522                String _hint, IResultReceiver _receiver, int _userHandle) {
523            activity = _activity;
524            extras = _extras;
525            intent = _intent;
526            hint = _hint;
527            receiver = _receiver;
528            userHandle = _userHandle;
529        }
530        @Override
531        public void run() {
532            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
533            synchronized (this) {
534                haveResult = true;
535                notifyAll();
536            }
537            pendingAssistExtrasTimedOut(this);
538        }
539    }
540
541    final ArrayList<PendingAssistExtras> mPendingAssistExtras
542            = new ArrayList<PendingAssistExtras>();
543
544    /**
545     * Process management.
546     */
547    final ProcessList mProcessList = new ProcessList();
548
549    /**
550     * All of the applications we currently have running organized by name.
551     * The keys are strings of the application package name (as
552     * returned by the package manager), and the keys are ApplicationRecord
553     * objects.
554     */
555    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
556
557    /**
558     * Tracking long-term execution of processes to look for abuse and other
559     * bad app behavior.
560     */
561    final ProcessStatsService mProcessStats;
562
563    /**
564     * The currently running isolated processes.
565     */
566    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
567
568    /**
569     * Counter for assigning isolated process uids, to avoid frequently reusing the
570     * same ones.
571     */
572    int mNextIsolatedProcessUid = 0;
573
574    /**
575     * The currently running heavy-weight process, if any.
576     */
577    ProcessRecord mHeavyWeightProcess = null;
578
579    /**
580     * The last time that various processes have crashed.
581     */
582    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
583
584    /**
585     * Information about a process that is currently marked as bad.
586     */
587    static final class BadProcessInfo {
588        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
589            this.time = time;
590            this.shortMsg = shortMsg;
591            this.longMsg = longMsg;
592            this.stack = stack;
593        }
594
595        final long time;
596        final String shortMsg;
597        final String longMsg;
598        final String stack;
599    }
600
601    /**
602     * Set of applications that we consider to be bad, and will reject
603     * incoming broadcasts from (which the user has no control over).
604     * Processes are added to this set when they have crashed twice within
605     * a minimum amount of time; they are removed from it when they are
606     * later restarted (hopefully due to some user action).  The value is the
607     * time it was added to the list.
608     */
609    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
610
611    /**
612     * All of the processes we currently have running organized by pid.
613     * The keys are the pid running the application.
614     *
615     * <p>NOTE: This object is protected by its own lock, NOT the global
616     * activity manager lock!
617     */
618    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
619
620    /**
621     * All of the processes that have been forced to be foreground.  The key
622     * is the pid of the caller who requested it (we hold a death
623     * link on it).
624     */
625    abstract class ForegroundToken implements IBinder.DeathRecipient {
626        int pid;
627        IBinder token;
628    }
629    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
630
631    /**
632     * List of records for processes that someone had tried to start before the
633     * system was ready.  We don't start them at that point, but ensure they
634     * are started by the time booting is complete.
635     */
636    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
637
638    /**
639     * List of persistent applications that are in the process
640     * of being started.
641     */
642    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
643
644    /**
645     * Processes that are being forcibly torn down.
646     */
647    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
648
649    /**
650     * List of running applications, sorted by recent usage.
651     * The first entry in the list is the least recently used.
652     */
653    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
654
655    /**
656     * Where in mLruProcesses that the processes hosting activities start.
657     */
658    int mLruProcessActivityStart = 0;
659
660    /**
661     * Where in mLruProcesses that the processes hosting services start.
662     * This is after (lower index) than mLruProcessesActivityStart.
663     */
664    int mLruProcessServiceStart = 0;
665
666    /**
667     * List of processes that should gc as soon as things are idle.
668     */
669    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
670
671    /**
672     * Processes we want to collect PSS data from.
673     */
674    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
675
676    private boolean mBinderTransactionTrackingEnabled = false;
677
678    /**
679     * Last time we requested PSS data of all processes.
680     */
681    long mLastFullPssTime = SystemClock.uptimeMillis();
682
683    /**
684     * If set, the next time we collect PSS data we should do a full collection
685     * with data from native processes and the kernel.
686     */
687    boolean mFullPssPending = false;
688
689    /**
690     * This is the process holding what we currently consider to be
691     * the "home" activity.
692     */
693    ProcessRecord mHomeProcess;
694
695    /**
696     * This is the process holding the activity the user last visited that
697     * is in a different process from the one they are currently in.
698     */
699    ProcessRecord mPreviousProcess;
700
701    /**
702     * The time at which the previous process was last visible.
703     */
704    long mPreviousProcessVisibleTime;
705
706    /**
707     * Track all uids that have actively running processes.
708     */
709    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
710
711    /**
712     * Packages that the user has asked to have run in screen size
713     * compatibility mode instead of filling the screen.
714     */
715    final CompatModePackages mCompatModePackages;
716
717    /**
718     * Set of IntentSenderRecord objects that are currently active.
719     */
720    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
721            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
722
723    /**
724     * Fingerprints (hashCode()) of stack traces that we've
725     * already logged DropBox entries for.  Guarded by itself.  If
726     * something (rogue user app) forces this over
727     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
728     */
729    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
730    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
731
732    /**
733     * Strict Mode background batched logging state.
734     *
735     * The string buffer is guarded by itself, and its lock is also
736     * used to determine if another batched write is already
737     * in-flight.
738     */
739    private final StringBuilder mStrictModeBuffer = new StringBuilder();
740
741    /**
742     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
743     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
744     */
745    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
746
747    /**
748     * Resolver for broadcast intents to registered receivers.
749     * Holds BroadcastFilter (subclass of IntentFilter).
750     */
751    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
752            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
753        @Override
754        protected boolean allowFilterResult(
755                BroadcastFilter filter, List<BroadcastFilter> dest) {
756            IBinder target = filter.receiverList.receiver.asBinder();
757            for (int i = dest.size() - 1; i >= 0; i--) {
758                if (dest.get(i).receiverList.receiver.asBinder() == target) {
759                    return false;
760                }
761            }
762            return true;
763        }
764
765        @Override
766        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
767            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
768                    || userId == filter.owningUserId) {
769                return super.newResult(filter, match, userId);
770            }
771            return null;
772        }
773
774        @Override
775        protected BroadcastFilter[] newArray(int size) {
776            return new BroadcastFilter[size];
777        }
778
779        @Override
780        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
781            return packageName.equals(filter.packageName);
782        }
783    };
784
785    /**
786     * State of all active sticky broadcasts per user.  Keys are the action of the
787     * sticky Intent, values are an ArrayList of all broadcasted intents with
788     * that action (which should usually be one).  The SparseArray is keyed
789     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
790     * for stickies that are sent to all users.
791     */
792    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
793            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
794
795    final ActiveServices mServices;
796
797    final static class Association {
798        final int mSourceUid;
799        final String mSourceProcess;
800        final int mTargetUid;
801        final ComponentName mTargetComponent;
802        final String mTargetProcess;
803
804        int mCount;
805        long mTime;
806
807        int mNesting;
808        long mStartTime;
809
810        Association(int sourceUid, String sourceProcess, int targetUid,
811                ComponentName targetComponent, String targetProcess) {
812            mSourceUid = sourceUid;
813            mSourceProcess = sourceProcess;
814            mTargetUid = targetUid;
815            mTargetComponent = targetComponent;
816            mTargetProcess = targetProcess;
817        }
818    }
819
820    /**
821     * When service association tracking is enabled, this is all of the associations we
822     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
823     * -> association data.
824     */
825    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
826            mAssociations = new SparseArray<>();
827    boolean mTrackingAssociations;
828
829    /**
830     * Backup/restore process management
831     */
832    String mBackupAppName = null;
833    BackupRecord mBackupTarget = null;
834
835    final ProviderMap mProviderMap;
836
837    /**
838     * List of content providers who have clients waiting for them.  The
839     * application is currently being launched and the provider will be
840     * removed from this list once it is published.
841     */
842    final ArrayList<ContentProviderRecord> mLaunchingProviders
843            = new ArrayList<ContentProviderRecord>();
844
845    /**
846     * File storing persisted {@link #mGrantedUriPermissions}.
847     */
848    private final AtomicFile mGrantFile;
849
850    /** XML constants used in {@link #mGrantFile} */
851    private static final String TAG_URI_GRANTS = "uri-grants";
852    private static final String TAG_URI_GRANT = "uri-grant";
853    private static final String ATTR_USER_HANDLE = "userHandle";
854    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
855    private static final String ATTR_TARGET_USER_ID = "targetUserId";
856    private static final String ATTR_SOURCE_PKG = "sourcePkg";
857    private static final String ATTR_TARGET_PKG = "targetPkg";
858    private static final String ATTR_URI = "uri";
859    private static final String ATTR_MODE_FLAGS = "modeFlags";
860    private static final String ATTR_CREATED_TIME = "createdTime";
861    private static final String ATTR_PREFIX = "prefix";
862
863    /**
864     * Global set of specific {@link Uri} permissions that have been granted.
865     * This optimized lookup structure maps from {@link UriPermission#targetUid}
866     * to {@link UriPermission#uri} to {@link UriPermission}.
867     */
868    @GuardedBy("this")
869    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
870            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
871
872    public static class GrantUri {
873        public final int sourceUserId;
874        public final Uri uri;
875        public boolean prefix;
876
877        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
878            this.sourceUserId = sourceUserId;
879            this.uri = uri;
880            this.prefix = prefix;
881        }
882
883        @Override
884        public int hashCode() {
885            int hashCode = 1;
886            hashCode = 31 * hashCode + sourceUserId;
887            hashCode = 31 * hashCode + uri.hashCode();
888            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
889            return hashCode;
890        }
891
892        @Override
893        public boolean equals(Object o) {
894            if (o instanceof GrantUri) {
895                GrantUri other = (GrantUri) o;
896                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
897                        && prefix == other.prefix;
898            }
899            return false;
900        }
901
902        @Override
903        public String toString() {
904            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
905            if (prefix) result += " [prefix]";
906            return result;
907        }
908
909        public String toSafeString() {
910            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
911            if (prefix) result += " [prefix]";
912            return result;
913        }
914
915        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
916            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
917                    ContentProvider.getUriWithoutUserId(uri), false);
918        }
919    }
920
921    CoreSettingsObserver mCoreSettingsObserver;
922
923    /**
924     * Thread-local storage used to carry caller permissions over through
925     * indirect content-provider access.
926     */
927    private class Identity {
928        public final IBinder token;
929        public final int pid;
930        public final int uid;
931
932        Identity(IBinder _token, int _pid, int _uid) {
933            token = _token;
934            pid = _pid;
935            uid = _uid;
936        }
937    }
938
939    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
940
941    /**
942     * All information we have collected about the runtime performance of
943     * any user id that can impact battery performance.
944     */
945    final BatteryStatsService mBatteryStatsService;
946
947    /**
948     * Information about component usage
949     */
950    UsageStatsManagerInternal mUsageStatsService;
951
952    /**
953     * Access to DeviceIdleController service.
954     */
955    DeviceIdleController.LocalService mLocalDeviceIdleController;
956
957    /**
958     * Information about and control over application operations
959     */
960    final AppOpsService mAppOpsService;
961
962    /**
963     * Save recent tasks information across reboots.
964     */
965    final TaskPersister mTaskPersister;
966
967    /**
968     * Current configuration information.  HistoryRecord objects are given
969     * a reference to this object to indicate which configuration they are
970     * currently running in, so this object must be kept immutable.
971     */
972    Configuration mConfiguration = new Configuration();
973
974    /**
975     * Current sequencing integer of the configuration, for skipping old
976     * configurations.
977     */
978    int mConfigurationSeq = 0;
979
980    boolean mSuppressResizeConfigChanges = false;
981
982    /**
983     * Hardware-reported OpenGLES version.
984     */
985    final int GL_ES_VERSION;
986
987    /**
988     * List of initialization arguments to pass to all processes when binding applications to them.
989     * For example, references to the commonly used services.
990     */
991    HashMap<String, IBinder> mAppBindArgs;
992
993    /**
994     * Temporary to avoid allocations.  Protected by main lock.
995     */
996    final StringBuilder mStringBuilder = new StringBuilder(256);
997
998    /**
999     * Used to control how we initialize the service.
1000     */
1001    ComponentName mTopComponent;
1002    String mTopAction = Intent.ACTION_MAIN;
1003    String mTopData;
1004    boolean mProcessesReady = false;
1005    boolean mSystemReady = false;
1006    boolean mBooting = false;
1007    boolean mCallFinishBooting = false;
1008    boolean mBootAnimationComplete = false;
1009    boolean mWaitingUpdate = false;
1010    boolean mDidUpdate = false;
1011    boolean mOnBattery = false;
1012    boolean mLaunchWarningShown = false;
1013
1014    Context mContext;
1015
1016    int mFactoryTest;
1017
1018    boolean mCheckedForSetup;
1019
1020    /**
1021     * The time at which we will allow normal application switches again,
1022     * after a call to {@link #stopAppSwitches()}.
1023     */
1024    long mAppSwitchesAllowedTime;
1025
1026    /**
1027     * This is set to true after the first switch after mAppSwitchesAllowedTime
1028     * is set; any switches after that will clear the time.
1029     */
1030    boolean mDidAppSwitch;
1031
1032    /**
1033     * Last time (in realtime) at which we checked for power usage.
1034     */
1035    long mLastPowerCheckRealtime;
1036
1037    /**
1038     * Last time (in uptime) at which we checked for power usage.
1039     */
1040    long mLastPowerCheckUptime;
1041
1042    /**
1043     * Set while we are wanting to sleep, to prevent any
1044     * activities from being started/resumed.
1045     */
1046    private boolean mSleeping = false;
1047
1048    /**
1049     * The process state used for processes that are running the top activities.
1050     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1051     */
1052    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1053
1054    /**
1055     * Set while we are running a voice interaction.  This overrides
1056     * sleeping while it is active.
1057     */
1058    private IVoiceInteractionSession mRunningVoice;
1059
1060    /**
1061     * For some direct access we need to power manager.
1062     */
1063    PowerManagerInternal mLocalPowerManager;
1064
1065    /**
1066     * We want to hold a wake lock while running a voice interaction session, since
1067     * this may happen with the screen off and we need to keep the CPU running to
1068     * be able to continue to interact with the user.
1069     */
1070    PowerManager.WakeLock mVoiceWakeLock;
1071
1072    /**
1073     * State of external calls telling us if the device is awake or asleep.
1074     */
1075    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1076
1077    /**
1078     * A list of tokens that cause the top activity to be put to sleep.
1079     * They are used by components that may hide and block interaction with underlying
1080     * activities.
1081     */
1082    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1083
1084    static final int LOCK_SCREEN_HIDDEN = 0;
1085    static final int LOCK_SCREEN_LEAVING = 1;
1086    static final int LOCK_SCREEN_SHOWN = 2;
1087    /**
1088     * State of external call telling us if the lock screen is shown.
1089     */
1090    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1091
1092    /**
1093     * Set if we are shutting down the system, similar to sleeping.
1094     */
1095    boolean mShuttingDown = false;
1096
1097    /**
1098     * Current sequence id for oom_adj computation traversal.
1099     */
1100    int mAdjSeq = 0;
1101
1102    /**
1103     * Current sequence id for process LRU updating.
1104     */
1105    int mLruSeq = 0;
1106
1107    /**
1108     * Keep track of the non-cached/empty process we last found, to help
1109     * determine how to distribute cached/empty processes next time.
1110     */
1111    int mNumNonCachedProcs = 0;
1112
1113    /**
1114     * Keep track of the number of cached hidden procs, to balance oom adj
1115     * distribution between those and empty procs.
1116     */
1117    int mNumCachedHiddenProcs = 0;
1118
1119    /**
1120     * Keep track of the number of service processes we last found, to
1121     * determine on the next iteration which should be B services.
1122     */
1123    int mNumServiceProcs = 0;
1124    int mNewNumAServiceProcs = 0;
1125    int mNewNumServiceProcs = 0;
1126
1127    /**
1128     * Allow the current computed overall memory level of the system to go down?
1129     * This is set to false when we are killing processes for reasons other than
1130     * memory management, so that the now smaller process list will not be taken as
1131     * an indication that memory is tighter.
1132     */
1133    boolean mAllowLowerMemLevel = false;
1134
1135    /**
1136     * The last computed memory level, for holding when we are in a state that
1137     * processes are going away for other reasons.
1138     */
1139    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1140
1141    /**
1142     * The last total number of process we have, to determine if changes actually look
1143     * like a shrinking number of process due to lower RAM.
1144     */
1145    int mLastNumProcesses;
1146
1147    /**
1148     * The uptime of the last time we performed idle maintenance.
1149     */
1150    long mLastIdleTime = SystemClock.uptimeMillis();
1151
1152    /**
1153     * Total time spent with RAM that has been added in the past since the last idle time.
1154     */
1155    long mLowRamTimeSinceLastIdle = 0;
1156
1157    /**
1158     * If RAM is currently low, when that horrible situation started.
1159     */
1160    long mLowRamStartTime = 0;
1161
1162    /**
1163     * For reporting to battery stats the current top application.
1164     */
1165    private String mCurResumedPackage = null;
1166    private int mCurResumedUid = -1;
1167
1168    /**
1169     * For reporting to battery stats the apps currently running foreground
1170     * service.  The ProcessMap is package/uid tuples; each of these contain
1171     * an array of the currently foreground processes.
1172     */
1173    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1174            = new ProcessMap<ArrayList<ProcessRecord>>();
1175
1176    /**
1177     * This is set if we had to do a delayed dexopt of an app before launching
1178     * it, to increase the ANR timeouts in that case.
1179     */
1180    boolean mDidDexOpt;
1181
1182    /**
1183     * Set if the systemServer made a call to enterSafeMode.
1184     */
1185    boolean mSafeMode;
1186
1187    /**
1188     * If true, we are running under a test environment so will sample PSS from processes
1189     * much more rapidly to try to collect better data when the tests are rapidly
1190     * running through apps.
1191     */
1192    boolean mTestPssMode = false;
1193
1194    String mDebugApp = null;
1195    boolean mWaitForDebugger = false;
1196    boolean mDebugTransient = false;
1197    String mOrigDebugApp = null;
1198    boolean mOrigWaitForDebugger = false;
1199    boolean mAlwaysFinishActivities = false;
1200    boolean mForceResizableActivites;
1201    IActivityController mController = null;
1202    String mProfileApp = null;
1203    ProcessRecord mProfileProc = null;
1204    String mProfileFile;
1205    ParcelFileDescriptor mProfileFd;
1206    int mSamplingInterval = 0;
1207    boolean mAutoStopProfiler = false;
1208    int mProfileType = 0;
1209    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1210    String mMemWatchDumpProcName;
1211    String mMemWatchDumpFile;
1212    int mMemWatchDumpPid;
1213    int mMemWatchDumpUid;
1214    String mTrackAllocationApp = null;
1215
1216    final long[] mTmpLong = new long[1];
1217
1218    static final class ProcessChangeItem {
1219        static final int CHANGE_ACTIVITIES = 1<<0;
1220        static final int CHANGE_PROCESS_STATE = 1<<1;
1221        int changes;
1222        int uid;
1223        int pid;
1224        int processState;
1225        boolean foregroundActivities;
1226    }
1227
1228    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1229    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1230
1231    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1232    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1233
1234    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1235    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1236
1237    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1238    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1239
1240    ArraySet<String> mAppsNotReportingCrashes;
1241
1242    /**
1243     * Runtime CPU use collection thread.  This object's lock is used to
1244     * perform synchronization with the thread (notifying it to run).
1245     */
1246    final Thread mProcessCpuThread;
1247
1248    /**
1249     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1250     * Must acquire this object's lock when accessing it.
1251     * NOTE: this lock will be held while doing long operations (trawling
1252     * through all processes in /proc), so it should never be acquired by
1253     * any critical paths such as when holding the main activity manager lock.
1254     */
1255    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1256            MONITOR_THREAD_CPU_USAGE);
1257    final AtomicLong mLastCpuTime = new AtomicLong(0);
1258    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1259
1260    long mLastWriteTime = 0;
1261
1262    /**
1263     * Used to retain an update lock when the foreground activity is in
1264     * immersive mode.
1265     */
1266    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1267
1268    /**
1269     * Set to true after the system has finished booting.
1270     */
1271    boolean mBooted = false;
1272
1273    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1274    int mProcessLimitOverride = -1;
1275
1276    WindowManagerService mWindowManager;
1277
1278    final ActivityThread mSystemThread;
1279
1280    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1281        final ProcessRecord mApp;
1282        final int mPid;
1283        final IApplicationThread mAppThread;
1284
1285        AppDeathRecipient(ProcessRecord app, int pid,
1286                IApplicationThread thread) {
1287            if (DEBUG_ALL) Slog.v(
1288                TAG, "New death recipient " + this
1289                + " for thread " + thread.asBinder());
1290            mApp = app;
1291            mPid = pid;
1292            mAppThread = thread;
1293        }
1294
1295        @Override
1296        public void binderDied() {
1297            if (DEBUG_ALL) Slog.v(
1298                TAG, "Death received in " + this
1299                + " for thread " + mAppThread.asBinder());
1300            synchronized(ActivityManagerService.this) {
1301                appDiedLocked(mApp, mPid, mAppThread, true);
1302            }
1303        }
1304    }
1305
1306    static final int SHOW_ERROR_MSG = 1;
1307    static final int SHOW_NOT_RESPONDING_MSG = 2;
1308    static final int SHOW_FACTORY_ERROR_MSG = 3;
1309    static final int UPDATE_CONFIGURATION_MSG = 4;
1310    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1311    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1312    static final int SERVICE_TIMEOUT_MSG = 12;
1313    static final int UPDATE_TIME_ZONE = 13;
1314    static final int SHOW_UID_ERROR_MSG = 14;
1315    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1316    static final int PROC_START_TIMEOUT_MSG = 20;
1317    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1318    static final int KILL_APPLICATION_MSG = 22;
1319    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1320    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1321    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1322    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1323    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1324    static final int CLEAR_DNS_CACHE_MSG = 28;
1325    static final int UPDATE_HTTP_PROXY_MSG = 29;
1326    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1327    static final int DISPATCH_PROCESSES_CHANGED = 31;
1328    static final int DISPATCH_PROCESS_DIED = 32;
1329    static final int REPORT_MEM_USAGE_MSG = 33;
1330    static final int REPORT_USER_SWITCH_MSG = 34;
1331    static final int CONTINUE_USER_SWITCH_MSG = 35;
1332    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1333    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1334    static final int PERSIST_URI_GRANTS_MSG = 38;
1335    static final int REQUEST_ALL_PSS_MSG = 39;
1336    static final int START_PROFILES_MSG = 40;
1337    static final int UPDATE_TIME = 41;
1338    static final int SYSTEM_USER_START_MSG = 42;
1339    static final int SYSTEM_USER_CURRENT_MSG = 43;
1340    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1341    static final int FINISH_BOOTING_MSG = 45;
1342    static final int START_USER_SWITCH_MSG = 46;
1343    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1344    static final int DISMISS_DIALOG_MSG = 48;
1345    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1346    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1347    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1348    static final int DELETE_DUMPHEAP_MSG = 52;
1349    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1350    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1351    static final int REPORT_TIME_TRACKER_MSG = 55;
1352    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1353    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1354    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1355    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1356
1357    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1358    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1359    static final int FIRST_COMPAT_MODE_MSG = 300;
1360    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1361
1362    CompatModeDialog mCompatModeDialog;
1363    long mLastMemUsageReportTime = 0;
1364
1365    /**
1366     * Flag whether the current user is a "monkey", i.e. whether
1367     * the UI is driven by a UI automation tool.
1368     */
1369    private boolean mUserIsMonkey;
1370
1371    /** Flag whether the device has a Recents UI */
1372    boolean mHasRecents;
1373
1374    /** The dimensions of the thumbnails in the Recents UI. */
1375    int mThumbnailWidth;
1376    int mThumbnailHeight;
1377
1378    final ServiceThread mHandlerThread;
1379    final MainHandler mHandler;
1380    final UiHandler mUiHandler;
1381
1382    final class UiHandler extends Handler {
1383        public UiHandler() {
1384            super(com.android.server.UiThread.get().getLooper(), null, true);
1385        }
1386
1387        @Override
1388        public void handleMessage(Message msg) {
1389            switch (msg.what) {
1390            case SHOW_ERROR_MSG: {
1391                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1392                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1393                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1394                synchronized (ActivityManagerService.this) {
1395                    ProcessRecord proc = (ProcessRecord)data.get("app");
1396                    AppErrorResult res = (AppErrorResult) data.get("result");
1397                    if (proc != null && proc.crashDialog != null) {
1398                        Slog.e(TAG, "App already has crash dialog: " + proc);
1399                        if (res != null) {
1400                            res.set(0);
1401                        }
1402                        return;
1403                    }
1404                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1405                            >= Process.FIRST_APPLICATION_UID
1406                            && proc.pid != MY_PID);
1407                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1408                        isBackground &= (proc.userId != userId);
1409                    }
1410                    if (isBackground && !showBackground) {
1411                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1412                        if (res != null) {
1413                            res.set(0);
1414                        }
1415                        return;
1416                    }
1417                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1418                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1419                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1420                        Dialog d = new AppErrorDialog(mContext,
1421                                ActivityManagerService.this, res, proc);
1422                        d.show();
1423                        proc.crashDialog = d;
1424                    } else {
1425                        // The device is asleep, so just pretend that the user
1426                        // saw a crash dialog and hit "force quit".
1427                        if (res != null) {
1428                            res.set(0);
1429                        }
1430                    }
1431                }
1432
1433                ensureBootCompleted();
1434            } break;
1435            case SHOW_NOT_RESPONDING_MSG: {
1436                synchronized (ActivityManagerService.this) {
1437                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1438                    ProcessRecord proc = (ProcessRecord)data.get("app");
1439                    if (proc != null && proc.anrDialog != null) {
1440                        Slog.e(TAG, "App already has anr dialog: " + proc);
1441                        return;
1442                    }
1443
1444                    Intent intent = new Intent("android.intent.action.ANR");
1445                    if (!mProcessesReady) {
1446                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1447                                | Intent.FLAG_RECEIVER_FOREGROUND);
1448                    }
1449                    broadcastIntentLocked(null, null, intent,
1450                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1451                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1452
1453                    if (mShowDialogs) {
1454                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1455                                mContext, proc, (ActivityRecord)data.get("activity"),
1456                                msg.arg1 != 0);
1457                        d.show();
1458                        proc.anrDialog = d;
1459                    } else {
1460                        // Just kill the app if there is no dialog to be shown.
1461                        killAppAtUsersRequest(proc, null);
1462                    }
1463                }
1464
1465                ensureBootCompleted();
1466            } break;
1467            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1468                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1469                synchronized (ActivityManagerService.this) {
1470                    ProcessRecord proc = (ProcessRecord) data.get("app");
1471                    if (proc == null) {
1472                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1473                        break;
1474                    }
1475                    if (proc.crashDialog != null) {
1476                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1477                        return;
1478                    }
1479                    AppErrorResult res = (AppErrorResult) data.get("result");
1480                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1481                        Dialog d = new StrictModeViolationDialog(mContext,
1482                                ActivityManagerService.this, res, proc);
1483                        d.show();
1484                        proc.crashDialog = d;
1485                    } else {
1486                        // The device is asleep, so just pretend that the user
1487                        // saw a crash dialog and hit "force quit".
1488                        res.set(0);
1489                    }
1490                }
1491                ensureBootCompleted();
1492            } break;
1493            case SHOW_FACTORY_ERROR_MSG: {
1494                Dialog d = new FactoryErrorDialog(
1495                    mContext, msg.getData().getCharSequence("msg"));
1496                d.show();
1497                ensureBootCompleted();
1498            } break;
1499            case WAIT_FOR_DEBUGGER_MSG: {
1500                synchronized (ActivityManagerService.this) {
1501                    ProcessRecord app = (ProcessRecord)msg.obj;
1502                    if (msg.arg1 != 0) {
1503                        if (!app.waitedForDebugger) {
1504                            Dialog d = new AppWaitingForDebuggerDialog(
1505                                    ActivityManagerService.this,
1506                                    mContext, app);
1507                            app.waitDialog = d;
1508                            app.waitedForDebugger = true;
1509                            d.show();
1510                        }
1511                    } else {
1512                        if (app.waitDialog != null) {
1513                            app.waitDialog.dismiss();
1514                            app.waitDialog = null;
1515                        }
1516                    }
1517                }
1518            } break;
1519            case SHOW_UID_ERROR_MSG: {
1520                if (mShowDialogs) {
1521                    AlertDialog d = new BaseErrorDialog(mContext);
1522                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1523                    d.setCancelable(false);
1524                    d.setTitle(mContext.getText(R.string.android_system_label));
1525                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1526                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1527                            obtainMessage(DISMISS_DIALOG_MSG, d));
1528                    d.show();
1529                }
1530            } break;
1531            case SHOW_FINGERPRINT_ERROR_MSG: {
1532                if (mShowDialogs) {
1533                    AlertDialog d = new BaseErrorDialog(mContext);
1534                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1535                    d.setCancelable(false);
1536                    d.setTitle(mContext.getText(R.string.android_system_label));
1537                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1538                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1539                            obtainMessage(DISMISS_DIALOG_MSG, d));
1540                    d.show();
1541                }
1542            } break;
1543            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    ActivityRecord ar = (ActivityRecord) msg.obj;
1546                    if (mCompatModeDialog != null) {
1547                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1548                                ar.info.applicationInfo.packageName)) {
1549                            return;
1550                        }
1551                        mCompatModeDialog.dismiss();
1552                        mCompatModeDialog = null;
1553                    }
1554                    if (ar != null && false) {
1555                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1556                                ar.packageName)) {
1557                            int mode = mCompatModePackages.computeCompatModeLocked(
1558                                    ar.info.applicationInfo);
1559                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1560                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1561                                mCompatModeDialog = new CompatModeDialog(
1562                                        ActivityManagerService.this, mContext,
1563                                        ar.info.applicationInfo);
1564                                mCompatModeDialog.show();
1565                            }
1566                        }
1567                    }
1568                }
1569                break;
1570            }
1571            case START_USER_SWITCH_MSG: {
1572                mUserController.showUserSwitchDialog(msg.arg1, (String) msg.obj);
1573                break;
1574            }
1575            case DISMISS_DIALOG_MSG: {
1576                final Dialog d = (Dialog) msg.obj;
1577                d.dismiss();
1578                break;
1579            }
1580            case DISPATCH_PROCESSES_CHANGED: {
1581                dispatchProcessesChanged();
1582                break;
1583            }
1584            case DISPATCH_PROCESS_DIED: {
1585                final int pid = msg.arg1;
1586                final int uid = msg.arg2;
1587                dispatchProcessDied(pid, uid);
1588                break;
1589            }
1590            case DISPATCH_UIDS_CHANGED_MSG: {
1591                dispatchUidsChanged();
1592            } break;
1593            }
1594        }
1595    }
1596
1597    final class MainHandler extends Handler {
1598        public MainHandler(Looper looper) {
1599            super(looper, null, true);
1600        }
1601
1602        @Override
1603        public void handleMessage(Message msg) {
1604            switch (msg.what) {
1605            case UPDATE_CONFIGURATION_MSG: {
1606                final ContentResolver resolver = mContext.getContentResolver();
1607                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1608                        msg.arg1);
1609            } break;
1610            case GC_BACKGROUND_PROCESSES_MSG: {
1611                synchronized (ActivityManagerService.this) {
1612                    performAppGcsIfAppropriateLocked();
1613                }
1614            } break;
1615            case SERVICE_TIMEOUT_MSG: {
1616                if (mDidDexOpt) {
1617                    mDidDexOpt = false;
1618                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1619                    nmsg.obj = msg.obj;
1620                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1621                    return;
1622                }
1623                mServices.serviceTimeout((ProcessRecord)msg.obj);
1624            } break;
1625            case UPDATE_TIME_ZONE: {
1626                synchronized (ActivityManagerService.this) {
1627                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1628                        ProcessRecord r = mLruProcesses.get(i);
1629                        if (r.thread != null) {
1630                            try {
1631                                r.thread.updateTimeZone();
1632                            } catch (RemoteException ex) {
1633                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1634                            }
1635                        }
1636                    }
1637                }
1638            } break;
1639            case CLEAR_DNS_CACHE_MSG: {
1640                synchronized (ActivityManagerService.this) {
1641                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1642                        ProcessRecord r = mLruProcesses.get(i);
1643                        if (r.thread != null) {
1644                            try {
1645                                r.thread.clearDnsCache();
1646                            } catch (RemoteException ex) {
1647                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1648                            }
1649                        }
1650                    }
1651                }
1652            } break;
1653            case UPDATE_HTTP_PROXY_MSG: {
1654                ProxyInfo proxy = (ProxyInfo)msg.obj;
1655                String host = "";
1656                String port = "";
1657                String exclList = "";
1658                Uri pacFileUrl = Uri.EMPTY;
1659                if (proxy != null) {
1660                    host = proxy.getHost();
1661                    port = Integer.toString(proxy.getPort());
1662                    exclList = proxy.getExclusionListAsString();
1663                    pacFileUrl = proxy.getPacFileUrl();
1664                }
1665                synchronized (ActivityManagerService.this) {
1666                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1667                        ProcessRecord r = mLruProcesses.get(i);
1668                        if (r.thread != null) {
1669                            try {
1670                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1671                            } catch (RemoteException ex) {
1672                                Slog.w(TAG, "Failed to update http proxy for: " +
1673                                        r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678            } break;
1679            case PROC_START_TIMEOUT_MSG: {
1680                if (mDidDexOpt) {
1681                    mDidDexOpt = false;
1682                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1683                    nmsg.obj = msg.obj;
1684                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1685                    return;
1686                }
1687                ProcessRecord app = (ProcessRecord)msg.obj;
1688                synchronized (ActivityManagerService.this) {
1689                    processStartTimedOutLocked(app);
1690                }
1691            } break;
1692            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1693                ProcessRecord app = (ProcessRecord)msg.obj;
1694                synchronized (ActivityManagerService.this) {
1695                    processContentProviderPublishTimedOutLocked(app);
1696                }
1697            } break;
1698            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1701                }
1702            } break;
1703            case KILL_APPLICATION_MSG: {
1704                synchronized (ActivityManagerService.this) {
1705                    int appid = msg.arg1;
1706                    boolean restart = (msg.arg2 == 1);
1707                    Bundle bundle = (Bundle)msg.obj;
1708                    String pkg = bundle.getString("pkg");
1709                    String reason = bundle.getString("reason");
1710                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1711                            false, UserHandle.USER_ALL, reason);
1712                }
1713            } break;
1714            case FINALIZE_PENDING_INTENT_MSG: {
1715                ((PendingIntentRecord)msg.obj).completeFinalize();
1716            } break;
1717            case POST_HEAVY_NOTIFICATION_MSG: {
1718                INotificationManager inm = NotificationManager.getService();
1719                if (inm == null) {
1720                    return;
1721                }
1722
1723                ActivityRecord root = (ActivityRecord)msg.obj;
1724                ProcessRecord process = root.app;
1725                if (process == null) {
1726                    return;
1727                }
1728
1729                try {
1730                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1731                    String text = mContext.getString(R.string.heavy_weight_notification,
1732                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1733                    Notification notification = new Notification.Builder(context)
1734                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1735                            .setWhen(0)
1736                            .setOngoing(true)
1737                            .setTicker(text)
1738                            .setColor(mContext.getColor(
1739                                    com.android.internal.R.color.system_notification_accent_color))
1740                            .setContentTitle(text)
1741                            .setContentText(
1742                                    mContext.getText(R.string.heavy_weight_notification_detail))
1743                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1744                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1745                                    new UserHandle(root.userId)))
1746                            .build();
1747                    try {
1748                        int[] outId = new int[1];
1749                        inm.enqueueNotificationWithTag("android", "android", null,
1750                                R.string.heavy_weight_notification,
1751                                notification, outId, root.userId);
1752                    } catch (RuntimeException e) {
1753                        Slog.w(ActivityManagerService.TAG,
1754                                "Error showing notification for heavy-weight app", e);
1755                    } catch (RemoteException e) {
1756                    }
1757                } catch (NameNotFoundException e) {
1758                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1759                }
1760            } break;
1761            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1762                INotificationManager inm = NotificationManager.getService();
1763                if (inm == null) {
1764                    return;
1765                }
1766                try {
1767                    inm.cancelNotificationWithTag("android", null,
1768                            R.string.heavy_weight_notification,  msg.arg1);
1769                } catch (RuntimeException e) {
1770                    Slog.w(ActivityManagerService.TAG,
1771                            "Error canceling notification for service", e);
1772                } catch (RemoteException e) {
1773                }
1774            } break;
1775            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    checkExcessivePowerUsageLocked(true);
1778                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1779                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1780                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1781                }
1782            } break;
1783            case REPORT_MEM_USAGE_MSG: {
1784                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1785                Thread thread = new Thread() {
1786                    @Override public void run() {
1787                        reportMemUsage(memInfos);
1788                    }
1789                };
1790                thread.start();
1791                break;
1792            }
1793            case REPORT_USER_SWITCH_MSG: {
1794                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1795                break;
1796            }
1797            case CONTINUE_USER_SWITCH_MSG: {
1798                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1799                break;
1800            }
1801            case USER_SWITCH_TIMEOUT_MSG: {
1802                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1803                break;
1804            }
1805            case IMMERSIVE_MODE_LOCK_MSG: {
1806                final boolean nextState = (msg.arg1 != 0);
1807                if (mUpdateLock.isHeld() != nextState) {
1808                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1809                            "Applying new update lock state '" + nextState
1810                            + "' for " + (ActivityRecord)msg.obj);
1811                    if (nextState) {
1812                        mUpdateLock.acquire();
1813                    } else {
1814                        mUpdateLock.release();
1815                    }
1816                }
1817                break;
1818            }
1819            case PERSIST_URI_GRANTS_MSG: {
1820                writeGrantedUriPermissions();
1821                break;
1822            }
1823            case REQUEST_ALL_PSS_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1826                }
1827                break;
1828            }
1829            case START_PROFILES_MSG: {
1830                synchronized (ActivityManagerService.this) {
1831                    mUserController.startProfilesLocked();
1832                }
1833                break;
1834            }
1835            case UPDATE_TIME: {
1836                synchronized (ActivityManagerService.this) {
1837                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1838                        ProcessRecord r = mLruProcesses.get(i);
1839                        if (r.thread != null) {
1840                            try {
1841                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1842                            } catch (RemoteException ex) {
1843                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1844                            }
1845                        }
1846                    }
1847                }
1848                break;
1849            }
1850            case SYSTEM_USER_START_MSG: {
1851                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1852                        Integer.toString(msg.arg1), msg.arg1);
1853                mSystemServiceManager.startUser(msg.arg1);
1854                break;
1855            }
1856            case SYSTEM_USER_CURRENT_MSG: {
1857                mBatteryStatsService.noteEvent(
1858                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1859                        Integer.toString(msg.arg2), msg.arg2);
1860                mBatteryStatsService.noteEvent(
1861                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1862                        Integer.toString(msg.arg1), msg.arg1);
1863                mSystemServiceManager.switchUser(msg.arg1);
1864                break;
1865            }
1866            case ENTER_ANIMATION_COMPLETE_MSG: {
1867                synchronized (ActivityManagerService.this) {
1868                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1869                    if (r != null && r.app != null && r.app.thread != null) {
1870                        try {
1871                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1872                        } catch (RemoteException e) {
1873                        }
1874                    }
1875                }
1876                break;
1877            }
1878            case FINISH_BOOTING_MSG: {
1879                if (msg.arg1 != 0) {
1880                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1881                    finishBooting();
1882                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1883                }
1884                if (msg.arg2 != 0) {
1885                    enableScreenAfterBoot();
1886                }
1887                break;
1888            }
1889            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1890                try {
1891                    Locale l = (Locale) msg.obj;
1892                    IBinder service = ServiceManager.getService("mount");
1893                    IMountService mountService = IMountService.Stub.asInterface(service);
1894                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1895                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1896                } catch (RemoteException e) {
1897                    Log.e(TAG, "Error storing locale for decryption UI", e);
1898                }
1899                break;
1900            }
1901            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1902                synchronized (ActivityManagerService.this) {
1903                    int i = mTaskStackListeners.beginBroadcast();
1904                    while (i > 0) {
1905                        i--;
1906                        try {
1907                            // Make a one-way callback to the listener
1908                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1909                        } catch (RemoteException e){
1910                            // Handled by the RemoteCallbackList
1911                        }
1912                    }
1913                    mTaskStackListeners.finishBroadcast();
1914                }
1915                break;
1916            }
1917            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1918                final int uid = msg.arg1;
1919                final byte[] firstPacket = (byte[]) msg.obj;
1920
1921                synchronized (mPidsSelfLocked) {
1922                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1923                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1924                        if (p.uid == uid) {
1925                            try {
1926                                p.thread.notifyCleartextNetwork(firstPacket);
1927                            } catch (RemoteException ignored) {
1928                            }
1929                        }
1930                    }
1931                }
1932                break;
1933            }
1934            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1935                final String procName;
1936                final int uid;
1937                final long memLimit;
1938                final String reportPackage;
1939                synchronized (ActivityManagerService.this) {
1940                    procName = mMemWatchDumpProcName;
1941                    uid = mMemWatchDumpUid;
1942                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1943                    if (val == null) {
1944                        val = mMemWatchProcesses.get(procName, 0);
1945                    }
1946                    if (val != null) {
1947                        memLimit = val.first;
1948                        reportPackage = val.second;
1949                    } else {
1950                        memLimit = 0;
1951                        reportPackage = null;
1952                    }
1953                }
1954                if (procName == null) {
1955                    return;
1956                }
1957
1958                if (DEBUG_PSS) Slog.d(TAG_PSS,
1959                        "Showing dump heap notification from " + procName + "/" + uid);
1960
1961                INotificationManager inm = NotificationManager.getService();
1962                if (inm == null) {
1963                    return;
1964                }
1965
1966                String text = mContext.getString(R.string.dump_heap_notification, procName);
1967
1968
1969                Intent deleteIntent = new Intent();
1970                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1971                Intent intent = new Intent();
1972                intent.setClassName("android", DumpHeapActivity.class.getName());
1973                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1974                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1975                if (reportPackage != null) {
1976                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1977                }
1978                int userId = UserHandle.getUserId(uid);
1979                Notification notification = new Notification.Builder(mContext)
1980                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1981                        .setWhen(0)
1982                        .setOngoing(true)
1983                        .setAutoCancel(true)
1984                        .setTicker(text)
1985                        .setColor(mContext.getColor(
1986                                com.android.internal.R.color.system_notification_accent_color))
1987                        .setContentTitle(text)
1988                        .setContentText(
1989                                mContext.getText(R.string.dump_heap_notification_detail))
1990                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1991                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1992                                new UserHandle(userId)))
1993                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1994                                deleteIntent, 0, UserHandle.SYSTEM))
1995                        .build();
1996
1997                try {
1998                    int[] outId = new int[1];
1999                    inm.enqueueNotificationWithTag("android", "android", null,
2000                            R.string.dump_heap_notification,
2001                            notification, outId, userId);
2002                } catch (RuntimeException e) {
2003                    Slog.w(ActivityManagerService.TAG,
2004                            "Error showing notification for dump heap", e);
2005                } catch (RemoteException e) {
2006                }
2007            } break;
2008            case DELETE_DUMPHEAP_MSG: {
2009                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2010                        DumpHeapActivity.JAVA_URI,
2011                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2012                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2013                        UserHandle.myUserId());
2014                synchronized (ActivityManagerService.this) {
2015                    mMemWatchDumpFile = null;
2016                    mMemWatchDumpProcName = null;
2017                    mMemWatchDumpPid = -1;
2018                    mMemWatchDumpUid = -1;
2019                }
2020            } break;
2021            case FOREGROUND_PROFILE_CHANGED_MSG: {
2022                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2023            } break;
2024            case REPORT_TIME_TRACKER_MSG: {
2025                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2026                tracker.deliverResult(mContext);
2027            } break;
2028            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2029                mUserController.dispatchUserSwitchComplete(msg.arg1);
2030            } break;
2031            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2032                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2033                try {
2034                    connection.shutdown();
2035                } catch (RemoteException e) {
2036                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2037                }
2038                // Only a UiAutomation can set this flag and now that
2039                // it is finished we make sure it is reset to its default.
2040                mUserIsMonkey = false;
2041            } break;
2042            case APP_BOOST_DEACTIVATE_MSG : {
2043                synchronized(ActivityManagerService.this) {
2044                    if (mIsBoosted) {
2045                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2046                            nativeMigrateFromBoost();
2047                            mIsBoosted = false;
2048                            mBoostStartTime = 0;
2049                        } else {
2050                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2051                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2052                        }
2053                    }
2054                }
2055            } break;
2056            }
2057        }
2058    };
2059
2060    static final int COLLECT_PSS_BG_MSG = 1;
2061
2062    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2063        @Override
2064        public void handleMessage(Message msg) {
2065            switch (msg.what) {
2066            case COLLECT_PSS_BG_MSG: {
2067                long start = SystemClock.uptimeMillis();
2068                MemInfoReader memInfo = null;
2069                synchronized (ActivityManagerService.this) {
2070                    if (mFullPssPending) {
2071                        mFullPssPending = false;
2072                        memInfo = new MemInfoReader();
2073                    }
2074                }
2075                if (memInfo != null) {
2076                    updateCpuStatsNow();
2077                    long nativeTotalPss = 0;
2078                    synchronized (mProcessCpuTracker) {
2079                        final int N = mProcessCpuTracker.countStats();
2080                        for (int j=0; j<N; j++) {
2081                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2082                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2083                                // This is definitely an application process; skip it.
2084                                continue;
2085                            }
2086                            synchronized (mPidsSelfLocked) {
2087                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2088                                    // This is one of our own processes; skip it.
2089                                    continue;
2090                                }
2091                            }
2092                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2093                        }
2094                    }
2095                    memInfo.readMemInfo();
2096                    synchronized (ActivityManagerService.this) {
2097                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2098                                + (SystemClock.uptimeMillis()-start) + "ms");
2099                        final long cachedKb = memInfo.getCachedSizeKb();
2100                        final long freeKb = memInfo.getFreeSizeKb();
2101                        final long zramKb = memInfo.getZramTotalSizeKb();
2102                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2103                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2104                                kernelKb*1024, nativeTotalPss*1024);
2105                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2106                                nativeTotalPss);
2107                    }
2108                }
2109
2110                int num = 0;
2111                long[] tmp = new long[1];
2112                do {
2113                    ProcessRecord proc;
2114                    int procState;
2115                    int pid;
2116                    long lastPssTime;
2117                    synchronized (ActivityManagerService.this) {
2118                        if (mPendingPssProcesses.size() <= 0) {
2119                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2120                                    "Collected PSS of " + num + " processes in "
2121                                    + (SystemClock.uptimeMillis() - start) + "ms");
2122                            mPendingPssProcesses.clear();
2123                            return;
2124                        }
2125                        proc = mPendingPssProcesses.remove(0);
2126                        procState = proc.pssProcState;
2127                        lastPssTime = proc.lastPssTime;
2128                        if (proc.thread != null && procState == proc.setProcState
2129                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2130                                        < SystemClock.uptimeMillis()) {
2131                            pid = proc.pid;
2132                        } else {
2133                            proc = null;
2134                            pid = 0;
2135                        }
2136                    }
2137                    if (proc != null) {
2138                        long pss = Debug.getPss(pid, tmp, null);
2139                        synchronized (ActivityManagerService.this) {
2140                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2141                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2142                                num++;
2143                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2144                                        SystemClock.uptimeMillis());
2145                            }
2146                        }
2147                    }
2148                } while (true);
2149            }
2150            }
2151        }
2152    };
2153
2154    public void setSystemProcess() {
2155        try {
2156            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2157            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2158            ServiceManager.addService("meminfo", new MemBinder(this));
2159            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2160            ServiceManager.addService("dbinfo", new DbBinder(this));
2161            if (MONITOR_CPU_USAGE) {
2162                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2163            }
2164            ServiceManager.addService("permission", new PermissionController(this));
2165            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2166
2167            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2168                    "android", STOCK_PM_FLAGS);
2169            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2170
2171            synchronized (this) {
2172                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2173                app.persistent = true;
2174                app.pid = MY_PID;
2175                app.maxAdj = ProcessList.SYSTEM_ADJ;
2176                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2177                synchronized (mPidsSelfLocked) {
2178                    mPidsSelfLocked.put(app.pid, app);
2179                }
2180                updateLruProcessLocked(app, false, null);
2181                updateOomAdjLocked();
2182            }
2183        } catch (PackageManager.NameNotFoundException e) {
2184            throw new RuntimeException(
2185                    "Unable to find android system package", e);
2186        }
2187    }
2188
2189    public void setWindowManager(WindowManagerService wm) {
2190        mWindowManager = wm;
2191        mStackSupervisor.setWindowManager(wm);
2192    }
2193
2194    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2195        mUsageStatsService = usageStatsManager;
2196    }
2197
2198    public void startObservingNativeCrashes() {
2199        final NativeCrashListener ncl = new NativeCrashListener(this);
2200        ncl.start();
2201    }
2202
2203    public IAppOpsService getAppOpsService() {
2204        return mAppOpsService;
2205    }
2206
2207    static class MemBinder extends Binder {
2208        ActivityManagerService mActivityManagerService;
2209        MemBinder(ActivityManagerService activityManagerService) {
2210            mActivityManagerService = activityManagerService;
2211        }
2212
2213        @Override
2214        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2215            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2216                    != PackageManager.PERMISSION_GRANTED) {
2217                pw.println("Permission Denial: can't dump meminfo from from pid="
2218                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2219                        + " without permission " + android.Manifest.permission.DUMP);
2220                return;
2221            }
2222
2223            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2224        }
2225    }
2226
2227    static class GraphicsBinder extends Binder {
2228        ActivityManagerService mActivityManagerService;
2229        GraphicsBinder(ActivityManagerService activityManagerService) {
2230            mActivityManagerService = activityManagerService;
2231        }
2232
2233        @Override
2234        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2235            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2236                    != PackageManager.PERMISSION_GRANTED) {
2237                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2238                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2239                        + " without permission " + android.Manifest.permission.DUMP);
2240                return;
2241            }
2242
2243            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2244        }
2245    }
2246
2247    static class DbBinder extends Binder {
2248        ActivityManagerService mActivityManagerService;
2249        DbBinder(ActivityManagerService activityManagerService) {
2250            mActivityManagerService = activityManagerService;
2251        }
2252
2253        @Override
2254        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2255            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2256                    != PackageManager.PERMISSION_GRANTED) {
2257                pw.println("Permission Denial: can't dump dbinfo from from pid="
2258                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2259                        + " without permission " + android.Manifest.permission.DUMP);
2260                return;
2261            }
2262
2263            mActivityManagerService.dumpDbInfo(fd, pw, args);
2264        }
2265    }
2266
2267    static class CpuBinder extends Binder {
2268        ActivityManagerService mActivityManagerService;
2269        CpuBinder(ActivityManagerService activityManagerService) {
2270            mActivityManagerService = activityManagerService;
2271        }
2272
2273        @Override
2274        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2275            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2276                    != PackageManager.PERMISSION_GRANTED) {
2277                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2278                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2279                        + " without permission " + android.Manifest.permission.DUMP);
2280                return;
2281            }
2282
2283            synchronized (mActivityManagerService.mProcessCpuTracker) {
2284                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2285                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2286                        SystemClock.uptimeMillis()));
2287            }
2288        }
2289    }
2290
2291    public static final class Lifecycle extends SystemService {
2292        private final ActivityManagerService mService;
2293
2294        public Lifecycle(Context context) {
2295            super(context);
2296            mService = new ActivityManagerService(context);
2297        }
2298
2299        @Override
2300        public void onStart() {
2301            mService.start();
2302        }
2303
2304        public ActivityManagerService getService() {
2305            return mService;
2306        }
2307    }
2308
2309    // Note: This method is invoked on the main thread but may need to attach various
2310    // handlers to other threads.  So take care to be explicit about the looper.
2311    public ActivityManagerService(Context systemContext) {
2312        mContext = systemContext;
2313        mFactoryTest = FactoryTest.getMode();
2314        mSystemThread = ActivityThread.currentActivityThread();
2315
2316        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2317
2318        mHandlerThread = new ServiceThread(TAG,
2319                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2320        mHandlerThread.start();
2321        mHandler = new MainHandler(mHandlerThread.getLooper());
2322        mUiHandler = new UiHandler();
2323
2324        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2325                "foreground", BROADCAST_FG_TIMEOUT, false);
2326        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2327                "background", BROADCAST_BG_TIMEOUT, true);
2328        mBroadcastQueues[0] = mFgBroadcastQueue;
2329        mBroadcastQueues[1] = mBgBroadcastQueue;
2330
2331        mServices = new ActiveServices(this);
2332        mProviderMap = new ProviderMap(this);
2333
2334        // TODO: Move creation of battery stats service outside of activity manager service.
2335        File dataDir = Environment.getDataDirectory();
2336        File systemDir = new File(dataDir, "system");
2337        systemDir.mkdirs();
2338        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2339        mBatteryStatsService.getActiveStatistics().readLocked();
2340        mBatteryStatsService.scheduleWriteToDisk();
2341        mOnBattery = DEBUG_POWER ? true
2342                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2343        mBatteryStatsService.getActiveStatistics().setCallback(this);
2344
2345        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2346
2347        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2348
2349        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2350
2351        mUserController = new UserController(this);
2352
2353        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2354            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2355
2356        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2357
2358        mConfiguration.setToDefaults();
2359        mConfiguration.setLocale(Locale.getDefault());
2360
2361        mConfigurationSeq = mConfiguration.seq = 1;
2362        mProcessCpuTracker.init();
2363
2364        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2365        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2366        mRecentTasks = new RecentTasks(this);
2367        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2368        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2369
2370        mProcessCpuThread = new Thread("CpuTracker") {
2371            @Override
2372            public void run() {
2373                while (true) {
2374                    try {
2375                        try {
2376                            synchronized(this) {
2377                                final long now = SystemClock.uptimeMillis();
2378                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2379                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2380                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2381                                //        + ", write delay=" + nextWriteDelay);
2382                                if (nextWriteDelay < nextCpuDelay) {
2383                                    nextCpuDelay = nextWriteDelay;
2384                                }
2385                                if (nextCpuDelay > 0) {
2386                                    mProcessCpuMutexFree.set(true);
2387                                    this.wait(nextCpuDelay);
2388                                }
2389                            }
2390                        } catch (InterruptedException e) {
2391                        }
2392                        updateCpuStatsNow();
2393                    } catch (Exception e) {
2394                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2395                    }
2396                }
2397            }
2398        };
2399
2400        Watchdog.getInstance().addMonitor(this);
2401        Watchdog.getInstance().addThread(mHandler);
2402    }
2403
2404    public void setSystemServiceManager(SystemServiceManager mgr) {
2405        mSystemServiceManager = mgr;
2406    }
2407
2408    public void setInstaller(Installer installer) {
2409        mInstaller = installer;
2410    }
2411
2412    private void start() {
2413        Process.removeAllProcessGroups();
2414        mProcessCpuThread.start();
2415
2416        mBatteryStatsService.publish(mContext);
2417        mAppOpsService.publish(mContext);
2418        Slog.d("AppOps", "AppOpsService published");
2419        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2420    }
2421
2422    public void initPowerManagement() {
2423        mStackSupervisor.initPowerManagement();
2424        mBatteryStatsService.initPowerManagement();
2425        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2426        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2427        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2428        mVoiceWakeLock.setReferenceCounted(false);
2429    }
2430
2431    @Override
2432    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2433            throws RemoteException {
2434        if (code == SYSPROPS_TRANSACTION) {
2435            // We need to tell all apps about the system property change.
2436            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2437            synchronized(this) {
2438                final int NP = mProcessNames.getMap().size();
2439                for (int ip=0; ip<NP; ip++) {
2440                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2441                    final int NA = apps.size();
2442                    for (int ia=0; ia<NA; ia++) {
2443                        ProcessRecord app = apps.valueAt(ia);
2444                        if (app.thread != null) {
2445                            procs.add(app.thread.asBinder());
2446                        }
2447                    }
2448                }
2449            }
2450
2451            int N = procs.size();
2452            for (int i=0; i<N; i++) {
2453                Parcel data2 = Parcel.obtain();
2454                try {
2455                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2456                } catch (RemoteException e) {
2457                }
2458                data2.recycle();
2459            }
2460        }
2461        try {
2462            return super.onTransact(code, data, reply, flags);
2463        } catch (RuntimeException e) {
2464            // The activity manager only throws security exceptions, so let's
2465            // log all others.
2466            if (!(e instanceof SecurityException)) {
2467                Slog.wtf(TAG, "Activity Manager Crash", e);
2468            }
2469            throw e;
2470        }
2471    }
2472
2473    void updateCpuStats() {
2474        final long now = SystemClock.uptimeMillis();
2475        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2476            return;
2477        }
2478        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2479            synchronized (mProcessCpuThread) {
2480                mProcessCpuThread.notify();
2481            }
2482        }
2483    }
2484
2485    void updateCpuStatsNow() {
2486        synchronized (mProcessCpuTracker) {
2487            mProcessCpuMutexFree.set(false);
2488            final long now = SystemClock.uptimeMillis();
2489            boolean haveNewCpuStats = false;
2490
2491            if (MONITOR_CPU_USAGE &&
2492                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2493                mLastCpuTime.set(now);
2494                mProcessCpuTracker.update();
2495                if (mProcessCpuTracker.hasGoodLastStats()) {
2496                    haveNewCpuStats = true;
2497                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2498                    //Slog.i(TAG, "Total CPU usage: "
2499                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2500
2501                    // Slog the cpu usage if the property is set.
2502                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2503                        int user = mProcessCpuTracker.getLastUserTime();
2504                        int system = mProcessCpuTracker.getLastSystemTime();
2505                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2506                        int irq = mProcessCpuTracker.getLastIrqTime();
2507                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2508                        int idle = mProcessCpuTracker.getLastIdleTime();
2509
2510                        int total = user + system + iowait + irq + softIrq + idle;
2511                        if (total == 0) total = 1;
2512
2513                        EventLog.writeEvent(EventLogTags.CPU,
2514                                ((user+system+iowait+irq+softIrq) * 100) / total,
2515                                (user * 100) / total,
2516                                (system * 100) / total,
2517                                (iowait * 100) / total,
2518                                (irq * 100) / total,
2519                                (softIrq * 100) / total);
2520                    }
2521                }
2522            }
2523
2524            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2525            synchronized(bstats) {
2526                synchronized(mPidsSelfLocked) {
2527                    if (haveNewCpuStats) {
2528                        if (bstats.startAddingCpuLocked()) {
2529                            int totalUTime = 0;
2530                            int totalSTime = 0;
2531                            final int N = mProcessCpuTracker.countStats();
2532                            for (int i=0; i<N; i++) {
2533                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2534                                if (!st.working) {
2535                                    continue;
2536                                }
2537                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2538                                totalUTime += st.rel_utime;
2539                                totalSTime += st.rel_stime;
2540                                if (pr != null) {
2541                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2542                                    if (ps == null || !ps.isActive()) {
2543                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2544                                                pr.info.uid, pr.processName);
2545                                    }
2546                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2547                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2548                                } else {
2549                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2550                                    if (ps == null || !ps.isActive()) {
2551                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2552                                                bstats.mapUid(st.uid), st.name);
2553                                    }
2554                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2555                                }
2556                            }
2557                            final int userTime = mProcessCpuTracker.getLastUserTime();
2558                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2559                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2560                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2561                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2562                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2563                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2564                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2565                        }
2566                    }
2567                }
2568
2569                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2570                    mLastWriteTime = now;
2571                    mBatteryStatsService.scheduleWriteToDisk();
2572                }
2573            }
2574        }
2575    }
2576
2577    @Override
2578    public void batteryNeedsCpuUpdate() {
2579        updateCpuStatsNow();
2580    }
2581
2582    @Override
2583    public void batteryPowerChanged(boolean onBattery) {
2584        // When plugging in, update the CPU stats first before changing
2585        // the plug state.
2586        updateCpuStatsNow();
2587        synchronized (this) {
2588            synchronized(mPidsSelfLocked) {
2589                mOnBattery = DEBUG_POWER ? true : onBattery;
2590            }
2591        }
2592    }
2593
2594    @Override
2595    public void batterySendBroadcast(Intent intent) {
2596        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2597                AppOpsManager.OP_NONE, null, false, false,
2598                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2599    }
2600
2601    /**
2602     * Initialize the application bind args. These are passed to each
2603     * process when the bindApplication() IPC is sent to the process. They're
2604     * lazily setup to make sure the services are running when they're asked for.
2605     */
2606    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2607        if (mAppBindArgs == null) {
2608            mAppBindArgs = new HashMap<>();
2609
2610            // Isolated processes won't get this optimization, so that we don't
2611            // violate the rules about which services they have access to.
2612            if (!isolated) {
2613                // Setup the application init args
2614                mAppBindArgs.put("package", ServiceManager.getService("package"));
2615                mAppBindArgs.put("window", ServiceManager.getService("window"));
2616                mAppBindArgs.put(Context.ALARM_SERVICE,
2617                        ServiceManager.getService(Context.ALARM_SERVICE));
2618            }
2619        }
2620        return mAppBindArgs;
2621    }
2622
2623    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2624        if (r != null && mFocusedActivity != r) {
2625            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2626            ActivityRecord last = mFocusedActivity;
2627            mFocusedActivity = r;
2628            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2629                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2630                if (mCurAppTimeTracker != r.appTimeTracker) {
2631                    // We are switching app tracking.  Complete the current one.
2632                    if (mCurAppTimeTracker != null) {
2633                        mCurAppTimeTracker.stop();
2634                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2635                                mCurAppTimeTracker).sendToTarget();
2636                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2637                        mCurAppTimeTracker = null;
2638                    }
2639                    if (r.appTimeTracker != null) {
2640                        mCurAppTimeTracker = r.appTimeTracker;
2641                        startTimeTrackingFocusedActivityLocked();
2642                    }
2643                } else {
2644                    startTimeTrackingFocusedActivityLocked();
2645                }
2646            } else {
2647                r.appTimeTracker = null;
2648            }
2649            if (r.task != null && r.task.voiceInteractor != null) {
2650                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2651            } else {
2652                finishRunningVoiceLocked();
2653                if (last != null && last.task.voiceSession != null) {
2654                    // We had been in a voice interaction session, but now focused has
2655                    // move to something different.  Just finish the session, we can't
2656                    // return to it and retain the proper state and synchronization with
2657                    // the voice interaction service.
2658                    finishVoiceTask(last.task.voiceSession);
2659                }
2660            }
2661            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2662                mWindowManager.setFocusedApp(r.appToken, true);
2663            }
2664            applyUpdateLockStateLocked(r);
2665            if (mFocusedActivity.userId != mLastFocusedUserId) {
2666                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2667                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2668                        mFocusedActivity.userId, 0));
2669                mLastFocusedUserId = mFocusedActivity.userId;
2670            }
2671        }
2672        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2673                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2674                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2675    }
2676
2677    final void clearFocusedActivity(ActivityRecord r) {
2678        if (mFocusedActivity == r) {
2679            ActivityStack stack = mStackSupervisor.getFocusedStack();
2680            if (stack != null) {
2681                ActivityRecord top = stack.topActivity();
2682                if (top != null && top.userId != mLastFocusedUserId) {
2683                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2684                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2685                                    top.userId, 0));
2686                    mLastFocusedUserId = top.userId;
2687                }
2688            }
2689            mFocusedActivity = null;
2690            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2691        }
2692    }
2693
2694    @Override
2695    public void setFocusedStack(int stackId) {
2696        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2697        synchronized (ActivityManagerService.this) {
2698            ActivityStack stack = mStackSupervisor.getStack(stackId);
2699            if (stack != null) {
2700                ActivityRecord r = stack.topRunningActivityLocked();
2701                if (r != null) {
2702                    setFocusedActivityLocked(r, "setFocusedStack");
2703                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2704                }
2705            }
2706        }
2707    }
2708
2709    @Override
2710    public void setFocusedTask(int taskId) {
2711        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2712        long callingId = Binder.clearCallingIdentity();
2713        try {
2714            synchronized (ActivityManagerService.this) {
2715                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2716                if (task != null) {
2717                    ActivityRecord r = task.topRunningActivityLocked();
2718                    if (r != null) {
2719                        setFocusedActivityLocked(r, "setFocusedTask");
2720                        mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2721                    }
2722                }
2723            }
2724        } finally {
2725            Binder.restoreCallingIdentity(callingId);
2726        }
2727    }
2728
2729    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2730    @Override
2731    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2732        synchronized (ActivityManagerService.this) {
2733            if (listener != null) {
2734                mTaskStackListeners.register(listener);
2735            }
2736        }
2737    }
2738
2739    @Override
2740    public void notifyActivityDrawn(IBinder token) {
2741        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2742        synchronized (this) {
2743            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2744            if (r != null) {
2745                r.task.stack.notifyActivityDrawnLocked(r);
2746            }
2747        }
2748    }
2749
2750    final void applyUpdateLockStateLocked(ActivityRecord r) {
2751        // Modifications to the UpdateLock state are done on our handler, outside
2752        // the activity manager's locks.  The new state is determined based on the
2753        // state *now* of the relevant activity record.  The object is passed to
2754        // the handler solely for logging detail, not to be consulted/modified.
2755        final boolean nextState = r != null && r.immersive;
2756        mHandler.sendMessage(
2757                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2758    }
2759
2760    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2761        Message msg = Message.obtain();
2762        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2763        msg.obj = r.task.askedCompatMode ? null : r;
2764        mUiHandler.sendMessage(msg);
2765    }
2766
2767    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2768            String what, Object obj, ProcessRecord srcApp) {
2769        app.lastActivityTime = now;
2770
2771        if (app.activities.size() > 0) {
2772            // Don't want to touch dependent processes that are hosting activities.
2773            return index;
2774        }
2775
2776        int lrui = mLruProcesses.lastIndexOf(app);
2777        if (lrui < 0) {
2778            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2779                    + what + " " + obj + " from " + srcApp);
2780            return index;
2781        }
2782
2783        if (lrui >= index) {
2784            // Don't want to cause this to move dependent processes *back* in the
2785            // list as if they were less frequently used.
2786            return index;
2787        }
2788
2789        if (lrui >= mLruProcessActivityStart) {
2790            // Don't want to touch dependent processes that are hosting activities.
2791            return index;
2792        }
2793
2794        mLruProcesses.remove(lrui);
2795        if (index > 0) {
2796            index--;
2797        }
2798        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2799                + " in LRU list: " + app);
2800        mLruProcesses.add(index, app);
2801        return index;
2802    }
2803
2804    private static void killProcessGroup(int uid, int pid) {
2805        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2806        Process.killProcessGroup(uid, pid);
2807        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2808    }
2809
2810    final void removeLruProcessLocked(ProcessRecord app) {
2811        int lrui = mLruProcesses.lastIndexOf(app);
2812        if (lrui >= 0) {
2813            if (!app.killed) {
2814                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2815                Process.killProcessQuiet(app.pid);
2816                killProcessGroup(app.info.uid, app.pid);
2817            }
2818            if (lrui <= mLruProcessActivityStart) {
2819                mLruProcessActivityStart--;
2820            }
2821            if (lrui <= mLruProcessServiceStart) {
2822                mLruProcessServiceStart--;
2823            }
2824            mLruProcesses.remove(lrui);
2825        }
2826    }
2827
2828    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2829            ProcessRecord client) {
2830        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2831                || app.treatLikeActivity;
2832        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2833        if (!activityChange && hasActivity) {
2834            // The process has activities, so we are only allowing activity-based adjustments
2835            // to move it.  It should be kept in the front of the list with other
2836            // processes that have activities, and we don't want those to change their
2837            // order except due to activity operations.
2838            return;
2839        }
2840
2841        mLruSeq++;
2842        final long now = SystemClock.uptimeMillis();
2843        app.lastActivityTime = now;
2844
2845        // First a quick reject: if the app is already at the position we will
2846        // put it, then there is nothing to do.
2847        if (hasActivity) {
2848            final int N = mLruProcesses.size();
2849            if (N > 0 && mLruProcesses.get(N-1) == app) {
2850                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2851                return;
2852            }
2853        } else {
2854            if (mLruProcessServiceStart > 0
2855                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2856                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2857                return;
2858            }
2859        }
2860
2861        int lrui = mLruProcesses.lastIndexOf(app);
2862
2863        if (app.persistent && lrui >= 0) {
2864            // We don't care about the position of persistent processes, as long as
2865            // they are in the list.
2866            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2867            return;
2868        }
2869
2870        /* In progress: compute new position first, so we can avoid doing work
2871           if the process is not actually going to move.  Not yet working.
2872        int addIndex;
2873        int nextIndex;
2874        boolean inActivity = false, inService = false;
2875        if (hasActivity) {
2876            // Process has activities, put it at the very tipsy-top.
2877            addIndex = mLruProcesses.size();
2878            nextIndex = mLruProcessServiceStart;
2879            inActivity = true;
2880        } else if (hasService) {
2881            // Process has services, put it at the top of the service list.
2882            addIndex = mLruProcessActivityStart;
2883            nextIndex = mLruProcessServiceStart;
2884            inActivity = true;
2885            inService = true;
2886        } else  {
2887            // Process not otherwise of interest, it goes to the top of the non-service area.
2888            addIndex = mLruProcessServiceStart;
2889            if (client != null) {
2890                int clientIndex = mLruProcesses.lastIndexOf(client);
2891                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2892                        + app);
2893                if (clientIndex >= 0 && addIndex > clientIndex) {
2894                    addIndex = clientIndex;
2895                }
2896            }
2897            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2898        }
2899
2900        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2901                + mLruProcessActivityStart + "): " + app);
2902        */
2903
2904        if (lrui >= 0) {
2905            if (lrui < mLruProcessActivityStart) {
2906                mLruProcessActivityStart--;
2907            }
2908            if (lrui < mLruProcessServiceStart) {
2909                mLruProcessServiceStart--;
2910            }
2911            /*
2912            if (addIndex > lrui) {
2913                addIndex--;
2914            }
2915            if (nextIndex > lrui) {
2916                nextIndex--;
2917            }
2918            */
2919            mLruProcesses.remove(lrui);
2920        }
2921
2922        /*
2923        mLruProcesses.add(addIndex, app);
2924        if (inActivity) {
2925            mLruProcessActivityStart++;
2926        }
2927        if (inService) {
2928            mLruProcessActivityStart++;
2929        }
2930        */
2931
2932        int nextIndex;
2933        if (hasActivity) {
2934            final int N = mLruProcesses.size();
2935            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2936                // Process doesn't have activities, but has clients with
2937                // activities...  move it up, but one below the top (the top
2938                // should always have a real activity).
2939                if (DEBUG_LRU) Slog.d(TAG_LRU,
2940                        "Adding to second-top of LRU activity list: " + app);
2941                mLruProcesses.add(N - 1, app);
2942                // To keep it from spamming the LRU list (by making a bunch of clients),
2943                // we will push down any other entries owned by the app.
2944                final int uid = app.info.uid;
2945                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2946                    ProcessRecord subProc = mLruProcesses.get(i);
2947                    if (subProc.info.uid == uid) {
2948                        // We want to push this one down the list.  If the process after
2949                        // it is for the same uid, however, don't do so, because we don't
2950                        // want them internally to be re-ordered.
2951                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2952                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2953                                    "Pushing uid " + uid + " swapping at " + i + ": "
2954                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2955                            ProcessRecord tmp = mLruProcesses.get(i);
2956                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2957                            mLruProcesses.set(i - 1, tmp);
2958                            i--;
2959                        }
2960                    } else {
2961                        // A gap, we can stop here.
2962                        break;
2963                    }
2964                }
2965            } else {
2966                // Process has activities, put it at the very tipsy-top.
2967                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2968                mLruProcesses.add(app);
2969            }
2970            nextIndex = mLruProcessServiceStart;
2971        } else if (hasService) {
2972            // Process has services, put it at the top of the service list.
2973            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2974            mLruProcesses.add(mLruProcessActivityStart, app);
2975            nextIndex = mLruProcessServiceStart;
2976            mLruProcessActivityStart++;
2977        } else  {
2978            // Process not otherwise of interest, it goes to the top of the non-service area.
2979            int index = mLruProcessServiceStart;
2980            if (client != null) {
2981                // If there is a client, don't allow the process to be moved up higher
2982                // in the list than that client.
2983                int clientIndex = mLruProcesses.lastIndexOf(client);
2984                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2985                        + " when updating " + app);
2986                if (clientIndex <= lrui) {
2987                    // Don't allow the client index restriction to push it down farther in the
2988                    // list than it already is.
2989                    clientIndex = lrui;
2990                }
2991                if (clientIndex >= 0 && index > clientIndex) {
2992                    index = clientIndex;
2993                }
2994            }
2995            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2996            mLruProcesses.add(index, app);
2997            nextIndex = index-1;
2998            mLruProcessActivityStart++;
2999            mLruProcessServiceStart++;
3000        }
3001
3002        // If the app is currently using a content provider or service,
3003        // bump those processes as well.
3004        for (int j=app.connections.size()-1; j>=0; j--) {
3005            ConnectionRecord cr = app.connections.valueAt(j);
3006            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3007                    && cr.binding.service.app != null
3008                    && cr.binding.service.app.lruSeq != mLruSeq
3009                    && !cr.binding.service.app.persistent) {
3010                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3011                        "service connection", cr, app);
3012            }
3013        }
3014        for (int j=app.conProviders.size()-1; j>=0; j--) {
3015            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3016            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3017                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3018                        "provider reference", cpr, app);
3019            }
3020        }
3021    }
3022
3023    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3024        if (uid == Process.SYSTEM_UID) {
3025            // The system gets to run in any process.  If there are multiple
3026            // processes with the same uid, just pick the first (this
3027            // should never happen).
3028            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3029            if (procs == null) return null;
3030            final int procCount = procs.size();
3031            for (int i = 0; i < procCount; i++) {
3032                final int procUid = procs.keyAt(i);
3033                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3034                    // Don't use an app process or different user process for system component.
3035                    continue;
3036                }
3037                return procs.valueAt(i);
3038            }
3039        }
3040        ProcessRecord proc = mProcessNames.get(processName, uid);
3041        if (false && proc != null && !keepIfLarge
3042                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3043                && proc.lastCachedPss >= 4000) {
3044            // Turn this condition on to cause killing to happen regularly, for testing.
3045            if (proc.baseProcessTracker != null) {
3046                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3047            }
3048            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3049        } else if (proc != null && !keepIfLarge
3050                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3051                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3052            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3053            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3054                if (proc.baseProcessTracker != null) {
3055                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3056                }
3057                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3058            }
3059        }
3060        return proc;
3061    }
3062
3063    void ensurePackageDexOpt(String packageName) {
3064        IPackageManager pm = AppGlobals.getPackageManager();
3065        try {
3066            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3067                mDidDexOpt = true;
3068            }
3069        } catch (RemoteException e) {
3070        }
3071    }
3072
3073    boolean isNextTransitionForward() {
3074        int transit = mWindowManager.getPendingAppTransition();
3075        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3076                || transit == AppTransition.TRANSIT_TASK_OPEN
3077                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3078    }
3079
3080    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3081            String processName, String abiOverride, int uid, Runnable crashHandler) {
3082        synchronized(this) {
3083            ApplicationInfo info = new ApplicationInfo();
3084            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3085            // For isolated processes, the former contains the parent's uid and the latter the
3086            // actual uid of the isolated process.
3087            // In the special case introduced by this method (which is, starting an isolated
3088            // process directly from the SystemServer without an actual parent app process) the
3089            // closest thing to a parent's uid is SYSTEM_UID.
3090            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3091            // the |isolated| logic in the ProcessRecord constructor.
3092            info.uid = Process.SYSTEM_UID;
3093            info.processName = processName;
3094            info.className = entryPoint;
3095            info.packageName = "android";
3096            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3097                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3098                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3099                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3100                    crashHandler);
3101            return proc != null ? proc.pid : 0;
3102        }
3103    }
3104
3105    final ProcessRecord startProcessLocked(String processName,
3106            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3107            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3108            boolean isolated, boolean keepIfLarge) {
3109        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3110                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3111                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3112                null /* crashHandler */);
3113    }
3114
3115    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3116            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3117            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3118            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3119        long startTime = SystemClock.elapsedRealtime();
3120        ProcessRecord app;
3121        if (!isolated) {
3122            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3123            checkTime(startTime, "startProcess: after getProcessRecord");
3124
3125            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3126                // If we are in the background, then check to see if this process
3127                // is bad.  If so, we will just silently fail.
3128                if (mBadProcesses.get(info.processName, info.uid) != null) {
3129                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3130                            + "/" + info.processName);
3131                    return null;
3132                }
3133            } else {
3134                // When the user is explicitly starting a process, then clear its
3135                // crash count so that we won't make it bad until they see at
3136                // least one crash dialog again, and make the process good again
3137                // if it had been bad.
3138                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3139                        + "/" + info.processName);
3140                mProcessCrashTimes.remove(info.processName, info.uid);
3141                if (mBadProcesses.get(info.processName, info.uid) != null) {
3142                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3143                            UserHandle.getUserId(info.uid), info.uid,
3144                            info.processName);
3145                    mBadProcesses.remove(info.processName, info.uid);
3146                    if (app != null) {
3147                        app.bad = false;
3148                    }
3149                }
3150            }
3151        } else {
3152            // If this is an isolated process, it can't re-use an existing process.
3153            app = null;
3154        }
3155
3156        // app launch boost for big.little configurations
3157        // use cpusets to migrate freshly launched tasks to big cores
3158        synchronized(ActivityManagerService.this) {
3159            nativeMigrateToBoost();
3160            mIsBoosted = true;
3161            mBoostStartTime = SystemClock.uptimeMillis();
3162            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3163            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3164        }
3165
3166        // We don't have to do anything more if:
3167        // (1) There is an existing application record; and
3168        // (2) The caller doesn't think it is dead, OR there is no thread
3169        //     object attached to it so we know it couldn't have crashed; and
3170        // (3) There is a pid assigned to it, so it is either starting or
3171        //     already running.
3172        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3173                + " app=" + app + " knownToBeDead=" + knownToBeDead
3174                + " thread=" + (app != null ? app.thread : null)
3175                + " pid=" + (app != null ? app.pid : -1));
3176        if (app != null && app.pid > 0) {
3177            if (!knownToBeDead || app.thread == null) {
3178                // We already have the app running, or are waiting for it to
3179                // come up (we have a pid but not yet its thread), so keep it.
3180                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3181                // If this is a new package in the process, add the package to the list
3182                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3183                checkTime(startTime, "startProcess: done, added package to proc");
3184                return app;
3185            }
3186
3187            // An application record is attached to a previous process,
3188            // clean it up now.
3189            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3190            checkTime(startTime, "startProcess: bad proc running, killing");
3191            killProcessGroup(app.info.uid, app.pid);
3192            handleAppDiedLocked(app, true, true);
3193            checkTime(startTime, "startProcess: done killing old proc");
3194        }
3195
3196        String hostingNameStr = hostingName != null
3197                ? hostingName.flattenToShortString() : null;
3198
3199        if (app == null) {
3200            checkTime(startTime, "startProcess: creating new process record");
3201            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3202            if (app == null) {
3203                Slog.w(TAG, "Failed making new process record for "
3204                        + processName + "/" + info.uid + " isolated=" + isolated);
3205                return null;
3206            }
3207            app.crashHandler = crashHandler;
3208            checkTime(startTime, "startProcess: done creating new process record");
3209        } else {
3210            // If this is a new package in the process, add the package to the list
3211            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3212            checkTime(startTime, "startProcess: added package to existing proc");
3213        }
3214
3215        // If the system is not ready yet, then hold off on starting this
3216        // process until it is.
3217        if (!mProcessesReady
3218                && !isAllowedWhileBooting(info)
3219                && !allowWhileBooting) {
3220            if (!mProcessesOnHold.contains(app)) {
3221                mProcessesOnHold.add(app);
3222            }
3223            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3224                    "System not ready, putting on hold: " + app);
3225            checkTime(startTime, "startProcess: returning with proc on hold");
3226            return app;
3227        }
3228
3229        checkTime(startTime, "startProcess: stepping in to startProcess");
3230        startProcessLocked(
3231                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3232        checkTime(startTime, "startProcess: done starting proc!");
3233        return (app.pid != 0) ? app : null;
3234    }
3235
3236    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3237        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3238    }
3239
3240    private final void startProcessLocked(ProcessRecord app,
3241            String hostingType, String hostingNameStr) {
3242        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3243                null /* entryPoint */, null /* entryPointArgs */);
3244    }
3245
3246    private final void startProcessLocked(ProcessRecord app, String hostingType,
3247            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3248        long startTime = SystemClock.elapsedRealtime();
3249        if (app.pid > 0 && app.pid != MY_PID) {
3250            checkTime(startTime, "startProcess: removing from pids map");
3251            synchronized (mPidsSelfLocked) {
3252                mPidsSelfLocked.remove(app.pid);
3253                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3254            }
3255            checkTime(startTime, "startProcess: done removing from pids map");
3256            app.setPid(0);
3257        }
3258
3259        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3260                "startProcessLocked removing on hold: " + app);
3261        mProcessesOnHold.remove(app);
3262
3263        checkTime(startTime, "startProcess: starting to update cpu stats");
3264        updateCpuStats();
3265        checkTime(startTime, "startProcess: done updating cpu stats");
3266
3267        try {
3268            try {
3269                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3270                    // This is caught below as if we had failed to fork zygote
3271                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3272                }
3273            } catch (RemoteException e) {
3274                throw e.rethrowAsRuntimeException();
3275            }
3276
3277            int uid = app.uid;
3278            int[] gids = null;
3279            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3280            if (!app.isolated) {
3281                int[] permGids = null;
3282                try {
3283                    checkTime(startTime, "startProcess: getting gids from package manager");
3284                    final IPackageManager pm = AppGlobals.getPackageManager();
3285                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3286                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3287                            MountServiceInternal.class);
3288                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3289                            app.info.packageName);
3290                } catch (RemoteException e) {
3291                    throw e.rethrowAsRuntimeException();
3292                }
3293
3294                /*
3295                 * Add shared application and profile GIDs so applications can share some
3296                 * resources like shared libraries and access user-wide resources
3297                 */
3298                if (ArrayUtils.isEmpty(permGids)) {
3299                    gids = new int[2];
3300                } else {
3301                    gids = new int[permGids.length + 2];
3302                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3303                }
3304                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3305                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3306            }
3307            checkTime(startTime, "startProcess: building args");
3308            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3309                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3310                        && mTopComponent != null
3311                        && app.processName.equals(mTopComponent.getPackageName())) {
3312                    uid = 0;
3313                }
3314                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3315                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3316                    uid = 0;
3317                }
3318            }
3319            int debugFlags = 0;
3320            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3321                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3322                // Also turn on CheckJNI for debuggable apps. It's quite
3323                // awkward to turn on otherwise.
3324                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3325            }
3326            // Run the app in safe mode if its manifest requests so or the
3327            // system is booted in safe mode.
3328            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3329                mSafeMode == true) {
3330                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3331            }
3332            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3333                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3334            }
3335            String jitDebugProperty = SystemProperties.get("debug.usejit");
3336            if ("true".equals(jitDebugProperty)) {
3337                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3338            } else if (!"false".equals(jitDebugProperty)) {
3339                // If we didn't force disable by setting false, defer to the dalvik vm options.
3340                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3341                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3342                }
3343            }
3344            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3345            if ("true".equals(genDebugInfoProperty)) {
3346                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3347            }
3348            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3349                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3350            }
3351            if ("1".equals(SystemProperties.get("debug.assert"))) {
3352                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3353            }
3354
3355            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3356            if (requiredAbi == null) {
3357                requiredAbi = Build.SUPPORTED_ABIS[0];
3358            }
3359
3360            String instructionSet = null;
3361            if (app.info.primaryCpuAbi != null) {
3362                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3363            }
3364
3365            app.gids = gids;
3366            app.requiredAbi = requiredAbi;
3367            app.instructionSet = instructionSet;
3368
3369            // Start the process.  It will either succeed and return a result containing
3370            // the PID of the new process, or else throw a RuntimeException.
3371            boolean isActivityProcess = (entryPoint == null);
3372            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3373            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3374                    app.processName);
3375            checkTime(startTime, "startProcess: asking zygote to start proc");
3376            Process.ProcessStartResult startResult = Process.start(entryPoint,
3377                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3378                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3379                    app.info.dataDir, entryPointArgs);
3380            checkTime(startTime, "startProcess: returned from zygote!");
3381            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3382
3383            if (app.isolated) {
3384                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3385            }
3386            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3387            checkTime(startTime, "startProcess: done updating battery stats");
3388
3389            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3390                    UserHandle.getUserId(uid), startResult.pid, uid,
3391                    app.processName, hostingType,
3392                    hostingNameStr != null ? hostingNameStr : "");
3393
3394            if (app.persistent) {
3395                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3396            }
3397
3398            checkTime(startTime, "startProcess: building log message");
3399            StringBuilder buf = mStringBuilder;
3400            buf.setLength(0);
3401            buf.append("Start proc ");
3402            buf.append(startResult.pid);
3403            buf.append(':');
3404            buf.append(app.processName);
3405            buf.append('/');
3406            UserHandle.formatUid(buf, uid);
3407            if (!isActivityProcess) {
3408                buf.append(" [");
3409                buf.append(entryPoint);
3410                buf.append("]");
3411            }
3412            buf.append(" for ");
3413            buf.append(hostingType);
3414            if (hostingNameStr != null) {
3415                buf.append(" ");
3416                buf.append(hostingNameStr);
3417            }
3418            Slog.i(TAG, buf.toString());
3419            app.setPid(startResult.pid);
3420            app.usingWrapper = startResult.usingWrapper;
3421            app.removed = false;
3422            app.killed = false;
3423            app.killedByAm = false;
3424            checkTime(startTime, "startProcess: starting to update pids map");
3425            synchronized (mPidsSelfLocked) {
3426                this.mPidsSelfLocked.put(startResult.pid, app);
3427                if (isActivityProcess) {
3428                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3429                    msg.obj = app;
3430                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3431                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3432                }
3433            }
3434            checkTime(startTime, "startProcess: done updating pids map");
3435        } catch (RuntimeException e) {
3436            // XXX do better error recovery.
3437            app.setPid(0);
3438            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3439            if (app.isolated) {
3440                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3441            }
3442            Slog.e(TAG, "Failure starting process " + app.processName, e);
3443        }
3444    }
3445
3446    void updateUsageStats(ActivityRecord component, boolean resumed) {
3447        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3448                "updateUsageStats: comp=" + component + "res=" + resumed);
3449        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3450        if (resumed) {
3451            if (mUsageStatsService != null) {
3452                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3453                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3454            }
3455            synchronized (stats) {
3456                stats.noteActivityResumedLocked(component.app.uid);
3457            }
3458        } else {
3459            if (mUsageStatsService != null) {
3460                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3461                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3462            }
3463            synchronized (stats) {
3464                stats.noteActivityPausedLocked(component.app.uid);
3465            }
3466        }
3467    }
3468
3469    Intent getHomeIntent() {
3470        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3471        intent.setComponent(mTopComponent);
3472        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3473            intent.addCategory(Intent.CATEGORY_HOME);
3474        }
3475        return intent;
3476    }
3477
3478    boolean startHomeActivityLocked(int userId, String reason) {
3479        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3480                && mTopAction == null) {
3481            // We are running in factory test mode, but unable to find
3482            // the factory test app, so just sit around displaying the
3483            // error message and don't try to start anything.
3484            return false;
3485        }
3486        Intent intent = getHomeIntent();
3487        ActivityInfo aInfo =
3488            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3489        if (aInfo != null) {
3490            intent.setComponent(new ComponentName(
3491                    aInfo.applicationInfo.packageName, aInfo.name));
3492            // Don't do this if the home app is currently being
3493            // instrumented.
3494            aInfo = new ActivityInfo(aInfo);
3495            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3496            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3497                    aInfo.applicationInfo.uid, true);
3498            if (app == null || app.instrumentationClass == null) {
3499                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3500                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3501            }
3502        }
3503
3504        return true;
3505    }
3506
3507    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3508        ActivityInfo ai = null;
3509        ComponentName comp = intent.getComponent();
3510        try {
3511            if (comp != null) {
3512                // Factory test.
3513                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3514            } else {
3515                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3516                        intent,
3517                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3518                        flags, userId);
3519
3520                if (info != null) {
3521                    ai = info.activityInfo;
3522                }
3523            }
3524        } catch (RemoteException e) {
3525            // ignore
3526        }
3527
3528        return ai;
3529    }
3530
3531    /**
3532     * Starts the "new version setup screen" if appropriate.
3533     */
3534    void startSetupActivityLocked() {
3535        // Only do this once per boot.
3536        if (mCheckedForSetup) {
3537            return;
3538        }
3539
3540        // We will show this screen if the current one is a different
3541        // version than the last one shown, and we are not running in
3542        // low-level factory test mode.
3543        final ContentResolver resolver = mContext.getContentResolver();
3544        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3545                Settings.Global.getInt(resolver,
3546                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3547            mCheckedForSetup = true;
3548
3549            // See if we should be showing the platform update setup UI.
3550            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3551            List<ResolveInfo> ris = mContext.getPackageManager()
3552                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3553
3554            // We don't allow third party apps to replace this.
3555            ResolveInfo ri = null;
3556            for (int i=0; ris != null && i<ris.size(); i++) {
3557                if ((ris.get(i).activityInfo.applicationInfo.flags
3558                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3559                    ri = ris.get(i);
3560                    break;
3561                }
3562            }
3563
3564            if (ri != null) {
3565                String vers = ri.activityInfo.metaData != null
3566                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3567                        : null;
3568                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3569                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3570                            Intent.METADATA_SETUP_VERSION);
3571                }
3572                String lastVers = Settings.Secure.getString(
3573                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3574                if (vers != null && !vers.equals(lastVers)) {
3575                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3576                    intent.setComponent(new ComponentName(
3577                            ri.activityInfo.packageName, ri.activityInfo.name));
3578                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3579                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3580                            null, null, null);
3581                }
3582            }
3583        }
3584    }
3585
3586    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3587        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3588    }
3589
3590    void enforceNotIsolatedCaller(String caller) {
3591        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3592            throw new SecurityException("Isolated process not allowed to call " + caller);
3593        }
3594    }
3595
3596    void enforceShellRestriction(String restriction, int userHandle) {
3597        if (Binder.getCallingUid() == Process.SHELL_UID) {
3598            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3599                throw new SecurityException("Shell does not have permission to access user "
3600                        + userHandle);
3601            }
3602        }
3603    }
3604
3605    @Override
3606    public int getFrontActivityScreenCompatMode() {
3607        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3608        synchronized (this) {
3609            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3610        }
3611    }
3612
3613    @Override
3614    public void setFrontActivityScreenCompatMode(int mode) {
3615        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3616                "setFrontActivityScreenCompatMode");
3617        synchronized (this) {
3618            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3619        }
3620    }
3621
3622    @Override
3623    public int getPackageScreenCompatMode(String packageName) {
3624        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3625        synchronized (this) {
3626            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3627        }
3628    }
3629
3630    @Override
3631    public void setPackageScreenCompatMode(String packageName, int mode) {
3632        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3633                "setPackageScreenCompatMode");
3634        synchronized (this) {
3635            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3636        }
3637    }
3638
3639    @Override
3640    public boolean getPackageAskScreenCompat(String packageName) {
3641        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3642        synchronized (this) {
3643            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3644        }
3645    }
3646
3647    @Override
3648    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3649        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3650                "setPackageAskScreenCompat");
3651        synchronized (this) {
3652            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3653        }
3654    }
3655
3656    private boolean hasUsageStatsPermission(String callingPackage) {
3657        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3658                Binder.getCallingUid(), callingPackage);
3659        if (mode == AppOpsManager.MODE_DEFAULT) {
3660            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3661                    == PackageManager.PERMISSION_GRANTED;
3662        }
3663        return mode == AppOpsManager.MODE_ALLOWED;
3664    }
3665
3666    @Override
3667    public int getPackageProcessState(String packageName, String callingPackage) {
3668        if (!hasUsageStatsPermission(callingPackage)) {
3669            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3670                    "getPackageProcessState");
3671        }
3672
3673        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3674        synchronized (this) {
3675            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3676                final ProcessRecord proc = mLruProcesses.get(i);
3677                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3678                        || procState > proc.setProcState) {
3679                    boolean found = false;
3680                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3681                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3682                            procState = proc.setProcState;
3683                            found = true;
3684                        }
3685                    }
3686                    if (proc.pkgDeps != null && !found) {
3687                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3688                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3689                                procState = proc.setProcState;
3690                                break;
3691                            }
3692                        }
3693                    }
3694                }
3695            }
3696        }
3697        return procState;
3698    }
3699
3700    @Override
3701    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3702        synchronized (this) {
3703            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3704            if (app == null) {
3705                return false;
3706            }
3707            if (app.trimMemoryLevel < level && app.thread != null &&
3708                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3709                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3710                try {
3711                    app.thread.scheduleTrimMemory(level);
3712                    app.trimMemoryLevel = level;
3713                    return true;
3714                } catch (RemoteException e) {
3715                    // Fallthrough to failure case.
3716                }
3717            }
3718        }
3719        return false;
3720    }
3721
3722    private void dispatchProcessesChanged() {
3723        int N;
3724        synchronized (this) {
3725            N = mPendingProcessChanges.size();
3726            if (mActiveProcessChanges.length < N) {
3727                mActiveProcessChanges = new ProcessChangeItem[N];
3728            }
3729            mPendingProcessChanges.toArray(mActiveProcessChanges);
3730            mPendingProcessChanges.clear();
3731            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3732                    "*** Delivering " + N + " process changes");
3733        }
3734
3735        int i = mProcessObservers.beginBroadcast();
3736        while (i > 0) {
3737            i--;
3738            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3739            if (observer != null) {
3740                try {
3741                    for (int j=0; j<N; j++) {
3742                        ProcessChangeItem item = mActiveProcessChanges[j];
3743                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3744                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3745                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3746                                    + item.uid + ": " + item.foregroundActivities);
3747                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3748                                    item.foregroundActivities);
3749                        }
3750                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3751                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3752                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3753                                    + ": " + item.processState);
3754                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3755                        }
3756                    }
3757                } catch (RemoteException e) {
3758                }
3759            }
3760        }
3761        mProcessObservers.finishBroadcast();
3762
3763        synchronized (this) {
3764            for (int j=0; j<N; j++) {
3765                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3766            }
3767        }
3768    }
3769
3770    private void dispatchProcessDied(int pid, int uid) {
3771        int i = mProcessObservers.beginBroadcast();
3772        while (i > 0) {
3773            i--;
3774            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3775            if (observer != null) {
3776                try {
3777                    observer.onProcessDied(pid, uid);
3778                } catch (RemoteException e) {
3779                }
3780            }
3781        }
3782        mProcessObservers.finishBroadcast();
3783    }
3784
3785    private void dispatchUidsChanged() {
3786        int N;
3787        synchronized (this) {
3788            N = mPendingUidChanges.size();
3789            if (mActiveUidChanges.length < N) {
3790                mActiveUidChanges = new UidRecord.ChangeItem[N];
3791            }
3792            for (int i=0; i<N; i++) {
3793                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3794                mActiveUidChanges[i] = change;
3795                change.uidRecord.pendingChange = null;
3796                change.uidRecord = null;
3797            }
3798            mPendingUidChanges.clear();
3799            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3800                    "*** Delivering " + N + " uid changes");
3801        }
3802
3803        if (mLocalPowerManager != null) {
3804            for (int j=0; j<N; j++) {
3805                UidRecord.ChangeItem item = mActiveUidChanges[j];
3806                if (item.gone) {
3807                    mLocalPowerManager.uidGone(item.uid);
3808                } else {
3809                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3810                }
3811            }
3812        }
3813
3814        int i = mUidObservers.beginBroadcast();
3815        while (i > 0) {
3816            i--;
3817            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3818            if (observer != null) {
3819                try {
3820                    for (int j=0; j<N; j++) {
3821                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3822                        if (item.gone) {
3823                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3824                                    "UID gone uid=" + item.uid);
3825                            observer.onUidGone(item.uid);
3826                        } else {
3827                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3828                                    "UID CHANGED uid=" + item.uid
3829                                    + ": " + item.processState);
3830                            observer.onUidStateChanged(item.uid, item.processState);
3831                        }
3832                    }
3833                } catch (RemoteException e) {
3834                }
3835            }
3836        }
3837        mUidObservers.finishBroadcast();
3838
3839        synchronized (this) {
3840            for (int j=0; j<N; j++) {
3841                mAvailUidChanges.add(mActiveUidChanges[j]);
3842            }
3843        }
3844    }
3845
3846    @Override
3847    public final int startActivity(IApplicationThread caller, String callingPackage,
3848            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3849            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
3850        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3851                resultWho, requestCode, startFlags, profilerInfo, bOptions,
3852                UserHandle.getCallingUserId());
3853    }
3854
3855    @Override
3856    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3857            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3858            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3859        enforceNotIsolatedCaller("startActivity");
3860        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3861                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
3862        // TODO: Switch to user app stacks here.
3863        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3864                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3865                profilerInfo, null, null, bOptions, false, userId, null, null);
3866    }
3867
3868    @Override
3869    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3870            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3871            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
3872            int userId) {
3873
3874        // This is very dangerous -- it allows you to perform a start activity (including
3875        // permission grants) as any app that may launch one of your own activities.  So
3876        // we will only allow this to be done from activities that are part of the core framework,
3877        // and then only when they are running as the system.
3878        final ActivityRecord sourceRecord;
3879        final int targetUid;
3880        final String targetPackage;
3881        synchronized (this) {
3882            if (resultTo == null) {
3883                throw new SecurityException("Must be called from an activity");
3884            }
3885            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3886            if (sourceRecord == null) {
3887                throw new SecurityException("Called with bad activity token: " + resultTo);
3888            }
3889            if (!sourceRecord.info.packageName.equals("android")) {
3890                throw new SecurityException(
3891                        "Must be called from an activity that is declared in the android package");
3892            }
3893            if (sourceRecord.app == null) {
3894                throw new SecurityException("Called without a process attached to activity");
3895            }
3896            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3897                // This is still okay, as long as this activity is running under the
3898                // uid of the original calling activity.
3899                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3900                    throw new SecurityException(
3901                            "Calling activity in uid " + sourceRecord.app.uid
3902                                    + " must be system uid or original calling uid "
3903                                    + sourceRecord.launchedFromUid);
3904                }
3905            }
3906            if (ignoreTargetSecurity) {
3907                if (intent.getComponent() == null) {
3908                    throw new SecurityException(
3909                            "Component must be specified with ignoreTargetSecurity");
3910                }
3911                if (intent.getSelector() != null) {
3912                    throw new SecurityException(
3913                            "Selector not allowed with ignoreTargetSecurity");
3914                }
3915            }
3916            targetUid = sourceRecord.launchedFromUid;
3917            targetPackage = sourceRecord.launchedFromPackage;
3918        }
3919
3920        if (userId == UserHandle.USER_NULL) {
3921            userId = UserHandle.getUserId(sourceRecord.app.uid);
3922        }
3923
3924        // TODO: Switch to user app stacks here.
3925        try {
3926            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3927                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3928                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
3929            return ret;
3930        } catch (SecurityException e) {
3931            // XXX need to figure out how to propagate to original app.
3932            // A SecurityException here is generally actually a fault of the original
3933            // calling activity (such as a fairly granting permissions), so propagate it
3934            // back to them.
3935            /*
3936            StringBuilder msg = new StringBuilder();
3937            msg.append("While launching");
3938            msg.append(intent.toString());
3939            msg.append(": ");
3940            msg.append(e.getMessage());
3941            */
3942            throw e;
3943        }
3944    }
3945
3946    @Override
3947    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3948            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3949            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3950        enforceNotIsolatedCaller("startActivityAndWait");
3951        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3952                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3953        WaitResult res = new WaitResult();
3954        // TODO: Switch to user app stacks here.
3955        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3956                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3957                bOptions, false, userId, null, null);
3958        return res;
3959    }
3960
3961    @Override
3962    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3963            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3964            int startFlags, Configuration config, Bundle bOptions, int userId) {
3965        enforceNotIsolatedCaller("startActivityWithConfig");
3966        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3967                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3968        // TODO: Switch to user app stacks here.
3969        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3970                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3971                null, null, config, bOptions, false, userId, null, null);
3972        return ret;
3973    }
3974
3975    @Override
3976    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3977            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3978            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
3979            throws TransactionTooLargeException {
3980        enforceNotIsolatedCaller("startActivityIntentSender");
3981        // Refuse possible leaked file descriptors
3982        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3983            throw new IllegalArgumentException("File descriptors passed in Intent");
3984        }
3985
3986        IIntentSender sender = intent.getTarget();
3987        if (!(sender instanceof PendingIntentRecord)) {
3988            throw new IllegalArgumentException("Bad PendingIntent object");
3989        }
3990
3991        PendingIntentRecord pir = (PendingIntentRecord)sender;
3992
3993        synchronized (this) {
3994            // If this is coming from the currently resumed activity, it is
3995            // effectively saying that app switches are allowed at this point.
3996            final ActivityStack stack = getFocusedStack();
3997            if (stack.mResumedActivity != null &&
3998                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3999                mAppSwitchesAllowedTime = 0;
4000            }
4001        }
4002        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4003                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4004        return ret;
4005    }
4006
4007    @Override
4008    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4009            Intent intent, String resolvedType, IVoiceInteractionSession session,
4010            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4011            Bundle bOptions, int userId) {
4012        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4013                != PackageManager.PERMISSION_GRANTED) {
4014            String msg = "Permission Denial: startVoiceActivity() from pid="
4015                    + Binder.getCallingPid()
4016                    + ", uid=" + Binder.getCallingUid()
4017                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4018            Slog.w(TAG, msg);
4019            throw new SecurityException(msg);
4020        }
4021        if (session == null || interactor == null) {
4022            throw new NullPointerException("null session or interactor");
4023        }
4024        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4025                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4026        // TODO: Switch to user app stacks here.
4027        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4028                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4029                null, bOptions, false, userId, null, null);
4030    }
4031
4032    @Override
4033    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4034        synchronized (this) {
4035            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4036                if (keepAwake) {
4037                    mVoiceWakeLock.acquire();
4038                } else {
4039                    mVoiceWakeLock.release();
4040                }
4041            }
4042        }
4043    }
4044
4045    @Override
4046    public boolean startNextMatchingActivity(IBinder callingActivity,
4047            Intent intent, Bundle bOptions) {
4048        // Refuse possible leaked file descriptors
4049        if (intent != null && intent.hasFileDescriptors() == true) {
4050            throw new IllegalArgumentException("File descriptors passed in Intent");
4051        }
4052        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4053
4054        synchronized (this) {
4055            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4056            if (r == null) {
4057                ActivityOptions.abort(options);
4058                return false;
4059            }
4060            if (r.app == null || r.app.thread == null) {
4061                // The caller is not running...  d'oh!
4062                ActivityOptions.abort(options);
4063                return false;
4064            }
4065            intent = new Intent(intent);
4066            // The caller is not allowed to change the data.
4067            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4068            // And we are resetting to find the next component...
4069            intent.setComponent(null);
4070
4071            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4072
4073            ActivityInfo aInfo = null;
4074            try {
4075                List<ResolveInfo> resolves =
4076                    AppGlobals.getPackageManager().queryIntentActivities(
4077                            intent, r.resolvedType,
4078                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4079                            UserHandle.getCallingUserId());
4080
4081                // Look for the original activity in the list...
4082                final int N = resolves != null ? resolves.size() : 0;
4083                for (int i=0; i<N; i++) {
4084                    ResolveInfo rInfo = resolves.get(i);
4085                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4086                            && rInfo.activityInfo.name.equals(r.info.name)) {
4087                        // We found the current one...  the next matching is
4088                        // after it.
4089                        i++;
4090                        if (i<N) {
4091                            aInfo = resolves.get(i).activityInfo;
4092                        }
4093                        if (debug) {
4094                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4095                                    + "/" + r.info.name);
4096                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4097                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4098                        }
4099                        break;
4100                    }
4101                }
4102            } catch (RemoteException e) {
4103            }
4104
4105            if (aInfo == null) {
4106                // Nobody who is next!
4107                ActivityOptions.abort(options);
4108                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4109                return false;
4110            }
4111
4112            intent.setComponent(new ComponentName(
4113                    aInfo.applicationInfo.packageName, aInfo.name));
4114            intent.setFlags(intent.getFlags()&~(
4115                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4116                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4117                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4118                    Intent.FLAG_ACTIVITY_NEW_TASK));
4119
4120            // Okay now we need to start the new activity, replacing the
4121            // currently running activity.  This is a little tricky because
4122            // we want to start the new one as if the current one is finished,
4123            // but not finish the current one first so that there is no flicker.
4124            // And thus...
4125            final boolean wasFinishing = r.finishing;
4126            r.finishing = true;
4127
4128            // Propagate reply information over to the new activity.
4129            final ActivityRecord resultTo = r.resultTo;
4130            final String resultWho = r.resultWho;
4131            final int requestCode = r.requestCode;
4132            r.resultTo = null;
4133            if (resultTo != null) {
4134                resultTo.removeResultsLocked(r, resultWho, requestCode);
4135            }
4136
4137            final long origId = Binder.clearCallingIdentity();
4138            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4139                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4140                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4141                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4142            Binder.restoreCallingIdentity(origId);
4143
4144            r.finishing = wasFinishing;
4145            if (res != ActivityManager.START_SUCCESS) {
4146                return false;
4147            }
4148            return true;
4149        }
4150    }
4151
4152    @Override
4153    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4154        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4155            String msg = "Permission Denial: startActivityFromRecents called without " +
4156                    START_TASKS_FROM_RECENTS;
4157            Slog.w(TAG, msg);
4158            throw new SecurityException(msg);
4159        }
4160        final long origId = Binder.clearCallingIdentity();
4161        try {
4162            return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4163        } finally {
4164            Binder.restoreCallingIdentity(origId);
4165        }
4166    }
4167
4168    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4169        final TaskRecord task;
4170        final int callingUid;
4171        final String callingPackage;
4172        final Intent intent;
4173        final int userId;
4174        synchronized (this) {
4175            if (launchStackId == HOME_STACK_ID) {
4176                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4177                        + taskId + " can't be launch in the home stack.");
4178            }
4179
4180            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4181            if (task == null) {
4182                throw new IllegalArgumentException(
4183                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4184            }
4185
4186            if (launchStackId != INVALID_STACK_ID && task.stack.mStackId != launchStackId) {
4187                if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4188                    ActivityOptions activityOptions = new ActivityOptions(bOptions);
4189                    mWindowManager.setDockedStackCreateMode(activityOptions.getDockCreateMode());
4190                }
4191                mStackSupervisor.moveTaskToStackLocked(
4192                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents");
4193            }
4194
4195            if (task.getRootActivity() != null) {
4196                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4197                return ActivityManager.START_TASK_TO_FRONT;
4198            }
4199            callingUid = task.mCallingUid;
4200            callingPackage = task.mCallingPackage;
4201            intent = task.intent;
4202            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4203            userId = task.userId;
4204        }
4205        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4206                bOptions, userId, null, task);
4207    }
4208
4209    final int startActivityInPackage(int uid, String callingPackage,
4210            Intent intent, String resolvedType, IBinder resultTo,
4211            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4212            IActivityContainer container, TaskRecord inTask) {
4213
4214        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4215                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4216
4217        // TODO: Switch to user app stacks here.
4218        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4219                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4220                null, null, null, bOptions, false, userId, container, inTask);
4221        return ret;
4222    }
4223
4224    @Override
4225    public final int startActivities(IApplicationThread caller, String callingPackage,
4226            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4227            int userId) {
4228        enforceNotIsolatedCaller("startActivities");
4229        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4230                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4231        // TODO: Switch to user app stacks here.
4232        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4233                resolvedTypes, resultTo, bOptions, userId);
4234        return ret;
4235    }
4236
4237    final int startActivitiesInPackage(int uid, String callingPackage,
4238            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4239            Bundle bOptions, int userId) {
4240
4241        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4242                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4243        // TODO: Switch to user app stacks here.
4244        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4245                resultTo, bOptions, userId);
4246        return ret;
4247    }
4248
4249    @Override
4250    public void reportActivityFullyDrawn(IBinder token) {
4251        synchronized (this) {
4252            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4253            if (r == null) {
4254                return;
4255            }
4256            r.reportFullyDrawnLocked();
4257        }
4258    }
4259
4260    @Override
4261    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4262        synchronized (this) {
4263            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4264            if (r == null) {
4265                return;
4266            }
4267            if (r.task != null && r.task.mResizeable) {
4268                // Fixed screen orientation isn't supported with resizeable activities.
4269                return;
4270            }
4271            final long origId = Binder.clearCallingIdentity();
4272            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4273            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4274                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4275            if (config != null) {
4276                r.frozenBeforeDestroy = true;
4277                if (!updateConfigurationLocked(config, r, false)) {
4278                    mStackSupervisor.resumeTopActivitiesLocked();
4279                }
4280            }
4281            Binder.restoreCallingIdentity(origId);
4282        }
4283    }
4284
4285    @Override
4286    public int getRequestedOrientation(IBinder token) {
4287        synchronized (this) {
4288            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4289            if (r == null) {
4290                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4291            }
4292            return mWindowManager.getAppOrientation(r.appToken);
4293        }
4294    }
4295
4296    /**
4297     * This is the internal entry point for handling Activity.finish().
4298     *
4299     * @param token The Binder token referencing the Activity we want to finish.
4300     * @param resultCode Result code, if any, from this Activity.
4301     * @param resultData Result data (Intent), if any, from this Activity.
4302     * @param finishTask Whether to finish the task associated with this Activity.
4303     *
4304     * @return Returns true if the activity successfully finished, or false if it is still running.
4305     */
4306    @Override
4307    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4308            int finishTask) {
4309        // Refuse possible leaked file descriptors
4310        if (resultData != null && resultData.hasFileDescriptors() == true) {
4311            throw new IllegalArgumentException("File descriptors passed in Intent");
4312        }
4313
4314        synchronized(this) {
4315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4316            if (r == null) {
4317                return true;
4318            }
4319            // Keep track of the root activity of the task before we finish it
4320            TaskRecord tr = r.task;
4321            ActivityRecord rootR = tr.getRootActivity();
4322            if (rootR == null) {
4323                Slog.w(TAG, "Finishing task with all activities already finished");
4324            }
4325            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4326            // finish.
4327            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4328                    mStackSupervisor.isLastLockedTask(tr)) {
4329                Slog.i(TAG, "Not finishing task in lock task mode");
4330                mStackSupervisor.showLockTaskToast();
4331                return false;
4332            }
4333            if (mController != null) {
4334                // Find the first activity that is not finishing.
4335                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4336                if (next != null) {
4337                    // ask watcher if this is allowed
4338                    boolean resumeOK = true;
4339                    try {
4340                        resumeOK = mController.activityResuming(next.packageName);
4341                    } catch (RemoteException e) {
4342                        mController = null;
4343                        Watchdog.getInstance().setActivityController(null);
4344                    }
4345
4346                    if (!resumeOK) {
4347                        Slog.i(TAG, "Not finishing activity because controller resumed");
4348                        return false;
4349                    }
4350                }
4351            }
4352            final long origId = Binder.clearCallingIdentity();
4353            try {
4354                boolean res;
4355                final boolean finishWithRootActivity =
4356                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4357                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4358                        || (finishWithRootActivity && r == rootR)) {
4359                    // If requested, remove the task that is associated to this activity only if it
4360                    // was the root activity in the task. The result code and data is ignored
4361                    // because we don't support returning them across task boundaries. Also, to
4362                    // keep backwards compatibility we remove the task from recents when finishing
4363                    // task with root activity.
4364                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4365                    if (!res) {
4366                        Slog.i(TAG, "Removing task failed to finish activity");
4367                    }
4368                } else {
4369                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4370                            resultData, "app-request", true);
4371                    if (!res) {
4372                        Slog.i(TAG, "Failed to finish by app-request");
4373                    }
4374                }
4375                return res;
4376            } finally {
4377                Binder.restoreCallingIdentity(origId);
4378            }
4379        }
4380    }
4381
4382    @Override
4383    public final void finishHeavyWeightApp() {
4384        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4385                != PackageManager.PERMISSION_GRANTED) {
4386            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4387                    + Binder.getCallingPid()
4388                    + ", uid=" + Binder.getCallingUid()
4389                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4390            Slog.w(TAG, msg);
4391            throw new SecurityException(msg);
4392        }
4393
4394        synchronized(this) {
4395            if (mHeavyWeightProcess == null) {
4396                return;
4397            }
4398
4399            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4400            for (int i = 0; i < activities.size(); i++) {
4401                ActivityRecord r = activities.get(i);
4402                if (!r.finishing && r.isInStackLocked()) {
4403                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4404                            null, "finish-heavy", true);
4405                }
4406            }
4407
4408            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4409                    mHeavyWeightProcess.userId, 0));
4410            mHeavyWeightProcess = null;
4411        }
4412    }
4413
4414    @Override
4415    public void crashApplication(int uid, int initialPid, String packageName,
4416            String message) {
4417        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4418                != PackageManager.PERMISSION_GRANTED) {
4419            String msg = "Permission Denial: crashApplication() from pid="
4420                    + Binder.getCallingPid()
4421                    + ", uid=" + Binder.getCallingUid()
4422                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4423            Slog.w(TAG, msg);
4424            throw new SecurityException(msg);
4425        }
4426
4427        synchronized(this) {
4428            ProcessRecord proc = null;
4429
4430            // Figure out which process to kill.  We don't trust that initialPid
4431            // still has any relation to current pids, so must scan through the
4432            // list.
4433            synchronized (mPidsSelfLocked) {
4434                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4435                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4436                    if (p.uid != uid) {
4437                        continue;
4438                    }
4439                    if (p.pid == initialPid) {
4440                        proc = p;
4441                        break;
4442                    }
4443                    if (p.pkgList.containsKey(packageName)) {
4444                        proc = p;
4445                    }
4446                }
4447            }
4448
4449            if (proc == null) {
4450                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4451                        + " initialPid=" + initialPid
4452                        + " packageName=" + packageName);
4453                return;
4454            }
4455
4456            if (proc.thread != null) {
4457                if (proc.pid == Process.myPid()) {
4458                    Log.w(TAG, "crashApplication: trying to crash self!");
4459                    return;
4460                }
4461                long ident = Binder.clearCallingIdentity();
4462                try {
4463                    proc.thread.scheduleCrash(message);
4464                } catch (RemoteException e) {
4465                }
4466                Binder.restoreCallingIdentity(ident);
4467            }
4468        }
4469    }
4470
4471    @Override
4472    public final void finishSubActivity(IBinder token, String resultWho,
4473            int requestCode) {
4474        synchronized(this) {
4475            final long origId = Binder.clearCallingIdentity();
4476            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4477            if (r != null) {
4478                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4479            }
4480            Binder.restoreCallingIdentity(origId);
4481        }
4482    }
4483
4484    @Override
4485    public boolean finishActivityAffinity(IBinder token) {
4486        synchronized(this) {
4487            final long origId = Binder.clearCallingIdentity();
4488            try {
4489                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4490                if (r == null) {
4491                    return false;
4492                }
4493
4494                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4495                // can finish.
4496                final TaskRecord task = r.task;
4497                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4498                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4499                    mStackSupervisor.showLockTaskToast();
4500                    return false;
4501                }
4502                return task.stack.finishActivityAffinityLocked(r);
4503            } finally {
4504                Binder.restoreCallingIdentity(origId);
4505            }
4506        }
4507    }
4508
4509    @Override
4510    public void finishVoiceTask(IVoiceInteractionSession session) {
4511        synchronized(this) {
4512            final long origId = Binder.clearCallingIdentity();
4513            try {
4514                mStackSupervisor.finishVoiceTask(session);
4515            } finally {
4516                Binder.restoreCallingIdentity(origId);
4517            }
4518        }
4519
4520    }
4521
4522    @Override
4523    public boolean releaseActivityInstance(IBinder token) {
4524        synchronized(this) {
4525            final long origId = Binder.clearCallingIdentity();
4526            try {
4527                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4528                if (r == null) {
4529                    return false;
4530                }
4531                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4532            } finally {
4533                Binder.restoreCallingIdentity(origId);
4534            }
4535        }
4536    }
4537
4538    @Override
4539    public void releaseSomeActivities(IApplicationThread appInt) {
4540        synchronized(this) {
4541            final long origId = Binder.clearCallingIdentity();
4542            try {
4543                ProcessRecord app = getRecordForAppLocked(appInt);
4544                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4545            } finally {
4546                Binder.restoreCallingIdentity(origId);
4547            }
4548        }
4549    }
4550
4551    @Override
4552    public boolean willActivityBeVisible(IBinder token) {
4553        synchronized(this) {
4554            ActivityStack stack = ActivityRecord.getStackLocked(token);
4555            if (stack != null) {
4556                return stack.willActivityBeVisibleLocked(token);
4557            }
4558            return false;
4559        }
4560    }
4561
4562    @Override
4563    public void overridePendingTransition(IBinder token, String packageName,
4564            int enterAnim, int exitAnim) {
4565        synchronized(this) {
4566            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4567            if (self == null) {
4568                return;
4569            }
4570
4571            final long origId = Binder.clearCallingIdentity();
4572
4573            if (self.state == ActivityState.RESUMED
4574                    || self.state == ActivityState.PAUSING) {
4575                mWindowManager.overridePendingAppTransition(packageName,
4576                        enterAnim, exitAnim, null);
4577            }
4578
4579            Binder.restoreCallingIdentity(origId);
4580        }
4581    }
4582
4583    /**
4584     * Main function for removing an existing process from the activity manager
4585     * as a result of that process going away.  Clears out all connections
4586     * to the process.
4587     */
4588    private final void handleAppDiedLocked(ProcessRecord app,
4589            boolean restarting, boolean allowRestart) {
4590        int pid = app.pid;
4591        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4592        if (!kept && !restarting) {
4593            removeLruProcessLocked(app);
4594            if (pid > 0) {
4595                ProcessList.remove(pid);
4596            }
4597        }
4598
4599        if (mProfileProc == app) {
4600            clearProfilerLocked();
4601        }
4602
4603        // Remove this application's activities from active lists.
4604        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4605
4606        app.activities.clear();
4607
4608        if (app.instrumentationClass != null) {
4609            Slog.w(TAG, "Crash of app " + app.processName
4610                  + " running instrumentation " + app.instrumentationClass);
4611            Bundle info = new Bundle();
4612            info.putString("shortMsg", "Process crashed.");
4613            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4614        }
4615
4616        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4617            // If there was nothing to resume, and we are not already
4618            // restarting this process, but there is a visible activity that
4619            // is hosted by the process...  then make sure all visible
4620            // activities are running, taking care of restarting this
4621            // process.
4622            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4623        }
4624    }
4625
4626    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4627        IBinder threadBinder = thread.asBinder();
4628        // Find the application record.
4629        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4630            ProcessRecord rec = mLruProcesses.get(i);
4631            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4632                return i;
4633            }
4634        }
4635        return -1;
4636    }
4637
4638    final ProcessRecord getRecordForAppLocked(
4639            IApplicationThread thread) {
4640        if (thread == null) {
4641            return null;
4642        }
4643
4644        int appIndex = getLRURecordIndexForAppLocked(thread);
4645        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4646    }
4647
4648    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4649        // If there are no longer any background processes running,
4650        // and the app that died was not running instrumentation,
4651        // then tell everyone we are now low on memory.
4652        boolean haveBg = false;
4653        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4654            ProcessRecord rec = mLruProcesses.get(i);
4655            if (rec.thread != null
4656                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4657                haveBg = true;
4658                break;
4659            }
4660        }
4661
4662        if (!haveBg) {
4663            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4664            if (doReport) {
4665                long now = SystemClock.uptimeMillis();
4666                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4667                    doReport = false;
4668                } else {
4669                    mLastMemUsageReportTime = now;
4670                }
4671            }
4672            final ArrayList<ProcessMemInfo> memInfos
4673                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4674            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4675            long now = SystemClock.uptimeMillis();
4676            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4677                ProcessRecord rec = mLruProcesses.get(i);
4678                if (rec == dyingProc || rec.thread == null) {
4679                    continue;
4680                }
4681                if (doReport) {
4682                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4683                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4684                }
4685                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4686                    // The low memory report is overriding any current
4687                    // state for a GC request.  Make sure to do
4688                    // heavy/important/visible/foreground processes first.
4689                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4690                        rec.lastRequestedGc = 0;
4691                    } else {
4692                        rec.lastRequestedGc = rec.lastLowMemory;
4693                    }
4694                    rec.reportLowMemory = true;
4695                    rec.lastLowMemory = now;
4696                    mProcessesToGc.remove(rec);
4697                    addProcessToGcListLocked(rec);
4698                }
4699            }
4700            if (doReport) {
4701                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4702                mHandler.sendMessage(msg);
4703            }
4704            scheduleAppGcsLocked();
4705        }
4706    }
4707
4708    final void appDiedLocked(ProcessRecord app) {
4709       appDiedLocked(app, app.pid, app.thread, false);
4710    }
4711
4712    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4713            boolean fromBinderDied) {
4714        // First check if this ProcessRecord is actually active for the pid.
4715        synchronized (mPidsSelfLocked) {
4716            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4717            if (curProc != app) {
4718                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4719                return;
4720            }
4721        }
4722
4723        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4724        synchronized (stats) {
4725            stats.noteProcessDiedLocked(app.info.uid, pid);
4726        }
4727
4728        if (!app.killed) {
4729            if (!fromBinderDied) {
4730                Process.killProcessQuiet(pid);
4731            }
4732            killProcessGroup(app.info.uid, pid);
4733            app.killed = true;
4734        }
4735
4736        // Clean up already done if the process has been re-started.
4737        if (app.pid == pid && app.thread != null &&
4738                app.thread.asBinder() == thread.asBinder()) {
4739            boolean doLowMem = app.instrumentationClass == null;
4740            boolean doOomAdj = doLowMem;
4741            if (!app.killedByAm) {
4742                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4743                        + ") has died");
4744                mAllowLowerMemLevel = true;
4745            } else {
4746                // Note that we always want to do oom adj to update our state with the
4747                // new number of procs.
4748                mAllowLowerMemLevel = false;
4749                doLowMem = false;
4750            }
4751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4752            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4753                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4754            handleAppDiedLocked(app, false, true);
4755
4756            if (doOomAdj) {
4757                updateOomAdjLocked();
4758            }
4759            if (doLowMem) {
4760                doLowMemReportIfNeededLocked(app);
4761            }
4762        } else if (app.pid != pid) {
4763            // A new process has already been started.
4764            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4765                    + ") has died and restarted (pid " + app.pid + ").");
4766            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4767        } else if (DEBUG_PROCESSES) {
4768            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4769                    + thread.asBinder());
4770        }
4771    }
4772
4773    /**
4774     * If a stack trace dump file is configured, dump process stack traces.
4775     * @param clearTraces causes the dump file to be erased prior to the new
4776     *    traces being written, if true; when false, the new traces will be
4777     *    appended to any existing file content.
4778     * @param firstPids of dalvik VM processes to dump stack traces for first
4779     * @param lastPids of dalvik VM processes to dump stack traces for last
4780     * @param nativeProcs optional list of native process names to dump stack crawls
4781     * @return file containing stack traces, or null if no dump file is configured
4782     */
4783    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4784            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4785        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4786        if (tracesPath == null || tracesPath.length() == 0) {
4787            return null;
4788        }
4789
4790        File tracesFile = new File(tracesPath);
4791        try {
4792            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4793            tracesFile.createNewFile();
4794            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4795        } catch (IOException e) {
4796            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4797            return null;
4798        }
4799
4800        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4801        return tracesFile;
4802    }
4803
4804    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4805            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4806        // Use a FileObserver to detect when traces finish writing.
4807        // The order of traces is considered important to maintain for legibility.
4808        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4809            @Override
4810            public synchronized void onEvent(int event, String path) { notify(); }
4811        };
4812
4813        try {
4814            observer.startWatching();
4815
4816            // First collect all of the stacks of the most important pids.
4817            if (firstPids != null) {
4818                try {
4819                    int num = firstPids.size();
4820                    for (int i = 0; i < num; i++) {
4821                        synchronized (observer) {
4822                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4823                            observer.wait(200);  // Wait for write-close, give up after 200msec
4824                        }
4825                    }
4826                } catch (InterruptedException e) {
4827                    Slog.wtf(TAG, e);
4828                }
4829            }
4830
4831            // Next collect the stacks of the native pids
4832            if (nativeProcs != null) {
4833                int[] pids = Process.getPidsForCommands(nativeProcs);
4834                if (pids != null) {
4835                    for (int pid : pids) {
4836                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4837                    }
4838                }
4839            }
4840
4841            // Lastly, measure CPU usage.
4842            if (processCpuTracker != null) {
4843                processCpuTracker.init();
4844                System.gc();
4845                processCpuTracker.update();
4846                try {
4847                    synchronized (processCpuTracker) {
4848                        processCpuTracker.wait(500); // measure over 1/2 second.
4849                    }
4850                } catch (InterruptedException e) {
4851                }
4852                processCpuTracker.update();
4853
4854                // We'll take the stack crawls of just the top apps using CPU.
4855                final int N = processCpuTracker.countWorkingStats();
4856                int numProcs = 0;
4857                for (int i=0; i<N && numProcs<5; i++) {
4858                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4859                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4860                        numProcs++;
4861                        try {
4862                            synchronized (observer) {
4863                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4864                                observer.wait(200);  // Wait for write-close, give up after 200msec
4865                            }
4866                        } catch (InterruptedException e) {
4867                            Slog.wtf(TAG, e);
4868                        }
4869
4870                    }
4871                }
4872            }
4873        } finally {
4874            observer.stopWatching();
4875        }
4876    }
4877
4878    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4879        if (true || IS_USER_BUILD) {
4880            return;
4881        }
4882        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4883        if (tracesPath == null || tracesPath.length() == 0) {
4884            return;
4885        }
4886
4887        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4888        StrictMode.allowThreadDiskWrites();
4889        try {
4890            final File tracesFile = new File(tracesPath);
4891            final File tracesDir = tracesFile.getParentFile();
4892            final File tracesTmp = new File(tracesDir, "__tmp__");
4893            try {
4894                if (tracesFile.exists()) {
4895                    tracesTmp.delete();
4896                    tracesFile.renameTo(tracesTmp);
4897                }
4898                StringBuilder sb = new StringBuilder();
4899                Time tobj = new Time();
4900                tobj.set(System.currentTimeMillis());
4901                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4902                sb.append(": ");
4903                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4904                sb.append(" since ");
4905                sb.append(msg);
4906                FileOutputStream fos = new FileOutputStream(tracesFile);
4907                fos.write(sb.toString().getBytes());
4908                if (app == null) {
4909                    fos.write("\n*** No application process!".getBytes());
4910                }
4911                fos.close();
4912                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4913            } catch (IOException e) {
4914                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4915                return;
4916            }
4917
4918            if (app != null) {
4919                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4920                firstPids.add(app.pid);
4921                dumpStackTraces(tracesPath, firstPids, null, null, null);
4922            }
4923
4924            File lastTracesFile = null;
4925            File curTracesFile = null;
4926            for (int i=9; i>=0; i--) {
4927                String name = String.format(Locale.US, "slow%02d.txt", i);
4928                curTracesFile = new File(tracesDir, name);
4929                if (curTracesFile.exists()) {
4930                    if (lastTracesFile != null) {
4931                        curTracesFile.renameTo(lastTracesFile);
4932                    } else {
4933                        curTracesFile.delete();
4934                    }
4935                }
4936                lastTracesFile = curTracesFile;
4937            }
4938            tracesFile.renameTo(curTracesFile);
4939            if (tracesTmp.exists()) {
4940                tracesTmp.renameTo(tracesFile);
4941            }
4942        } finally {
4943            StrictMode.setThreadPolicy(oldPolicy);
4944        }
4945    }
4946
4947    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4948            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4949        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4950        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4951
4952        if (mController != null) {
4953            try {
4954                // 0 == continue, -1 = kill process immediately
4955                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4956                if (res < 0 && app.pid != MY_PID) {
4957                    app.kill("anr", true);
4958                }
4959            } catch (RemoteException e) {
4960                mController = null;
4961                Watchdog.getInstance().setActivityController(null);
4962            }
4963        }
4964
4965        long anrTime = SystemClock.uptimeMillis();
4966        if (MONITOR_CPU_USAGE) {
4967            updateCpuStatsNow();
4968        }
4969
4970        synchronized (this) {
4971            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4972            if (mShuttingDown) {
4973                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4974                return;
4975            } else if (app.notResponding) {
4976                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4977                return;
4978            } else if (app.crashing) {
4979                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4980                return;
4981            }
4982
4983            // In case we come through here for the same app before completing
4984            // this one, mark as anring now so we will bail out.
4985            app.notResponding = true;
4986
4987            // Log the ANR to the event log.
4988            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4989                    app.processName, app.info.flags, annotation);
4990
4991            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4992            firstPids.add(app.pid);
4993
4994            int parentPid = app.pid;
4995            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4996            if (parentPid != app.pid) firstPids.add(parentPid);
4997
4998            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4999
5000            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5001                ProcessRecord r = mLruProcesses.get(i);
5002                if (r != null && r.thread != null) {
5003                    int pid = r.pid;
5004                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5005                        if (r.persistent) {
5006                            firstPids.add(pid);
5007                        } else {
5008                            lastPids.put(pid, Boolean.TRUE);
5009                        }
5010                    }
5011                }
5012            }
5013        }
5014
5015        // Log the ANR to the main log.
5016        StringBuilder info = new StringBuilder();
5017        info.setLength(0);
5018        info.append("ANR in ").append(app.processName);
5019        if (activity != null && activity.shortComponentName != null) {
5020            info.append(" (").append(activity.shortComponentName).append(")");
5021        }
5022        info.append("\n");
5023        info.append("PID: ").append(app.pid).append("\n");
5024        if (annotation != null) {
5025            info.append("Reason: ").append(annotation).append("\n");
5026        }
5027        if (parent != null && parent != activity) {
5028            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5029        }
5030
5031        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5032
5033        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5034                NATIVE_STACKS_OF_INTEREST);
5035
5036        String cpuInfo = null;
5037        if (MONITOR_CPU_USAGE) {
5038            updateCpuStatsNow();
5039            synchronized (mProcessCpuTracker) {
5040                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5041            }
5042            info.append(processCpuTracker.printCurrentLoad());
5043            info.append(cpuInfo);
5044        }
5045
5046        info.append(processCpuTracker.printCurrentState(anrTime));
5047
5048        Slog.e(TAG, info.toString());
5049        if (tracesFile == null) {
5050            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5051            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5052        }
5053
5054        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5055                cpuInfo, tracesFile, null);
5056
5057        if (mController != null) {
5058            try {
5059                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5060                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5061                if (res != 0) {
5062                    if (res < 0 && app.pid != MY_PID) {
5063                        app.kill("anr", true);
5064                    } else {
5065                        synchronized (this) {
5066                            mServices.scheduleServiceTimeoutLocked(app);
5067                        }
5068                    }
5069                    return;
5070                }
5071            } catch (RemoteException e) {
5072                mController = null;
5073                Watchdog.getInstance().setActivityController(null);
5074            }
5075        }
5076
5077        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5078        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5079                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5080
5081        synchronized (this) {
5082            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5083
5084            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5085                app.kill("bg anr", true);
5086                return;
5087            }
5088
5089            // Set the app's notResponding state, and look up the errorReportReceiver
5090            makeAppNotRespondingLocked(app,
5091                    activity != null ? activity.shortComponentName : null,
5092                    annotation != null ? "ANR " + annotation : "ANR",
5093                    info.toString());
5094
5095            // Bring up the infamous App Not Responding dialog
5096            Message msg = Message.obtain();
5097            HashMap<String, Object> map = new HashMap<String, Object>();
5098            msg.what = SHOW_NOT_RESPONDING_MSG;
5099            msg.obj = map;
5100            msg.arg1 = aboveSystem ? 1 : 0;
5101            map.put("app", app);
5102            if (activity != null) {
5103                map.put("activity", activity);
5104            }
5105
5106            mUiHandler.sendMessage(msg);
5107        }
5108    }
5109
5110    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5111        if (!mLaunchWarningShown) {
5112            mLaunchWarningShown = true;
5113            mUiHandler.post(new Runnable() {
5114                @Override
5115                public void run() {
5116                    synchronized (ActivityManagerService.this) {
5117                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5118                        d.show();
5119                        mUiHandler.postDelayed(new Runnable() {
5120                            @Override
5121                            public void run() {
5122                                synchronized (ActivityManagerService.this) {
5123                                    d.dismiss();
5124                                    mLaunchWarningShown = false;
5125                                }
5126                            }
5127                        }, 4000);
5128                    }
5129                }
5130            });
5131        }
5132    }
5133
5134    @Override
5135    public boolean clearApplicationUserData(final String packageName,
5136            final IPackageDataObserver observer, int userId) {
5137        enforceNotIsolatedCaller("clearApplicationUserData");
5138        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5139            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5140        }
5141        int uid = Binder.getCallingUid();
5142        int pid = Binder.getCallingPid();
5143        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5144                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5145        long callingId = Binder.clearCallingIdentity();
5146        try {
5147            IPackageManager pm = AppGlobals.getPackageManager();
5148            int pkgUid = -1;
5149            synchronized(this) {
5150                try {
5151                    pkgUid = pm.getPackageUid(packageName, userId);
5152                } catch (RemoteException e) {
5153                }
5154                if (pkgUid == -1) {
5155                    Slog.w(TAG, "Invalid packageName: " + packageName);
5156                    if (observer != null) {
5157                        try {
5158                            observer.onRemoveCompleted(packageName, false);
5159                        } catch (RemoteException e) {
5160                            Slog.i(TAG, "Observer no longer exists.");
5161                        }
5162                    }
5163                    return false;
5164                }
5165                if (uid == pkgUid || checkComponentPermission(
5166                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5167                        pid, uid, -1, true)
5168                        == PackageManager.PERMISSION_GRANTED) {
5169                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5170                } else {
5171                    throw new SecurityException("PID " + pid + " does not have permission "
5172                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5173                                    + " of package " + packageName);
5174                }
5175
5176                // Remove all tasks match the cleared application package and user
5177                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5178                    final TaskRecord tr = mRecentTasks.get(i);
5179                    final String taskPackageName =
5180                            tr.getBaseIntent().getComponent().getPackageName();
5181                    if (tr.userId != userId) continue;
5182                    if (!taskPackageName.equals(packageName)) continue;
5183                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5184                }
5185            }
5186
5187            try {
5188                // Clear application user data
5189                pm.clearApplicationUserData(packageName, observer, userId);
5190
5191                synchronized(this) {
5192                    // Remove all permissions granted from/to this package
5193                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5194                }
5195
5196                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5197                        Uri.fromParts("package", packageName, null));
5198                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5199                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5200                        null, null, 0, null, null, null, null, false, false, userId);
5201            } catch (RemoteException e) {
5202            }
5203        } finally {
5204            Binder.restoreCallingIdentity(callingId);
5205        }
5206        return true;
5207    }
5208
5209    @Override
5210    public void killBackgroundProcesses(final String packageName, int userId) {
5211        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5212                != PackageManager.PERMISSION_GRANTED &&
5213                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5214                        != PackageManager.PERMISSION_GRANTED) {
5215            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5216                    + Binder.getCallingPid()
5217                    + ", uid=" + Binder.getCallingUid()
5218                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5219            Slog.w(TAG, msg);
5220            throw new SecurityException(msg);
5221        }
5222
5223        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5224                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5225        long callingId = Binder.clearCallingIdentity();
5226        try {
5227            IPackageManager pm = AppGlobals.getPackageManager();
5228            synchronized(this) {
5229                int appId = -1;
5230                try {
5231                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5232                } catch (RemoteException e) {
5233                }
5234                if (appId == -1) {
5235                    Slog.w(TAG, "Invalid packageName: " + packageName);
5236                    return;
5237                }
5238                killPackageProcessesLocked(packageName, appId, userId,
5239                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5240            }
5241        } finally {
5242            Binder.restoreCallingIdentity(callingId);
5243        }
5244    }
5245
5246    @Override
5247    public void killAllBackgroundProcesses() {
5248        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5249                != PackageManager.PERMISSION_GRANTED) {
5250            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5251                    + Binder.getCallingPid()
5252                    + ", uid=" + Binder.getCallingUid()
5253                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5254            Slog.w(TAG, msg);
5255            throw new SecurityException(msg);
5256        }
5257
5258        long callingId = Binder.clearCallingIdentity();
5259        try {
5260            synchronized(this) {
5261                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5262                final int NP = mProcessNames.getMap().size();
5263                for (int ip=0; ip<NP; ip++) {
5264                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5265                    final int NA = apps.size();
5266                    for (int ia=0; ia<NA; ia++) {
5267                        ProcessRecord app = apps.valueAt(ia);
5268                        if (app.persistent) {
5269                            // we don't kill persistent processes
5270                            continue;
5271                        }
5272                        if (app.removed) {
5273                            procs.add(app);
5274                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5275                            app.removed = true;
5276                            procs.add(app);
5277                        }
5278                    }
5279                }
5280
5281                int N = procs.size();
5282                for (int i=0; i<N; i++) {
5283                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5284                }
5285                mAllowLowerMemLevel = true;
5286                updateOomAdjLocked();
5287                doLowMemReportIfNeededLocked(null);
5288            }
5289        } finally {
5290            Binder.restoreCallingIdentity(callingId);
5291        }
5292    }
5293
5294    @Override
5295    public void forceStopPackage(final String packageName, int userId) {
5296        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5297                != PackageManager.PERMISSION_GRANTED) {
5298            String msg = "Permission Denial: forceStopPackage() from pid="
5299                    + Binder.getCallingPid()
5300                    + ", uid=" + Binder.getCallingUid()
5301                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5302            Slog.w(TAG, msg);
5303            throw new SecurityException(msg);
5304        }
5305        final int callingPid = Binder.getCallingPid();
5306        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5307                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5308        long callingId = Binder.clearCallingIdentity();
5309        try {
5310            IPackageManager pm = AppGlobals.getPackageManager();
5311            synchronized(this) {
5312                int[] users = userId == UserHandle.USER_ALL
5313                        ? mUserController.getUsers() : new int[] { userId };
5314                for (int user : users) {
5315                    int pkgUid = -1;
5316                    try {
5317                        pkgUid = pm.getPackageUid(packageName, user);
5318                    } catch (RemoteException e) {
5319                    }
5320                    if (pkgUid == -1) {
5321                        Slog.w(TAG, "Invalid packageName: " + packageName);
5322                        continue;
5323                    }
5324                    try {
5325                        pm.setPackageStoppedState(packageName, true, user);
5326                    } catch (RemoteException e) {
5327                    } catch (IllegalArgumentException e) {
5328                        Slog.w(TAG, "Failed trying to unstop package "
5329                                + packageName + ": " + e);
5330                    }
5331                    if (mUserController.isUserRunningLocked(user, false)) {
5332                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5333                    }
5334                }
5335            }
5336        } finally {
5337            Binder.restoreCallingIdentity(callingId);
5338        }
5339    }
5340
5341    @Override
5342    public void addPackageDependency(String packageName) {
5343        synchronized (this) {
5344            int callingPid = Binder.getCallingPid();
5345            if (callingPid == Process.myPid()) {
5346                //  Yeah, um, no.
5347                return;
5348            }
5349            ProcessRecord proc;
5350            synchronized (mPidsSelfLocked) {
5351                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5352            }
5353            if (proc != null) {
5354                if (proc.pkgDeps == null) {
5355                    proc.pkgDeps = new ArraySet<String>(1);
5356                }
5357                proc.pkgDeps.add(packageName);
5358            }
5359        }
5360    }
5361
5362    /*
5363     * The pkg name and app id have to be specified.
5364     */
5365    @Override
5366    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5367        if (pkg == null) {
5368            return;
5369        }
5370        // Make sure the uid is valid.
5371        if (appid < 0) {
5372            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5373            return;
5374        }
5375        int callerUid = Binder.getCallingUid();
5376        // Only the system server can kill an application
5377        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5378            // Post an aysnc message to kill the application
5379            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5380            msg.arg1 = appid;
5381            msg.arg2 = 0;
5382            Bundle bundle = new Bundle();
5383            bundle.putString("pkg", pkg);
5384            bundle.putString("reason", reason);
5385            msg.obj = bundle;
5386            mHandler.sendMessage(msg);
5387        } else {
5388            throw new SecurityException(callerUid + " cannot kill pkg: " +
5389                    pkg);
5390        }
5391    }
5392
5393    @Override
5394    public void closeSystemDialogs(String reason) {
5395        enforceNotIsolatedCaller("closeSystemDialogs");
5396
5397        final int pid = Binder.getCallingPid();
5398        final int uid = Binder.getCallingUid();
5399        final long origId = Binder.clearCallingIdentity();
5400        try {
5401            synchronized (this) {
5402                // Only allow this from foreground processes, so that background
5403                // applications can't abuse it to prevent system UI from being shown.
5404                if (uid >= Process.FIRST_APPLICATION_UID) {
5405                    ProcessRecord proc;
5406                    synchronized (mPidsSelfLocked) {
5407                        proc = mPidsSelfLocked.get(pid);
5408                    }
5409                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5410                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5411                                + " from background process " + proc);
5412                        return;
5413                    }
5414                }
5415                closeSystemDialogsLocked(reason);
5416            }
5417        } finally {
5418            Binder.restoreCallingIdentity(origId);
5419        }
5420    }
5421
5422    void closeSystemDialogsLocked(String reason) {
5423        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5424        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5425                | Intent.FLAG_RECEIVER_FOREGROUND);
5426        if (reason != null) {
5427            intent.putExtra("reason", reason);
5428        }
5429        mWindowManager.closeSystemDialogs(reason);
5430
5431        mStackSupervisor.closeSystemDialogsLocked();
5432
5433        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5434                AppOpsManager.OP_NONE, null, false, false,
5435                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5436    }
5437
5438    @Override
5439    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5440        enforceNotIsolatedCaller("getProcessMemoryInfo");
5441        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5442        for (int i=pids.length-1; i>=0; i--) {
5443            ProcessRecord proc;
5444            int oomAdj;
5445            synchronized (this) {
5446                synchronized (mPidsSelfLocked) {
5447                    proc = mPidsSelfLocked.get(pids[i]);
5448                    oomAdj = proc != null ? proc.setAdj : 0;
5449                }
5450            }
5451            infos[i] = new Debug.MemoryInfo();
5452            Debug.getMemoryInfo(pids[i], infos[i]);
5453            if (proc != null) {
5454                synchronized (this) {
5455                    if (proc.thread != null && proc.setAdj == oomAdj) {
5456                        // Record this for posterity if the process has been stable.
5457                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5458                                infos[i].getTotalUss(), false, proc.pkgList);
5459                    }
5460                }
5461            }
5462        }
5463        return infos;
5464    }
5465
5466    @Override
5467    public long[] getProcessPss(int[] pids) {
5468        enforceNotIsolatedCaller("getProcessPss");
5469        long[] pss = new long[pids.length];
5470        for (int i=pids.length-1; i>=0; i--) {
5471            ProcessRecord proc;
5472            int oomAdj;
5473            synchronized (this) {
5474                synchronized (mPidsSelfLocked) {
5475                    proc = mPidsSelfLocked.get(pids[i]);
5476                    oomAdj = proc != null ? proc.setAdj : 0;
5477                }
5478            }
5479            long[] tmpUss = new long[1];
5480            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5481            if (proc != null) {
5482                synchronized (this) {
5483                    if (proc.thread != null && proc.setAdj == oomAdj) {
5484                        // Record this for posterity if the process has been stable.
5485                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5486                    }
5487                }
5488            }
5489        }
5490        return pss;
5491    }
5492
5493    @Override
5494    public void killApplicationProcess(String processName, int uid) {
5495        if (processName == null) {
5496            return;
5497        }
5498
5499        int callerUid = Binder.getCallingUid();
5500        // Only the system server can kill an application
5501        if (callerUid == Process.SYSTEM_UID) {
5502            synchronized (this) {
5503                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5504                if (app != null && app.thread != null) {
5505                    try {
5506                        app.thread.scheduleSuicide();
5507                    } catch (RemoteException e) {
5508                        // If the other end already died, then our work here is done.
5509                    }
5510                } else {
5511                    Slog.w(TAG, "Process/uid not found attempting kill of "
5512                            + processName + " / " + uid);
5513                }
5514            }
5515        } else {
5516            throw new SecurityException(callerUid + " cannot kill app process: " +
5517                    processName);
5518        }
5519    }
5520
5521    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5522        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5523                false, true, false, false, UserHandle.getUserId(uid), reason);
5524        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5525                Uri.fromParts("package", packageName, null));
5526        if (!mProcessesReady) {
5527            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5528                    | Intent.FLAG_RECEIVER_FOREGROUND);
5529        }
5530        intent.putExtra(Intent.EXTRA_UID, uid);
5531        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5532        broadcastIntentLocked(null, null, intent,
5533                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5534                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5535    }
5536
5537
5538    private final boolean killPackageProcessesLocked(String packageName, int appId,
5539            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5540            boolean doit, boolean evenPersistent, String reason) {
5541        ArrayList<ProcessRecord> procs = new ArrayList<>();
5542
5543        // Remove all processes this package may have touched: all with the
5544        // same UID (except for the system or root user), and all whose name
5545        // matches the package name.
5546        final int NP = mProcessNames.getMap().size();
5547        for (int ip=0; ip<NP; ip++) {
5548            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5549            final int NA = apps.size();
5550            for (int ia=0; ia<NA; ia++) {
5551                ProcessRecord app = apps.valueAt(ia);
5552                if (app.persistent && !evenPersistent) {
5553                    // we don't kill persistent processes
5554                    continue;
5555                }
5556                if (app.removed) {
5557                    if (doit) {
5558                        procs.add(app);
5559                    }
5560                    continue;
5561                }
5562
5563                // Skip process if it doesn't meet our oom adj requirement.
5564                if (app.setAdj < minOomAdj) {
5565                    continue;
5566                }
5567
5568                // If no package is specified, we call all processes under the
5569                // give user id.
5570                if (packageName == null) {
5571                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5572                        continue;
5573                    }
5574                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5575                        continue;
5576                    }
5577                // Package has been specified, we want to hit all processes
5578                // that match it.  We need to qualify this by the processes
5579                // that are running under the specified app and user ID.
5580                } else {
5581                    final boolean isDep = app.pkgDeps != null
5582                            && app.pkgDeps.contains(packageName);
5583                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5584                        continue;
5585                    }
5586                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5587                        continue;
5588                    }
5589                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5590                        continue;
5591                    }
5592                }
5593
5594                // Process has passed all conditions, kill it!
5595                if (!doit) {
5596                    return true;
5597                }
5598                app.removed = true;
5599                procs.add(app);
5600            }
5601        }
5602
5603        int N = procs.size();
5604        for (int i=0; i<N; i++) {
5605            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5606        }
5607        updateOomAdjLocked();
5608        return N > 0;
5609    }
5610
5611    private void cleanupDisabledPackageComponentsLocked(
5612            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5613
5614        Set<String> disabledClasses = null;
5615        boolean packageDisabled = false;
5616        IPackageManager pm = AppGlobals.getPackageManager();
5617
5618        if (changedClasses == null) {
5619            // Nothing changed...
5620            return;
5621        }
5622
5623        // Determine enable/disable state of the package and its components.
5624        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5625        for (int i = changedClasses.length - 1; i >= 0; i--) {
5626            final String changedClass = changedClasses[i];
5627
5628            if (changedClass.equals(packageName)) {
5629                try {
5630                    // Entire package setting changed
5631                    enabled = pm.getApplicationEnabledSetting(packageName,
5632                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5633                } catch (Exception e) {
5634                    // No such package/component; probably racing with uninstall.  In any
5635                    // event it means we have nothing further to do here.
5636                    return;
5637                }
5638                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5639                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5640                if (packageDisabled) {
5641                    // Entire package is disabled.
5642                    // No need to continue to check component states.
5643                    disabledClasses = null;
5644                    break;
5645                }
5646            } else {
5647                try {
5648                    enabled = pm.getComponentEnabledSetting(
5649                            new ComponentName(packageName, changedClass),
5650                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5651                } catch (Exception e) {
5652                    // As above, probably racing with uninstall.
5653                    return;
5654                }
5655                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5656                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5657                    if (disabledClasses == null) {
5658                        disabledClasses = new ArraySet<>(changedClasses.length);
5659                    }
5660                    disabledClasses.add(changedClass);
5661                }
5662            }
5663        }
5664
5665        if (!packageDisabled && disabledClasses == null) {
5666            // Nothing to do here...
5667            return;
5668        }
5669
5670        // Clean-up disabled activities.
5671        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5672                packageName, disabledClasses, true, false, userId) && mBooted) {
5673            mStackSupervisor.resumeTopActivitiesLocked();
5674            mStackSupervisor.scheduleIdleLocked();
5675        }
5676
5677        // Clean-up disabled tasks
5678        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5679
5680        // Clean-up disabled services.
5681        mServices.bringDownDisabledPackageServicesLocked(
5682                packageName, disabledClasses, userId, false, killProcess, true);
5683
5684        // Clean-up disabled providers.
5685        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5686        mProviderMap.collectPackageProvidersLocked(
5687                packageName, disabledClasses, true, false, userId, providers);
5688        for (int i = providers.size() - 1; i >= 0; i--) {
5689            removeDyingProviderLocked(null, providers.get(i), true);
5690        }
5691
5692        // Clean-up disabled broadcast receivers.
5693        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5694            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5695                    packageName, disabledClasses, userId, true);
5696        }
5697
5698    }
5699
5700    final boolean forceStopPackageLocked(String packageName, int appId,
5701            boolean callerWillRestart, boolean purgeCache, boolean doit,
5702            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5703        int i;
5704
5705        if (userId == UserHandle.USER_ALL && packageName == null) {
5706            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5707        }
5708
5709        if (appId < 0 && packageName != null) {
5710            try {
5711                appId = UserHandle.getAppId(
5712                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5713            } catch (RemoteException e) {
5714            }
5715        }
5716
5717        if (doit) {
5718            if (packageName != null) {
5719                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5720                        + " user=" + userId + ": " + reason);
5721            } else {
5722                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5723            }
5724
5725            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5726            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5727                SparseArray<Long> ba = pmap.valueAt(ip);
5728                for (i = ba.size() - 1; i >= 0; i--) {
5729                    boolean remove = false;
5730                    final int entUid = ba.keyAt(i);
5731                    if (packageName != null) {
5732                        if (userId == UserHandle.USER_ALL) {
5733                            if (UserHandle.getAppId(entUid) == appId) {
5734                                remove = true;
5735                            }
5736                        } else {
5737                            if (entUid == UserHandle.getUid(userId, appId)) {
5738                                remove = true;
5739                            }
5740                        }
5741                    } else if (UserHandle.getUserId(entUid) == userId) {
5742                        remove = true;
5743                    }
5744                    if (remove) {
5745                        ba.removeAt(i);
5746                    }
5747                }
5748                if (ba.size() == 0) {
5749                    pmap.removeAt(ip);
5750                }
5751            }
5752        }
5753
5754        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5755                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5756                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5757
5758        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5759                packageName, null, doit, evenPersistent, userId)) {
5760            if (!doit) {
5761                return true;
5762            }
5763            didSomething = true;
5764        }
5765
5766        if (mServices.bringDownDisabledPackageServicesLocked(
5767                packageName, null, userId, evenPersistent, true, doit)) {
5768            if (!doit) {
5769                return true;
5770            }
5771            didSomething = true;
5772        }
5773
5774        if (packageName == null) {
5775            // Remove all sticky broadcasts from this user.
5776            mStickyBroadcasts.remove(userId);
5777        }
5778
5779        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5780        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5781                userId, providers)) {
5782            if (!doit) {
5783                return true;
5784            }
5785            didSomething = true;
5786        }
5787        for (i = providers.size() - 1; i >= 0; i--) {
5788            removeDyingProviderLocked(null, providers.get(i), true);
5789        }
5790
5791        // Remove transient permissions granted from/to this package/user
5792        removeUriPermissionsForPackageLocked(packageName, userId, false);
5793
5794        if (doit) {
5795            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5796                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5797                        packageName, null, userId, doit);
5798            }
5799        }
5800
5801        if (packageName == null || uninstalling) {
5802            // Remove pending intents.  For now we only do this when force
5803            // stopping users, because we have some problems when doing this
5804            // for packages -- app widgets are not currently cleaned up for
5805            // such packages, so they can be left with bad pending intents.
5806            if (mIntentSenderRecords.size() > 0) {
5807                Iterator<WeakReference<PendingIntentRecord>> it
5808                        = mIntentSenderRecords.values().iterator();
5809                while (it.hasNext()) {
5810                    WeakReference<PendingIntentRecord> wpir = it.next();
5811                    if (wpir == null) {
5812                        it.remove();
5813                        continue;
5814                    }
5815                    PendingIntentRecord pir = wpir.get();
5816                    if (pir == null) {
5817                        it.remove();
5818                        continue;
5819                    }
5820                    if (packageName == null) {
5821                        // Stopping user, remove all objects for the user.
5822                        if (pir.key.userId != userId) {
5823                            // Not the same user, skip it.
5824                            continue;
5825                        }
5826                    } else {
5827                        if (UserHandle.getAppId(pir.uid) != appId) {
5828                            // Different app id, skip it.
5829                            continue;
5830                        }
5831                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5832                            // Different user, skip it.
5833                            continue;
5834                        }
5835                        if (!pir.key.packageName.equals(packageName)) {
5836                            // Different package, skip it.
5837                            continue;
5838                        }
5839                    }
5840                    if (!doit) {
5841                        return true;
5842                    }
5843                    didSomething = true;
5844                    it.remove();
5845                    pir.canceled = true;
5846                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5847                        pir.key.activity.pendingResults.remove(pir.ref);
5848                    }
5849                }
5850            }
5851        }
5852
5853        if (doit) {
5854            if (purgeCache && packageName != null) {
5855                AttributeCache ac = AttributeCache.instance();
5856                if (ac != null) {
5857                    ac.removePackage(packageName);
5858                }
5859            }
5860            if (mBooted) {
5861                mStackSupervisor.resumeTopActivitiesLocked();
5862                mStackSupervisor.scheduleIdleLocked();
5863            }
5864        }
5865
5866        return didSomething;
5867    }
5868
5869    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5870        ProcessRecord old = mProcessNames.remove(name, uid);
5871        if (old != null) {
5872            old.uidRecord.numProcs--;
5873            if (old.uidRecord.numProcs == 0) {
5874                // No more processes using this uid, tell clients it is gone.
5875                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5876                        "No more processes in " + old.uidRecord);
5877                enqueueUidChangeLocked(old.uidRecord, true);
5878                mActiveUids.remove(uid);
5879            }
5880            old.uidRecord = null;
5881        }
5882        mIsolatedProcesses.remove(uid);
5883        return old;
5884    }
5885
5886    private final void addProcessNameLocked(ProcessRecord proc) {
5887        // We shouldn't already have a process under this name, but just in case we
5888        // need to clean up whatever may be there now.
5889        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5890        if (old == proc && proc.persistent) {
5891            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5892            Slog.w(TAG, "Re-adding persistent process " + proc);
5893        } else if (old != null) {
5894            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5895        }
5896        UidRecord uidRec = mActiveUids.get(proc.uid);
5897        if (uidRec == null) {
5898            uidRec = new UidRecord(proc.uid);
5899            // This is the first appearance of the uid, report it now!
5900            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5901                    "Creating new process uid: " + uidRec);
5902            mActiveUids.put(proc.uid, uidRec);
5903            enqueueUidChangeLocked(uidRec, false);
5904        }
5905        proc.uidRecord = uidRec;
5906        uidRec.numProcs++;
5907        mProcessNames.put(proc.processName, proc.uid, proc);
5908        if (proc.isolated) {
5909            mIsolatedProcesses.put(proc.uid, proc);
5910        }
5911    }
5912
5913    private final boolean removeProcessLocked(ProcessRecord app,
5914            boolean callerWillRestart, boolean allowRestart, String reason) {
5915        final String name = app.processName;
5916        final int uid = app.uid;
5917        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5918            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5919
5920        removeProcessNameLocked(name, uid);
5921        if (mHeavyWeightProcess == app) {
5922            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5923                    mHeavyWeightProcess.userId, 0));
5924            mHeavyWeightProcess = null;
5925        }
5926        boolean needRestart = false;
5927        if (app.pid > 0 && app.pid != MY_PID) {
5928            int pid = app.pid;
5929            synchronized (mPidsSelfLocked) {
5930                mPidsSelfLocked.remove(pid);
5931                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5932            }
5933            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5934            if (app.isolated) {
5935                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5936            }
5937            boolean willRestart = false;
5938            if (app.persistent && !app.isolated) {
5939                if (!callerWillRestart) {
5940                    willRestart = true;
5941                } else {
5942                    needRestart = true;
5943                }
5944            }
5945            app.kill(reason, true);
5946            handleAppDiedLocked(app, willRestart, allowRestart);
5947            if (willRestart) {
5948                removeLruProcessLocked(app);
5949                addAppLocked(app.info, false, null /* ABI override */);
5950            }
5951        } else {
5952            mRemovedProcesses.add(app);
5953        }
5954
5955        return needRestart;
5956    }
5957
5958    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5959        cleanupAppInLaunchingProvidersLocked(app, true);
5960        removeProcessLocked(app, false, true, "timeout publishing content providers");
5961    }
5962
5963    private final void processStartTimedOutLocked(ProcessRecord app) {
5964        final int pid = app.pid;
5965        boolean gone = false;
5966        synchronized (mPidsSelfLocked) {
5967            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5968            if (knownApp != null && knownApp.thread == null) {
5969                mPidsSelfLocked.remove(pid);
5970                gone = true;
5971            }
5972        }
5973
5974        if (gone) {
5975            Slog.w(TAG, "Process " + app + " failed to attach");
5976            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5977                    pid, app.uid, app.processName);
5978            removeProcessNameLocked(app.processName, app.uid);
5979            if (mHeavyWeightProcess == app) {
5980                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5981                        mHeavyWeightProcess.userId, 0));
5982                mHeavyWeightProcess = null;
5983            }
5984            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5985            if (app.isolated) {
5986                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5987            }
5988            // Take care of any launching providers waiting for this process.
5989            cleanupAppInLaunchingProvidersLocked(app, true);
5990            // Take care of any services that are waiting for the process.
5991            mServices.processStartTimedOutLocked(app);
5992            app.kill("start timeout", true);
5993            removeLruProcessLocked(app);
5994            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5995                Slog.w(TAG, "Unattached app died before backup, skipping");
5996                try {
5997                    IBackupManager bm = IBackupManager.Stub.asInterface(
5998                            ServiceManager.getService(Context.BACKUP_SERVICE));
5999                    bm.agentDisconnected(app.info.packageName);
6000                } catch (RemoteException e) {
6001                    // Can't happen; the backup manager is local
6002                }
6003            }
6004            if (isPendingBroadcastProcessLocked(pid)) {
6005                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6006                skipPendingBroadcastLocked(pid);
6007            }
6008        } else {
6009            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6010        }
6011    }
6012
6013    private final boolean attachApplicationLocked(IApplicationThread thread,
6014            int pid) {
6015
6016        // Find the application record that is being attached...  either via
6017        // the pid if we are running in multiple processes, or just pull the
6018        // next app record if we are emulating process with anonymous threads.
6019        ProcessRecord app;
6020        if (pid != MY_PID && pid >= 0) {
6021            synchronized (mPidsSelfLocked) {
6022                app = mPidsSelfLocked.get(pid);
6023            }
6024        } else {
6025            app = null;
6026        }
6027
6028        if (app == null) {
6029            Slog.w(TAG, "No pending application record for pid " + pid
6030                    + " (IApplicationThread " + thread + "); dropping process");
6031            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6032            if (pid > 0 && pid != MY_PID) {
6033                Process.killProcessQuiet(pid);
6034                //TODO: killProcessGroup(app.info.uid, pid);
6035            } else {
6036                try {
6037                    thread.scheduleExit();
6038                } catch (Exception e) {
6039                    // Ignore exceptions.
6040                }
6041            }
6042            return false;
6043        }
6044
6045        // If this application record is still attached to a previous
6046        // process, clean it up now.
6047        if (app.thread != null) {
6048            handleAppDiedLocked(app, true, true);
6049        }
6050
6051        // Tell the process all about itself.
6052
6053        if (DEBUG_ALL) Slog.v(
6054                TAG, "Binding process pid " + pid + " to record " + app);
6055
6056        final String processName = app.processName;
6057        try {
6058            AppDeathRecipient adr = new AppDeathRecipient(
6059                    app, pid, thread);
6060            thread.asBinder().linkToDeath(adr, 0);
6061            app.deathRecipient = adr;
6062        } catch (RemoteException e) {
6063            app.resetPackageList(mProcessStats);
6064            startProcessLocked(app, "link fail", processName);
6065            return false;
6066        }
6067
6068        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6069
6070        app.makeActive(thread, mProcessStats);
6071        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6072        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6073        app.forcingToForeground = null;
6074        updateProcessForegroundLocked(app, false, false);
6075        app.hasShownUi = false;
6076        app.debugging = false;
6077        app.cached = false;
6078        app.killedByAm = false;
6079
6080        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6081
6082        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6083        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6084
6085        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6086            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6087            msg.obj = app;
6088            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6089        }
6090
6091        if (!normalMode) {
6092            Slog.i(TAG, "Launching preboot mode app: " + app);
6093        }
6094
6095        if (DEBUG_ALL) Slog.v(
6096            TAG, "New app record " + app
6097            + " thread=" + thread.asBinder() + " pid=" + pid);
6098        try {
6099            int testMode = IApplicationThread.DEBUG_OFF;
6100            if (mDebugApp != null && mDebugApp.equals(processName)) {
6101                testMode = mWaitForDebugger
6102                    ? IApplicationThread.DEBUG_WAIT
6103                    : IApplicationThread.DEBUG_ON;
6104                app.debugging = true;
6105                if (mDebugTransient) {
6106                    mDebugApp = mOrigDebugApp;
6107                    mWaitForDebugger = mOrigWaitForDebugger;
6108                }
6109            }
6110            String profileFile = app.instrumentationProfileFile;
6111            ParcelFileDescriptor profileFd = null;
6112            int samplingInterval = 0;
6113            boolean profileAutoStop = false;
6114            if (mProfileApp != null && mProfileApp.equals(processName)) {
6115                mProfileProc = app;
6116                profileFile = mProfileFile;
6117                profileFd = mProfileFd;
6118                samplingInterval = mSamplingInterval;
6119                profileAutoStop = mAutoStopProfiler;
6120            }
6121            boolean enableTrackAllocation = false;
6122            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6123                enableTrackAllocation = true;
6124                mTrackAllocationApp = null;
6125            }
6126
6127            // If the app is being launched for restore or full backup, set it up specially
6128            boolean isRestrictedBackupMode = false;
6129            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6130                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6131                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6132                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6133            }
6134
6135            ensurePackageDexOpt(app.instrumentationInfo != null
6136                    ? app.instrumentationInfo.packageName
6137                    : app.info.packageName);
6138            if (app.instrumentationClass != null) {
6139                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6140            }
6141            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6142                    + processName + " with config " + mConfiguration);
6143            ApplicationInfo appInfo = app.instrumentationInfo != null
6144                    ? app.instrumentationInfo : app.info;
6145            app.compat = compatibilityInfoForPackageLocked(appInfo);
6146            if (profileFd != null) {
6147                profileFd = profileFd.dup();
6148            }
6149            ProfilerInfo profilerInfo = profileFile == null ? null
6150                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6151            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6152                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6153                    app.instrumentationUiAutomationConnection, testMode,
6154                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6155                    isRestrictedBackupMode || !normalMode, app.persistent,
6156                    new Configuration(mConfiguration), app.compat,
6157                    getCommonServicesLocked(app.isolated),
6158                    mCoreSettingsObserver.getCoreSettingsLocked());
6159            updateLruProcessLocked(app, false, null);
6160            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6161        } catch (Exception e) {
6162            // todo: Yikes!  What should we do?  For now we will try to
6163            // start another process, but that could easily get us in
6164            // an infinite loop of restarting processes...
6165            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6166
6167            app.resetPackageList(mProcessStats);
6168            app.unlinkDeathRecipient();
6169            startProcessLocked(app, "bind fail", processName);
6170            return false;
6171        }
6172
6173        // Remove this record from the list of starting applications.
6174        mPersistentStartingProcesses.remove(app);
6175        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6176                "Attach application locked removing on hold: " + app);
6177        mProcessesOnHold.remove(app);
6178
6179        boolean badApp = false;
6180        boolean didSomething = false;
6181
6182        // See if the top visible activity is waiting to run in this process...
6183        if (normalMode) {
6184            try {
6185                if (mStackSupervisor.attachApplicationLocked(app)) {
6186                    didSomething = true;
6187                }
6188            } catch (Exception e) {
6189                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6190                badApp = true;
6191            }
6192        }
6193
6194        // Find any services that should be running in this process...
6195        if (!badApp) {
6196            try {
6197                didSomething |= mServices.attachApplicationLocked(app, processName);
6198            } catch (Exception e) {
6199                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6200                badApp = true;
6201            }
6202        }
6203
6204        // Check if a next-broadcast receiver is in this process...
6205        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6206            try {
6207                didSomething |= sendPendingBroadcastsLocked(app);
6208            } catch (Exception e) {
6209                // If the app died trying to launch the receiver we declare it 'bad'
6210                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6211                badApp = true;
6212            }
6213        }
6214
6215        // Check whether the next backup agent is in this process...
6216        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6217            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6218                    "New app is backup target, launching agent for " + app);
6219            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6220            try {
6221                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6222                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6223                        mBackupTarget.backupMode);
6224            } catch (Exception e) {
6225                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6226                badApp = true;
6227            }
6228        }
6229
6230        if (badApp) {
6231            app.kill("error during init", true);
6232            handleAppDiedLocked(app, false, true);
6233            return false;
6234        }
6235
6236        if (!didSomething) {
6237            updateOomAdjLocked();
6238        }
6239
6240        return true;
6241    }
6242
6243    @Override
6244    public final void attachApplication(IApplicationThread thread) {
6245        synchronized (this) {
6246            int callingPid = Binder.getCallingPid();
6247            final long origId = Binder.clearCallingIdentity();
6248            attachApplicationLocked(thread, callingPid);
6249            Binder.restoreCallingIdentity(origId);
6250        }
6251    }
6252
6253    @Override
6254    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6255        final long origId = Binder.clearCallingIdentity();
6256        synchronized (this) {
6257            ActivityStack stack = ActivityRecord.getStackLocked(token);
6258            if (stack != null) {
6259                ActivityRecord r =
6260                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6261                if (stopProfiling) {
6262                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6263                        try {
6264                            mProfileFd.close();
6265                        } catch (IOException e) {
6266                        }
6267                        clearProfilerLocked();
6268                    }
6269                }
6270            }
6271        }
6272        Binder.restoreCallingIdentity(origId);
6273    }
6274
6275    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6276        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6277                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6278    }
6279
6280    void enableScreenAfterBoot() {
6281        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6282                SystemClock.uptimeMillis());
6283        mWindowManager.enableScreenAfterBoot();
6284
6285        synchronized (this) {
6286            updateEventDispatchingLocked();
6287        }
6288    }
6289
6290    @Override
6291    public void showBootMessage(final CharSequence msg, final boolean always) {
6292        if (Binder.getCallingUid() != Process.myUid()) {
6293            // These days only the core system can call this, so apps can't get in
6294            // the way of what we show about running them.
6295        }
6296        mWindowManager.showBootMessage(msg, always);
6297    }
6298
6299    @Override
6300    public void keyguardWaitingForActivityDrawn() {
6301        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6302        final long token = Binder.clearCallingIdentity();
6303        try {
6304            synchronized (this) {
6305                if (DEBUG_LOCKSCREEN) logLockScreen("");
6306                mWindowManager.keyguardWaitingForActivityDrawn();
6307                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6308                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6309                    updateSleepIfNeededLocked();
6310                }
6311            }
6312        } finally {
6313            Binder.restoreCallingIdentity(token);
6314        }
6315    }
6316
6317    @Override
6318    public void keyguardGoingAway(boolean disableWindowAnimations,
6319            boolean keyguardGoingToNotificationShade) {
6320        enforceNotIsolatedCaller("keyguardGoingAway");
6321        final long token = Binder.clearCallingIdentity();
6322        try {
6323            synchronized (this) {
6324                if (DEBUG_LOCKSCREEN) logLockScreen("");
6325                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6326                        keyguardGoingToNotificationShade);
6327                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6328                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6329                    updateSleepIfNeededLocked();
6330                }
6331            }
6332        } finally {
6333            Binder.restoreCallingIdentity(token);
6334        }
6335    }
6336
6337    final void finishBooting() {
6338        synchronized (this) {
6339            if (!mBootAnimationComplete) {
6340                mCallFinishBooting = true;
6341                return;
6342            }
6343            mCallFinishBooting = false;
6344        }
6345
6346        ArraySet<String> completedIsas = new ArraySet<String>();
6347        for (String abi : Build.SUPPORTED_ABIS) {
6348            Process.establishZygoteConnectionForAbi(abi);
6349            final String instructionSet = VMRuntime.getInstructionSet(abi);
6350            if (!completedIsas.contains(instructionSet)) {
6351                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6352                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6353                }
6354                completedIsas.add(instructionSet);
6355            }
6356        }
6357
6358        IntentFilter pkgFilter = new IntentFilter();
6359        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6360        pkgFilter.addDataScheme("package");
6361        mContext.registerReceiver(new BroadcastReceiver() {
6362            @Override
6363            public void onReceive(Context context, Intent intent) {
6364                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6365                if (pkgs != null) {
6366                    for (String pkg : pkgs) {
6367                        synchronized (ActivityManagerService.this) {
6368                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6369                                    0, "query restart")) {
6370                                setResultCode(Activity.RESULT_OK);
6371                                return;
6372                            }
6373                        }
6374                    }
6375                }
6376            }
6377        }, pkgFilter);
6378
6379        IntentFilter dumpheapFilter = new IntentFilter();
6380        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6381        mContext.registerReceiver(new BroadcastReceiver() {
6382            @Override
6383            public void onReceive(Context context, Intent intent) {
6384                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6385                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6386                } else {
6387                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6388                }
6389            }
6390        }, dumpheapFilter);
6391
6392        // Let system services know.
6393        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6394
6395        synchronized (this) {
6396            // Ensure that any processes we had put on hold are now started
6397            // up.
6398            final int NP = mProcessesOnHold.size();
6399            if (NP > 0) {
6400                ArrayList<ProcessRecord> procs =
6401                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6402                for (int ip=0; ip<NP; ip++) {
6403                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6404                            + procs.get(ip));
6405                    startProcessLocked(procs.get(ip), "on-hold", null);
6406                }
6407            }
6408
6409            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6410                // Start looking for apps that are abusing wake locks.
6411                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6412                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6413                // Tell anyone interested that we are done booting!
6414                SystemProperties.set("sys.boot_completed", "1");
6415
6416                // And trigger dev.bootcomplete if we are not showing encryption progress
6417                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6418                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6419                    SystemProperties.set("dev.bootcomplete", "1");
6420                }
6421                mUserController.sendBootCompletedLocked(
6422                        new IIntentReceiver.Stub() {
6423                            @Override
6424                            public void performReceive(Intent intent, int resultCode,
6425                                    String data, Bundle extras, boolean ordered,
6426                                    boolean sticky, int sendingUser) {
6427                                synchronized (ActivityManagerService.this) {
6428                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6429                                            true, false);
6430                                }
6431                            }
6432                        });
6433                scheduleStartProfilesLocked();
6434            }
6435        }
6436    }
6437
6438    @Override
6439    public void bootAnimationComplete() {
6440        final boolean callFinishBooting;
6441        synchronized (this) {
6442            callFinishBooting = mCallFinishBooting;
6443            mBootAnimationComplete = true;
6444        }
6445        if (callFinishBooting) {
6446            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6447            finishBooting();
6448            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6449        }
6450    }
6451
6452    final void ensureBootCompleted() {
6453        boolean booting;
6454        boolean enableScreen;
6455        synchronized (this) {
6456            booting = mBooting;
6457            mBooting = false;
6458            enableScreen = !mBooted;
6459            mBooted = true;
6460        }
6461
6462        if (booting) {
6463            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6464            finishBooting();
6465            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6466        }
6467
6468        if (enableScreen) {
6469            enableScreenAfterBoot();
6470        }
6471    }
6472
6473    @Override
6474    public final void activityResumed(IBinder token) {
6475        final long origId = Binder.clearCallingIdentity();
6476        synchronized(this) {
6477            ActivityStack stack = ActivityRecord.getStackLocked(token);
6478            if (stack != null) {
6479                ActivityRecord.activityResumedLocked(token);
6480            }
6481        }
6482        Binder.restoreCallingIdentity(origId);
6483    }
6484
6485    @Override
6486    public final void activityPaused(IBinder token) {
6487        final long origId = Binder.clearCallingIdentity();
6488        synchronized(this) {
6489            ActivityStack stack = ActivityRecord.getStackLocked(token);
6490            if (stack != null) {
6491                stack.activityPausedLocked(token, false);
6492            }
6493        }
6494        Binder.restoreCallingIdentity(origId);
6495    }
6496
6497    @Override
6498    public final void activityStopped(IBinder token, Bundle icicle,
6499            PersistableBundle persistentState, CharSequence description) {
6500        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6501
6502        // Refuse possible leaked file descriptors
6503        if (icicle != null && icicle.hasFileDescriptors()) {
6504            throw new IllegalArgumentException("File descriptors passed in Bundle");
6505        }
6506
6507        final long origId = Binder.clearCallingIdentity();
6508
6509        synchronized (this) {
6510            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6511            if (r != null) {
6512                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6513            }
6514        }
6515
6516        trimApplications();
6517
6518        Binder.restoreCallingIdentity(origId);
6519    }
6520
6521    @Override
6522    public final void activityDestroyed(IBinder token) {
6523        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6524        synchronized (this) {
6525            ActivityStack stack = ActivityRecord.getStackLocked(token);
6526            if (stack != null) {
6527                stack.activityDestroyedLocked(token, "activityDestroyed");
6528            }
6529        }
6530    }
6531
6532    @Override
6533    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6534            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6535        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6536                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6537        synchronized (this) {
6538            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6539            if (record == null) {
6540                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6541                        + "found for: " + token);
6542            }
6543            record.setSizeConfigurations(horizontalSizeConfiguration,
6544                    verticalSizeConfigurations, smallestSizeConfigurations);
6545        }
6546    }
6547
6548    @Override
6549    public final void backgroundResourcesReleased(IBinder token) {
6550        final long origId = Binder.clearCallingIdentity();
6551        try {
6552            synchronized (this) {
6553                ActivityStack stack = ActivityRecord.getStackLocked(token);
6554                if (stack != null) {
6555                    stack.backgroundResourcesReleased();
6556                }
6557            }
6558        } finally {
6559            Binder.restoreCallingIdentity(origId);
6560        }
6561    }
6562
6563    @Override
6564    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6565        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6566    }
6567
6568    @Override
6569    public final void notifyEnterAnimationComplete(IBinder token) {
6570        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6571    }
6572
6573    @Override
6574    public String getCallingPackage(IBinder token) {
6575        synchronized (this) {
6576            ActivityRecord r = getCallingRecordLocked(token);
6577            return r != null ? r.info.packageName : null;
6578        }
6579    }
6580
6581    @Override
6582    public ComponentName getCallingActivity(IBinder token) {
6583        synchronized (this) {
6584            ActivityRecord r = getCallingRecordLocked(token);
6585            return r != null ? r.intent.getComponent() : null;
6586        }
6587    }
6588
6589    private ActivityRecord getCallingRecordLocked(IBinder token) {
6590        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6591        if (r == null) {
6592            return null;
6593        }
6594        return r.resultTo;
6595    }
6596
6597    @Override
6598    public ComponentName getActivityClassForToken(IBinder token) {
6599        synchronized(this) {
6600            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6601            if (r == null) {
6602                return null;
6603            }
6604            return r.intent.getComponent();
6605        }
6606    }
6607
6608    @Override
6609    public String getPackageForToken(IBinder token) {
6610        synchronized(this) {
6611            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6612            if (r == null) {
6613                return null;
6614            }
6615            return r.packageName;
6616        }
6617    }
6618
6619    @Override
6620    public boolean isRootVoiceInteraction(IBinder token) {
6621        synchronized(this) {
6622            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6623            if (r == null) {
6624                return false;
6625            }
6626            return r.rootVoiceInteraction;
6627        }
6628    }
6629
6630    @Override
6631    public IIntentSender getIntentSender(int type,
6632            String packageName, IBinder token, String resultWho,
6633            int requestCode, Intent[] intents, String[] resolvedTypes,
6634            int flags, Bundle bOptions, int userId) {
6635        enforceNotIsolatedCaller("getIntentSender");
6636        // Refuse possible leaked file descriptors
6637        if (intents != null) {
6638            if (intents.length < 1) {
6639                throw new IllegalArgumentException("Intents array length must be >= 1");
6640            }
6641            for (int i=0; i<intents.length; i++) {
6642                Intent intent = intents[i];
6643                if (intent != null) {
6644                    if (intent.hasFileDescriptors()) {
6645                        throw new IllegalArgumentException("File descriptors passed in Intent");
6646                    }
6647                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6648                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6649                        throw new IllegalArgumentException(
6650                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6651                    }
6652                    intents[i] = new Intent(intent);
6653                }
6654            }
6655            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6656                throw new IllegalArgumentException(
6657                        "Intent array length does not match resolvedTypes length");
6658            }
6659        }
6660        if (bOptions != null) {
6661            if (bOptions.hasFileDescriptors()) {
6662                throw new IllegalArgumentException("File descriptors passed in options");
6663            }
6664        }
6665
6666        synchronized(this) {
6667            int callingUid = Binder.getCallingUid();
6668            int origUserId = userId;
6669            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6670                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6671                    ALLOW_NON_FULL, "getIntentSender", null);
6672            if (origUserId == UserHandle.USER_CURRENT) {
6673                // We don't want to evaluate this until the pending intent is
6674                // actually executed.  However, we do want to always do the
6675                // security checking for it above.
6676                userId = UserHandle.USER_CURRENT;
6677            }
6678            try {
6679                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6680                    int uid = AppGlobals.getPackageManager()
6681                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6682                    if (!UserHandle.isSameApp(callingUid, uid)) {
6683                        String msg = "Permission Denial: getIntentSender() from pid="
6684                            + Binder.getCallingPid()
6685                            + ", uid=" + Binder.getCallingUid()
6686                            + ", (need uid=" + uid + ")"
6687                            + " is not allowed to send as package " + packageName;
6688                        Slog.w(TAG, msg);
6689                        throw new SecurityException(msg);
6690                    }
6691                }
6692
6693                return getIntentSenderLocked(type, packageName, callingUid, userId,
6694                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6695
6696            } catch (RemoteException e) {
6697                throw new SecurityException(e);
6698            }
6699        }
6700    }
6701
6702    IIntentSender getIntentSenderLocked(int type, String packageName,
6703            int callingUid, int userId, IBinder token, String resultWho,
6704            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6705            Bundle bOptions) {
6706        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6707        ActivityRecord activity = null;
6708        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6709            activity = ActivityRecord.isInStackLocked(token);
6710            if (activity == null) {
6711                return null;
6712            }
6713            if (activity.finishing) {
6714                return null;
6715            }
6716        }
6717
6718        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6719        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6720        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6721        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6722                |PendingIntent.FLAG_UPDATE_CURRENT);
6723
6724        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6725                type, packageName, activity, resultWho,
6726                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6727        WeakReference<PendingIntentRecord> ref;
6728        ref = mIntentSenderRecords.get(key);
6729        PendingIntentRecord rec = ref != null ? ref.get() : null;
6730        if (rec != null) {
6731            if (!cancelCurrent) {
6732                if (updateCurrent) {
6733                    if (rec.key.requestIntent != null) {
6734                        rec.key.requestIntent.replaceExtras(intents != null ?
6735                                intents[intents.length - 1] : null);
6736                    }
6737                    if (intents != null) {
6738                        intents[intents.length-1] = rec.key.requestIntent;
6739                        rec.key.allIntents = intents;
6740                        rec.key.allResolvedTypes = resolvedTypes;
6741                    } else {
6742                        rec.key.allIntents = null;
6743                        rec.key.allResolvedTypes = null;
6744                    }
6745                }
6746                return rec;
6747            }
6748            rec.canceled = true;
6749            mIntentSenderRecords.remove(key);
6750        }
6751        if (noCreate) {
6752            return rec;
6753        }
6754        rec = new PendingIntentRecord(this, key, callingUid);
6755        mIntentSenderRecords.put(key, rec.ref);
6756        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6757            if (activity.pendingResults == null) {
6758                activity.pendingResults
6759                        = new HashSet<WeakReference<PendingIntentRecord>>();
6760            }
6761            activity.pendingResults.add(rec.ref);
6762        }
6763        return rec;
6764    }
6765
6766    @Override
6767    public void cancelIntentSender(IIntentSender sender) {
6768        if (!(sender instanceof PendingIntentRecord)) {
6769            return;
6770        }
6771        synchronized(this) {
6772            PendingIntentRecord rec = (PendingIntentRecord)sender;
6773            try {
6774                int uid = AppGlobals.getPackageManager()
6775                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6776                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6777                    String msg = "Permission Denial: cancelIntentSender() from pid="
6778                        + Binder.getCallingPid()
6779                        + ", uid=" + Binder.getCallingUid()
6780                        + " is not allowed to cancel packges "
6781                        + rec.key.packageName;
6782                    Slog.w(TAG, msg);
6783                    throw new SecurityException(msg);
6784                }
6785            } catch (RemoteException e) {
6786                throw new SecurityException(e);
6787            }
6788            cancelIntentSenderLocked(rec, true);
6789        }
6790    }
6791
6792    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6793        rec.canceled = true;
6794        mIntentSenderRecords.remove(rec.key);
6795        if (cleanActivity && rec.key.activity != null) {
6796            rec.key.activity.pendingResults.remove(rec.ref);
6797        }
6798    }
6799
6800    @Override
6801    public String getPackageForIntentSender(IIntentSender pendingResult) {
6802        if (!(pendingResult instanceof PendingIntentRecord)) {
6803            return null;
6804        }
6805        try {
6806            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6807            return res.key.packageName;
6808        } catch (ClassCastException e) {
6809        }
6810        return null;
6811    }
6812
6813    @Override
6814    public int getUidForIntentSender(IIntentSender sender) {
6815        if (sender instanceof PendingIntentRecord) {
6816            try {
6817                PendingIntentRecord res = (PendingIntentRecord)sender;
6818                return res.uid;
6819            } catch (ClassCastException e) {
6820            }
6821        }
6822        return -1;
6823    }
6824
6825    @Override
6826    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6827        if (!(pendingResult instanceof PendingIntentRecord)) {
6828            return false;
6829        }
6830        try {
6831            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6832            if (res.key.allIntents == null) {
6833                return false;
6834            }
6835            for (int i=0; i<res.key.allIntents.length; i++) {
6836                Intent intent = res.key.allIntents[i];
6837                if (intent.getPackage() != null && intent.getComponent() != null) {
6838                    return false;
6839                }
6840            }
6841            return true;
6842        } catch (ClassCastException e) {
6843        }
6844        return false;
6845    }
6846
6847    @Override
6848    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6849        if (!(pendingResult instanceof PendingIntentRecord)) {
6850            return false;
6851        }
6852        try {
6853            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6854            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6855                return true;
6856            }
6857            return false;
6858        } catch (ClassCastException e) {
6859        }
6860        return false;
6861    }
6862
6863    @Override
6864    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6865        if (!(pendingResult instanceof PendingIntentRecord)) {
6866            return null;
6867        }
6868        try {
6869            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6870            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6871        } catch (ClassCastException e) {
6872        }
6873        return null;
6874    }
6875
6876    @Override
6877    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6878        if (!(pendingResult instanceof PendingIntentRecord)) {
6879            return null;
6880        }
6881        try {
6882            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6883            synchronized (this) {
6884                return getTagForIntentSenderLocked(res, prefix);
6885            }
6886        } catch (ClassCastException e) {
6887        }
6888        return null;
6889    }
6890
6891    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6892        final Intent intent = res.key.requestIntent;
6893        if (intent != null) {
6894            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6895                    || res.lastTagPrefix.equals(prefix))) {
6896                return res.lastTag;
6897            }
6898            res.lastTagPrefix = prefix;
6899            final StringBuilder sb = new StringBuilder(128);
6900            if (prefix != null) {
6901                sb.append(prefix);
6902            }
6903            if (intent.getAction() != null) {
6904                sb.append(intent.getAction());
6905            } else if (intent.getComponent() != null) {
6906                intent.getComponent().appendShortString(sb);
6907            } else {
6908                sb.append("?");
6909            }
6910            return res.lastTag = sb.toString();
6911        }
6912        return null;
6913    }
6914
6915    @Override
6916    public void setProcessLimit(int max) {
6917        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6918                "setProcessLimit()");
6919        synchronized (this) {
6920            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6921            mProcessLimitOverride = max;
6922        }
6923        trimApplications();
6924    }
6925
6926    @Override
6927    public int getProcessLimit() {
6928        synchronized (this) {
6929            return mProcessLimitOverride;
6930        }
6931    }
6932
6933    void foregroundTokenDied(ForegroundToken token) {
6934        synchronized (ActivityManagerService.this) {
6935            synchronized (mPidsSelfLocked) {
6936                ForegroundToken cur
6937                    = mForegroundProcesses.get(token.pid);
6938                if (cur != token) {
6939                    return;
6940                }
6941                mForegroundProcesses.remove(token.pid);
6942                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6943                if (pr == null) {
6944                    return;
6945                }
6946                pr.forcingToForeground = null;
6947                updateProcessForegroundLocked(pr, false, false);
6948            }
6949            updateOomAdjLocked();
6950        }
6951    }
6952
6953    @Override
6954    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6955        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6956                "setProcessForeground()");
6957        synchronized(this) {
6958            boolean changed = false;
6959
6960            synchronized (mPidsSelfLocked) {
6961                ProcessRecord pr = mPidsSelfLocked.get(pid);
6962                if (pr == null && isForeground) {
6963                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6964                    return;
6965                }
6966                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6967                if (oldToken != null) {
6968                    oldToken.token.unlinkToDeath(oldToken, 0);
6969                    mForegroundProcesses.remove(pid);
6970                    if (pr != null) {
6971                        pr.forcingToForeground = null;
6972                    }
6973                    changed = true;
6974                }
6975                if (isForeground && token != null) {
6976                    ForegroundToken newToken = new ForegroundToken() {
6977                        @Override
6978                        public void binderDied() {
6979                            foregroundTokenDied(this);
6980                        }
6981                    };
6982                    newToken.pid = pid;
6983                    newToken.token = token;
6984                    try {
6985                        token.linkToDeath(newToken, 0);
6986                        mForegroundProcesses.put(pid, newToken);
6987                        pr.forcingToForeground = token;
6988                        changed = true;
6989                    } catch (RemoteException e) {
6990                        // If the process died while doing this, we will later
6991                        // do the cleanup with the process death link.
6992                    }
6993                }
6994            }
6995
6996            if (changed) {
6997                updateOomAdjLocked();
6998            }
6999        }
7000    }
7001
7002    // =========================================================
7003    // PROCESS INFO
7004    // =========================================================
7005
7006    static class ProcessInfoService extends IProcessInfoService.Stub {
7007        final ActivityManagerService mActivityManagerService;
7008        ProcessInfoService(ActivityManagerService activityManagerService) {
7009            mActivityManagerService = activityManagerService;
7010        }
7011
7012        @Override
7013        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7014            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7015        }
7016    }
7017
7018    /**
7019     * For each PID in the given input array, write the current process state
7020     * for that process into the output array, or -1 to indicate that no
7021     * process with the given PID exists.
7022     */
7023    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7024        if (pids == null) {
7025            throw new NullPointerException("pids");
7026        } else if (states == null) {
7027            throw new NullPointerException("states");
7028        } else if (pids.length != states.length) {
7029            throw new IllegalArgumentException("input and output arrays have different lengths!");
7030        }
7031
7032        synchronized (mPidsSelfLocked) {
7033            for (int i = 0; i < pids.length; i++) {
7034                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7035                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7036                        pr.curProcState;
7037            }
7038        }
7039    }
7040
7041    // =========================================================
7042    // PERMISSIONS
7043    // =========================================================
7044
7045    static class PermissionController extends IPermissionController.Stub {
7046        ActivityManagerService mActivityManagerService;
7047        PermissionController(ActivityManagerService activityManagerService) {
7048            mActivityManagerService = activityManagerService;
7049        }
7050
7051        @Override
7052        public boolean checkPermission(String permission, int pid, int uid) {
7053            return mActivityManagerService.checkPermission(permission, pid,
7054                    uid) == PackageManager.PERMISSION_GRANTED;
7055        }
7056
7057        @Override
7058        public String[] getPackagesForUid(int uid) {
7059            return mActivityManagerService.mContext.getPackageManager()
7060                    .getPackagesForUid(uid);
7061        }
7062
7063        @Override
7064        public boolean isRuntimePermission(String permission) {
7065            try {
7066                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7067                        .getPermissionInfo(permission, 0);
7068                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7069            } catch (NameNotFoundException nnfe) {
7070                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7071            }
7072            return false;
7073        }
7074    }
7075
7076    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7077        @Override
7078        public int checkComponentPermission(String permission, int pid, int uid,
7079                int owningUid, boolean exported) {
7080            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7081                    owningUid, exported);
7082        }
7083
7084        @Override
7085        public Object getAMSLock() {
7086            return ActivityManagerService.this;
7087        }
7088    }
7089
7090    /**
7091     * This can be called with or without the global lock held.
7092     */
7093    int checkComponentPermission(String permission, int pid, int uid,
7094            int owningUid, boolean exported) {
7095        if (pid == MY_PID) {
7096            return PackageManager.PERMISSION_GRANTED;
7097        }
7098        return ActivityManager.checkComponentPermission(permission, uid,
7099                owningUid, exported);
7100    }
7101
7102    /**
7103     * As the only public entry point for permissions checking, this method
7104     * can enforce the semantic that requesting a check on a null global
7105     * permission is automatically denied.  (Internally a null permission
7106     * string is used when calling {@link #checkComponentPermission} in cases
7107     * when only uid-based security is needed.)
7108     *
7109     * This can be called with or without the global lock held.
7110     */
7111    @Override
7112    public int checkPermission(String permission, int pid, int uid) {
7113        if (permission == null) {
7114            return PackageManager.PERMISSION_DENIED;
7115        }
7116        return checkComponentPermission(permission, pid, uid, -1, true);
7117    }
7118
7119    @Override
7120    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7121        if (permission == null) {
7122            return PackageManager.PERMISSION_DENIED;
7123        }
7124
7125        // We might be performing an operation on behalf of an indirect binder
7126        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7127        // client identity accordingly before proceeding.
7128        Identity tlsIdentity = sCallerIdentity.get();
7129        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7130            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7131                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7132            uid = tlsIdentity.uid;
7133            pid = tlsIdentity.pid;
7134        }
7135
7136        return checkComponentPermission(permission, pid, uid, -1, true);
7137    }
7138
7139    /**
7140     * Binder IPC calls go through the public entry point.
7141     * This can be called with or without the global lock held.
7142     */
7143    int checkCallingPermission(String permission) {
7144        return checkPermission(permission,
7145                Binder.getCallingPid(),
7146                UserHandle.getAppId(Binder.getCallingUid()));
7147    }
7148
7149    /**
7150     * This can be called with or without the global lock held.
7151     */
7152    void enforceCallingPermission(String permission, String func) {
7153        if (checkCallingPermission(permission)
7154                == PackageManager.PERMISSION_GRANTED) {
7155            return;
7156        }
7157
7158        String msg = "Permission Denial: " + func + " from pid="
7159                + Binder.getCallingPid()
7160                + ", uid=" + Binder.getCallingUid()
7161                + " requires " + permission;
7162        Slog.w(TAG, msg);
7163        throw new SecurityException(msg);
7164    }
7165
7166    /**
7167     * Determine if UID is holding permissions required to access {@link Uri} in
7168     * the given {@link ProviderInfo}. Final permission checking is always done
7169     * in {@link ContentProvider}.
7170     */
7171    private final boolean checkHoldingPermissionsLocked(
7172            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7173        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7174                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7175        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7176            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7177                    != PERMISSION_GRANTED) {
7178                return false;
7179            }
7180        }
7181        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7182    }
7183
7184    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7185            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7186        if (pi.applicationInfo.uid == uid) {
7187            return true;
7188        } else if (!pi.exported) {
7189            return false;
7190        }
7191
7192        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7193        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7194        try {
7195            // check if target holds top-level <provider> permissions
7196            if (!readMet && pi.readPermission != null && considerUidPermissions
7197                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7198                readMet = true;
7199            }
7200            if (!writeMet && pi.writePermission != null && considerUidPermissions
7201                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7202                writeMet = true;
7203            }
7204
7205            // track if unprotected read/write is allowed; any denied
7206            // <path-permission> below removes this ability
7207            boolean allowDefaultRead = pi.readPermission == null;
7208            boolean allowDefaultWrite = pi.writePermission == null;
7209
7210            // check if target holds any <path-permission> that match uri
7211            final PathPermission[] pps = pi.pathPermissions;
7212            if (pps != null) {
7213                final String path = grantUri.uri.getPath();
7214                int i = pps.length;
7215                while (i > 0 && (!readMet || !writeMet)) {
7216                    i--;
7217                    PathPermission pp = pps[i];
7218                    if (pp.match(path)) {
7219                        if (!readMet) {
7220                            final String pprperm = pp.getReadPermission();
7221                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7222                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7223                                    + ": match=" + pp.match(path)
7224                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7225                            if (pprperm != null) {
7226                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7227                                        == PERMISSION_GRANTED) {
7228                                    readMet = true;
7229                                } else {
7230                                    allowDefaultRead = false;
7231                                }
7232                            }
7233                        }
7234                        if (!writeMet) {
7235                            final String ppwperm = pp.getWritePermission();
7236                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7237                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7238                                    + ": match=" + pp.match(path)
7239                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7240                            if (ppwperm != null) {
7241                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7242                                        == PERMISSION_GRANTED) {
7243                                    writeMet = true;
7244                                } else {
7245                                    allowDefaultWrite = false;
7246                                }
7247                            }
7248                        }
7249                    }
7250                }
7251            }
7252
7253            // grant unprotected <provider> read/write, if not blocked by
7254            // <path-permission> above
7255            if (allowDefaultRead) readMet = true;
7256            if (allowDefaultWrite) writeMet = true;
7257
7258        } catch (RemoteException e) {
7259            return false;
7260        }
7261
7262        return readMet && writeMet;
7263    }
7264
7265    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7266        ProviderInfo pi = null;
7267        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7268        if (cpr != null) {
7269            pi = cpr.info;
7270        } else {
7271            try {
7272                pi = AppGlobals.getPackageManager().resolveContentProvider(
7273                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7274            } catch (RemoteException ex) {
7275            }
7276        }
7277        return pi;
7278    }
7279
7280    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7281        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7282        if (targetUris != null) {
7283            return targetUris.get(grantUri);
7284        }
7285        return null;
7286    }
7287
7288    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7289            String targetPkg, int targetUid, GrantUri grantUri) {
7290        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7291        if (targetUris == null) {
7292            targetUris = Maps.newArrayMap();
7293            mGrantedUriPermissions.put(targetUid, targetUris);
7294        }
7295
7296        UriPermission perm = targetUris.get(grantUri);
7297        if (perm == null) {
7298            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7299            targetUris.put(grantUri, perm);
7300        }
7301
7302        return perm;
7303    }
7304
7305    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7306            final int modeFlags) {
7307        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7308        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7309                : UriPermission.STRENGTH_OWNED;
7310
7311        // Root gets to do everything.
7312        if (uid == 0) {
7313            return true;
7314        }
7315
7316        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7317        if (perms == null) return false;
7318
7319        // First look for exact match
7320        final UriPermission exactPerm = perms.get(grantUri);
7321        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7322            return true;
7323        }
7324
7325        // No exact match, look for prefixes
7326        final int N = perms.size();
7327        for (int i = 0; i < N; i++) {
7328            final UriPermission perm = perms.valueAt(i);
7329            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7330                    && perm.getStrength(modeFlags) >= minStrength) {
7331                return true;
7332            }
7333        }
7334
7335        return false;
7336    }
7337
7338    /**
7339     * @param uri This uri must NOT contain an embedded userId.
7340     * @param userId The userId in which the uri is to be resolved.
7341     */
7342    @Override
7343    public int checkUriPermission(Uri uri, int pid, int uid,
7344            final int modeFlags, int userId, IBinder callerToken) {
7345        enforceNotIsolatedCaller("checkUriPermission");
7346
7347        // Another redirected-binder-call permissions check as in
7348        // {@link checkPermissionWithToken}.
7349        Identity tlsIdentity = sCallerIdentity.get();
7350        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7351            uid = tlsIdentity.uid;
7352            pid = tlsIdentity.pid;
7353        }
7354
7355        // Our own process gets to do everything.
7356        if (pid == MY_PID) {
7357            return PackageManager.PERMISSION_GRANTED;
7358        }
7359        synchronized (this) {
7360            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7361                    ? PackageManager.PERMISSION_GRANTED
7362                    : PackageManager.PERMISSION_DENIED;
7363        }
7364    }
7365
7366    /**
7367     * Check if the targetPkg can be granted permission to access uri by
7368     * the callingUid using the given modeFlags.  Throws a security exception
7369     * if callingUid is not allowed to do this.  Returns the uid of the target
7370     * if the URI permission grant should be performed; returns -1 if it is not
7371     * needed (for example targetPkg already has permission to access the URI).
7372     * If you already know the uid of the target, you can supply it in
7373     * lastTargetUid else set that to -1.
7374     */
7375    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7376            final int modeFlags, int lastTargetUid) {
7377        if (!Intent.isAccessUriMode(modeFlags)) {
7378            return -1;
7379        }
7380
7381        if (targetPkg != null) {
7382            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7383                    "Checking grant " + targetPkg + " permission to " + grantUri);
7384        }
7385
7386        final IPackageManager pm = AppGlobals.getPackageManager();
7387
7388        // If this is not a content: uri, we can't do anything with it.
7389        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7390            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7391                    "Can't grant URI permission for non-content URI: " + grantUri);
7392            return -1;
7393        }
7394
7395        final String authority = grantUri.uri.getAuthority();
7396        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7397        if (pi == null) {
7398            Slog.w(TAG, "No content provider found for permission check: " +
7399                    grantUri.uri.toSafeString());
7400            return -1;
7401        }
7402
7403        int targetUid = lastTargetUid;
7404        if (targetUid < 0 && targetPkg != null) {
7405            try {
7406                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7407                if (targetUid < 0) {
7408                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7409                            "Can't grant URI permission no uid for: " + targetPkg);
7410                    return -1;
7411                }
7412            } catch (RemoteException ex) {
7413                return -1;
7414            }
7415        }
7416
7417        if (targetUid >= 0) {
7418            // First...  does the target actually need this permission?
7419            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7420                // No need to grant the target this permission.
7421                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7422                        "Target " + targetPkg + " already has full permission to " + grantUri);
7423                return -1;
7424            }
7425        } else {
7426            // First...  there is no target package, so can anyone access it?
7427            boolean allowed = pi.exported;
7428            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7429                if (pi.readPermission != null) {
7430                    allowed = false;
7431                }
7432            }
7433            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7434                if (pi.writePermission != null) {
7435                    allowed = false;
7436                }
7437            }
7438            if (allowed) {
7439                return -1;
7440            }
7441        }
7442
7443        /* There is a special cross user grant if:
7444         * - The target is on another user.
7445         * - Apps on the current user can access the uri without any uid permissions.
7446         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7447         * grant uri permissions.
7448         */
7449        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7450                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7451                modeFlags, false /*without considering the uid permissions*/);
7452
7453        // Second...  is the provider allowing granting of URI permissions?
7454        if (!specialCrossUserGrant) {
7455            if (!pi.grantUriPermissions) {
7456                throw new SecurityException("Provider " + pi.packageName
7457                        + "/" + pi.name
7458                        + " does not allow granting of Uri permissions (uri "
7459                        + grantUri + ")");
7460            }
7461            if (pi.uriPermissionPatterns != null) {
7462                final int N = pi.uriPermissionPatterns.length;
7463                boolean allowed = false;
7464                for (int i=0; i<N; i++) {
7465                    if (pi.uriPermissionPatterns[i] != null
7466                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7467                        allowed = true;
7468                        break;
7469                    }
7470                }
7471                if (!allowed) {
7472                    throw new SecurityException("Provider " + pi.packageName
7473                            + "/" + pi.name
7474                            + " does not allow granting of permission to path of Uri "
7475                            + grantUri);
7476                }
7477            }
7478        }
7479
7480        // Third...  does the caller itself have permission to access
7481        // this uri?
7482        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7483            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7484                // Require they hold a strong enough Uri permission
7485                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7486                    throw new SecurityException("Uid " + callingUid
7487                            + " does not have permission to uri " + grantUri);
7488                }
7489            }
7490        }
7491        return targetUid;
7492    }
7493
7494    /**
7495     * @param uri This uri must NOT contain an embedded userId.
7496     * @param userId The userId in which the uri is to be resolved.
7497     */
7498    @Override
7499    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7500            final int modeFlags, int userId) {
7501        enforceNotIsolatedCaller("checkGrantUriPermission");
7502        synchronized(this) {
7503            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7504                    new GrantUri(userId, uri, false), modeFlags, -1);
7505        }
7506    }
7507
7508    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7509            final int modeFlags, UriPermissionOwner owner) {
7510        if (!Intent.isAccessUriMode(modeFlags)) {
7511            return;
7512        }
7513
7514        // So here we are: the caller has the assumed permission
7515        // to the uri, and the target doesn't.  Let's now give this to
7516        // the target.
7517
7518        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7519                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7520
7521        final String authority = grantUri.uri.getAuthority();
7522        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7523        if (pi == null) {
7524            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7525            return;
7526        }
7527
7528        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7529            grantUri.prefix = true;
7530        }
7531        final UriPermission perm = findOrCreateUriPermissionLocked(
7532                pi.packageName, targetPkg, targetUid, grantUri);
7533        perm.grantModes(modeFlags, owner);
7534    }
7535
7536    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7537            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7538        if (targetPkg == null) {
7539            throw new NullPointerException("targetPkg");
7540        }
7541        int targetUid;
7542        final IPackageManager pm = AppGlobals.getPackageManager();
7543        try {
7544            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7545        } catch (RemoteException ex) {
7546            return;
7547        }
7548
7549        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7550                targetUid);
7551        if (targetUid < 0) {
7552            return;
7553        }
7554
7555        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7556                owner);
7557    }
7558
7559    static class NeededUriGrants extends ArrayList<GrantUri> {
7560        final String targetPkg;
7561        final int targetUid;
7562        final int flags;
7563
7564        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7565            this.targetPkg = targetPkg;
7566            this.targetUid = targetUid;
7567            this.flags = flags;
7568        }
7569    }
7570
7571    /**
7572     * Like checkGrantUriPermissionLocked, but takes an Intent.
7573     */
7574    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7575            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7576        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7577                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7578                + " clip=" + (intent != null ? intent.getClipData() : null)
7579                + " from " + intent + "; flags=0x"
7580                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7581
7582        if (targetPkg == null) {
7583            throw new NullPointerException("targetPkg");
7584        }
7585
7586        if (intent == null) {
7587            return null;
7588        }
7589        Uri data = intent.getData();
7590        ClipData clip = intent.getClipData();
7591        if (data == null && clip == null) {
7592            return null;
7593        }
7594        // Default userId for uris in the intent (if they don't specify it themselves)
7595        int contentUserHint = intent.getContentUserHint();
7596        if (contentUserHint == UserHandle.USER_CURRENT) {
7597            contentUserHint = UserHandle.getUserId(callingUid);
7598        }
7599        final IPackageManager pm = AppGlobals.getPackageManager();
7600        int targetUid;
7601        if (needed != null) {
7602            targetUid = needed.targetUid;
7603        } else {
7604            try {
7605                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7606            } catch (RemoteException ex) {
7607                return null;
7608            }
7609            if (targetUid < 0) {
7610                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7611                        "Can't grant URI permission no uid for: " + targetPkg
7612                        + " on user " + targetUserId);
7613                return null;
7614            }
7615        }
7616        if (data != null) {
7617            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7618            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7619                    targetUid);
7620            if (targetUid > 0) {
7621                if (needed == null) {
7622                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7623                }
7624                needed.add(grantUri);
7625            }
7626        }
7627        if (clip != null) {
7628            for (int i=0; i<clip.getItemCount(); i++) {
7629                Uri uri = clip.getItemAt(i).getUri();
7630                if (uri != null) {
7631                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7632                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7633                            targetUid);
7634                    if (targetUid > 0) {
7635                        if (needed == null) {
7636                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7637                        }
7638                        needed.add(grantUri);
7639                    }
7640                } else {
7641                    Intent clipIntent = clip.getItemAt(i).getIntent();
7642                    if (clipIntent != null) {
7643                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7644                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7645                        if (newNeeded != null) {
7646                            needed = newNeeded;
7647                        }
7648                    }
7649                }
7650            }
7651        }
7652
7653        return needed;
7654    }
7655
7656    /**
7657     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7658     */
7659    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7660            UriPermissionOwner owner) {
7661        if (needed != null) {
7662            for (int i=0; i<needed.size(); i++) {
7663                GrantUri grantUri = needed.get(i);
7664                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7665                        grantUri, needed.flags, owner);
7666            }
7667        }
7668    }
7669
7670    void grantUriPermissionFromIntentLocked(int callingUid,
7671            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7672        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7673                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7674        if (needed == null) {
7675            return;
7676        }
7677
7678        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7679    }
7680
7681    /**
7682     * @param uri This uri must NOT contain an embedded userId.
7683     * @param userId The userId in which the uri is to be resolved.
7684     */
7685    @Override
7686    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7687            final int modeFlags, int userId) {
7688        enforceNotIsolatedCaller("grantUriPermission");
7689        GrantUri grantUri = new GrantUri(userId, uri, false);
7690        synchronized(this) {
7691            final ProcessRecord r = getRecordForAppLocked(caller);
7692            if (r == null) {
7693                throw new SecurityException("Unable to find app for caller "
7694                        + caller
7695                        + " when granting permission to uri " + grantUri);
7696            }
7697            if (targetPkg == null) {
7698                throw new IllegalArgumentException("null target");
7699            }
7700            if (grantUri == null) {
7701                throw new IllegalArgumentException("null uri");
7702            }
7703
7704            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7705                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7706                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7707                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7708
7709            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7710                    UserHandle.getUserId(r.uid));
7711        }
7712    }
7713
7714    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7715        if (perm.modeFlags == 0) {
7716            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7717                    perm.targetUid);
7718            if (perms != null) {
7719                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7720                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7721
7722                perms.remove(perm.uri);
7723                if (perms.isEmpty()) {
7724                    mGrantedUriPermissions.remove(perm.targetUid);
7725                }
7726            }
7727        }
7728    }
7729
7730    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7731        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7732                "Revoking all granted permissions to " + grantUri);
7733
7734        final IPackageManager pm = AppGlobals.getPackageManager();
7735        final String authority = grantUri.uri.getAuthority();
7736        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7737        if (pi == null) {
7738            Slog.w(TAG, "No content provider found for permission revoke: "
7739                    + grantUri.toSafeString());
7740            return;
7741        }
7742
7743        // Does the caller have this permission on the URI?
7744        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7745            // If they don't have direct access to the URI, then revoke any
7746            // ownerless URI permissions that have been granted to them.
7747            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7748            if (perms != null) {
7749                boolean persistChanged = false;
7750                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7751                    final UriPermission perm = it.next();
7752                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7753                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7754                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7755                                "Revoking non-owned " + perm.targetUid
7756                                + " permission to " + perm.uri);
7757                        persistChanged |= perm.revokeModes(
7758                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7759                        if (perm.modeFlags == 0) {
7760                            it.remove();
7761                        }
7762                    }
7763                }
7764                if (perms.isEmpty()) {
7765                    mGrantedUriPermissions.remove(callingUid);
7766                }
7767                if (persistChanged) {
7768                    schedulePersistUriGrants();
7769                }
7770            }
7771            return;
7772        }
7773
7774        boolean persistChanged = false;
7775
7776        // Go through all of the permissions and remove any that match.
7777        int N = mGrantedUriPermissions.size();
7778        for (int i = 0; i < N; i++) {
7779            final int targetUid = mGrantedUriPermissions.keyAt(i);
7780            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7781
7782            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7783                final UriPermission perm = it.next();
7784                if (perm.uri.sourceUserId == grantUri.sourceUserId
7785                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7786                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7787                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7788                    persistChanged |= perm.revokeModes(
7789                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7790                    if (perm.modeFlags == 0) {
7791                        it.remove();
7792                    }
7793                }
7794            }
7795
7796            if (perms.isEmpty()) {
7797                mGrantedUriPermissions.remove(targetUid);
7798                N--;
7799                i--;
7800            }
7801        }
7802
7803        if (persistChanged) {
7804            schedulePersistUriGrants();
7805        }
7806    }
7807
7808    /**
7809     * @param uri This uri must NOT contain an embedded userId.
7810     * @param userId The userId in which the uri is to be resolved.
7811     */
7812    @Override
7813    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7814            int userId) {
7815        enforceNotIsolatedCaller("revokeUriPermission");
7816        synchronized(this) {
7817            final ProcessRecord r = getRecordForAppLocked(caller);
7818            if (r == null) {
7819                throw new SecurityException("Unable to find app for caller "
7820                        + caller
7821                        + " when revoking permission to uri " + uri);
7822            }
7823            if (uri == null) {
7824                Slog.w(TAG, "revokeUriPermission: null uri");
7825                return;
7826            }
7827
7828            if (!Intent.isAccessUriMode(modeFlags)) {
7829                return;
7830            }
7831
7832            final String authority = uri.getAuthority();
7833            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7834            if (pi == null) {
7835                Slog.w(TAG, "No content provider found for permission revoke: "
7836                        + uri.toSafeString());
7837                return;
7838            }
7839
7840            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7841        }
7842    }
7843
7844    /**
7845     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7846     * given package.
7847     *
7848     * @param packageName Package name to match, or {@code null} to apply to all
7849     *            packages.
7850     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7851     *            to all users.
7852     * @param persistable If persistable grants should be removed.
7853     */
7854    private void removeUriPermissionsForPackageLocked(
7855            String packageName, int userHandle, boolean persistable) {
7856        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7857            throw new IllegalArgumentException("Must narrow by either package or user");
7858        }
7859
7860        boolean persistChanged = false;
7861
7862        int N = mGrantedUriPermissions.size();
7863        for (int i = 0; i < N; i++) {
7864            final int targetUid = mGrantedUriPermissions.keyAt(i);
7865            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7866
7867            // Only inspect grants matching user
7868            if (userHandle == UserHandle.USER_ALL
7869                    || userHandle == UserHandle.getUserId(targetUid)) {
7870                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7871                    final UriPermission perm = it.next();
7872
7873                    // Only inspect grants matching package
7874                    if (packageName == null || perm.sourcePkg.equals(packageName)
7875                            || perm.targetPkg.equals(packageName)) {
7876                        persistChanged |= perm.revokeModes(persistable
7877                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7878
7879                        // Only remove when no modes remain; any persisted grants
7880                        // will keep this alive.
7881                        if (perm.modeFlags == 0) {
7882                            it.remove();
7883                        }
7884                    }
7885                }
7886
7887                if (perms.isEmpty()) {
7888                    mGrantedUriPermissions.remove(targetUid);
7889                    N--;
7890                    i--;
7891                }
7892            }
7893        }
7894
7895        if (persistChanged) {
7896            schedulePersistUriGrants();
7897        }
7898    }
7899
7900    @Override
7901    public IBinder newUriPermissionOwner(String name) {
7902        enforceNotIsolatedCaller("newUriPermissionOwner");
7903        synchronized(this) {
7904            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7905            return owner.getExternalTokenLocked();
7906        }
7907    }
7908
7909    /**
7910     * @param uri This uri must NOT contain an embedded userId.
7911     * @param sourceUserId The userId in which the uri is to be resolved.
7912     * @param targetUserId The userId of the app that receives the grant.
7913     */
7914    @Override
7915    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7916            final int modeFlags, int sourceUserId, int targetUserId) {
7917        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
7918                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
7919                "grantUriPermissionFromOwner", null);
7920        synchronized(this) {
7921            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7922            if (owner == null) {
7923                throw new IllegalArgumentException("Unknown owner: " + token);
7924            }
7925            if (fromUid != Binder.getCallingUid()) {
7926                if (Binder.getCallingUid() != Process.myUid()) {
7927                    // Only system code can grant URI permissions on behalf
7928                    // of other users.
7929                    throw new SecurityException("nice try");
7930                }
7931            }
7932            if (targetPkg == null) {
7933                throw new IllegalArgumentException("null target");
7934            }
7935            if (uri == null) {
7936                throw new IllegalArgumentException("null uri");
7937            }
7938
7939            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7940                    modeFlags, owner, targetUserId);
7941        }
7942    }
7943
7944    /**
7945     * @param uri This uri must NOT contain an embedded userId.
7946     * @param userId The userId in which the uri is to be resolved.
7947     */
7948    @Override
7949    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7950        synchronized(this) {
7951            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7952            if (owner == null) {
7953                throw new IllegalArgumentException("Unknown owner: " + token);
7954            }
7955
7956            if (uri == null) {
7957                owner.removeUriPermissionsLocked(mode);
7958            } else {
7959                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7960            }
7961        }
7962    }
7963
7964    private void schedulePersistUriGrants() {
7965        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7966            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7967                    10 * DateUtils.SECOND_IN_MILLIS);
7968        }
7969    }
7970
7971    private void writeGrantedUriPermissions() {
7972        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7973
7974        // Snapshot permissions so we can persist without lock
7975        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7976        synchronized (this) {
7977            final int size = mGrantedUriPermissions.size();
7978            for (int i = 0; i < size; i++) {
7979                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7980                for (UriPermission perm : perms.values()) {
7981                    if (perm.persistedModeFlags != 0) {
7982                        persist.add(perm.snapshot());
7983                    }
7984                }
7985            }
7986        }
7987
7988        FileOutputStream fos = null;
7989        try {
7990            fos = mGrantFile.startWrite();
7991
7992            XmlSerializer out = new FastXmlSerializer();
7993            out.setOutput(fos, StandardCharsets.UTF_8.name());
7994            out.startDocument(null, true);
7995            out.startTag(null, TAG_URI_GRANTS);
7996            for (UriPermission.Snapshot perm : persist) {
7997                out.startTag(null, TAG_URI_GRANT);
7998                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7999                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8000                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8001                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8002                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8003                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8004                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8005                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8006                out.endTag(null, TAG_URI_GRANT);
8007            }
8008            out.endTag(null, TAG_URI_GRANTS);
8009            out.endDocument();
8010
8011            mGrantFile.finishWrite(fos);
8012        } catch (IOException e) {
8013            if (fos != null) {
8014                mGrantFile.failWrite(fos);
8015            }
8016        }
8017    }
8018
8019    private void readGrantedUriPermissionsLocked() {
8020        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8021
8022        final long now = System.currentTimeMillis();
8023
8024        FileInputStream fis = null;
8025        try {
8026            fis = mGrantFile.openRead();
8027            final XmlPullParser in = Xml.newPullParser();
8028            in.setInput(fis, StandardCharsets.UTF_8.name());
8029
8030            int type;
8031            while ((type = in.next()) != END_DOCUMENT) {
8032                final String tag = in.getName();
8033                if (type == START_TAG) {
8034                    if (TAG_URI_GRANT.equals(tag)) {
8035                        final int sourceUserId;
8036                        final int targetUserId;
8037                        final int userHandle = readIntAttribute(in,
8038                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8039                        if (userHandle != UserHandle.USER_NULL) {
8040                            // For backwards compatibility.
8041                            sourceUserId = userHandle;
8042                            targetUserId = userHandle;
8043                        } else {
8044                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8045                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8046                        }
8047                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8048                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8049                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8050                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8051                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8052                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8053
8054                        // Sanity check that provider still belongs to source package
8055                        final ProviderInfo pi = getProviderInfoLocked(
8056                                uri.getAuthority(), sourceUserId);
8057                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8058                            int targetUid = -1;
8059                            try {
8060                                targetUid = AppGlobals.getPackageManager()
8061                                        .getPackageUid(targetPkg, targetUserId);
8062                            } catch (RemoteException e) {
8063                            }
8064                            if (targetUid != -1) {
8065                                final UriPermission perm = findOrCreateUriPermissionLocked(
8066                                        sourcePkg, targetPkg, targetUid,
8067                                        new GrantUri(sourceUserId, uri, prefix));
8068                                perm.initPersistedModes(modeFlags, createdTime);
8069                            }
8070                        } else {
8071                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8072                                    + " but instead found " + pi);
8073                        }
8074                    }
8075                }
8076            }
8077        } catch (FileNotFoundException e) {
8078            // Missing grants is okay
8079        } catch (IOException e) {
8080            Slog.wtf(TAG, "Failed reading Uri grants", e);
8081        } catch (XmlPullParserException e) {
8082            Slog.wtf(TAG, "Failed reading Uri grants", e);
8083        } finally {
8084            IoUtils.closeQuietly(fis);
8085        }
8086    }
8087
8088    /**
8089     * @param uri This uri must NOT contain an embedded userId.
8090     * @param userId The userId in which the uri is to be resolved.
8091     */
8092    @Override
8093    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8094        enforceNotIsolatedCaller("takePersistableUriPermission");
8095
8096        Preconditions.checkFlagsArgument(modeFlags,
8097                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8098
8099        synchronized (this) {
8100            final int callingUid = Binder.getCallingUid();
8101            boolean persistChanged = false;
8102            GrantUri grantUri = new GrantUri(userId, uri, false);
8103
8104            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8105                    new GrantUri(userId, uri, false));
8106            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8107                    new GrantUri(userId, uri, true));
8108
8109            final boolean exactValid = (exactPerm != null)
8110                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8111            final boolean prefixValid = (prefixPerm != null)
8112                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8113
8114            if (!(exactValid || prefixValid)) {
8115                throw new SecurityException("No persistable permission grants found for UID "
8116                        + callingUid + " and Uri " + grantUri.toSafeString());
8117            }
8118
8119            if (exactValid) {
8120                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8121            }
8122            if (prefixValid) {
8123                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8124            }
8125
8126            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8127
8128            if (persistChanged) {
8129                schedulePersistUriGrants();
8130            }
8131        }
8132    }
8133
8134    /**
8135     * @param uri This uri must NOT contain an embedded userId.
8136     * @param userId The userId in which the uri is to be resolved.
8137     */
8138    @Override
8139    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8140        enforceNotIsolatedCaller("releasePersistableUriPermission");
8141
8142        Preconditions.checkFlagsArgument(modeFlags,
8143                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8144
8145        synchronized (this) {
8146            final int callingUid = Binder.getCallingUid();
8147            boolean persistChanged = false;
8148
8149            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8150                    new GrantUri(userId, uri, false));
8151            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8152                    new GrantUri(userId, uri, true));
8153            if (exactPerm == null && prefixPerm == null) {
8154                throw new SecurityException("No permission grants found for UID " + callingUid
8155                        + " and Uri " + uri.toSafeString());
8156            }
8157
8158            if (exactPerm != null) {
8159                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8160                removeUriPermissionIfNeededLocked(exactPerm);
8161            }
8162            if (prefixPerm != null) {
8163                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8164                removeUriPermissionIfNeededLocked(prefixPerm);
8165            }
8166
8167            if (persistChanged) {
8168                schedulePersistUriGrants();
8169            }
8170        }
8171    }
8172
8173    /**
8174     * Prune any older {@link UriPermission} for the given UID until outstanding
8175     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8176     *
8177     * @return if any mutations occured that require persisting.
8178     */
8179    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8180        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8181        if (perms == null) return false;
8182        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8183
8184        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8185        for (UriPermission perm : perms.values()) {
8186            if (perm.persistedModeFlags != 0) {
8187                persisted.add(perm);
8188            }
8189        }
8190
8191        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8192        if (trimCount <= 0) return false;
8193
8194        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8195        for (int i = 0; i < trimCount; i++) {
8196            final UriPermission perm = persisted.get(i);
8197
8198            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8199                    "Trimming grant created at " + perm.persistedCreateTime);
8200
8201            perm.releasePersistableModes(~0);
8202            removeUriPermissionIfNeededLocked(perm);
8203        }
8204
8205        return true;
8206    }
8207
8208    @Override
8209    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8210            String packageName, boolean incoming) {
8211        enforceNotIsolatedCaller("getPersistedUriPermissions");
8212        Preconditions.checkNotNull(packageName, "packageName");
8213
8214        final int callingUid = Binder.getCallingUid();
8215        final IPackageManager pm = AppGlobals.getPackageManager();
8216        try {
8217            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8218            if (packageUid != callingUid) {
8219                throw new SecurityException(
8220                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8221            }
8222        } catch (RemoteException e) {
8223            throw new SecurityException("Failed to verify package name ownership");
8224        }
8225
8226        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8227        synchronized (this) {
8228            if (incoming) {
8229                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8230                        callingUid);
8231                if (perms == null) {
8232                    Slog.w(TAG, "No permission grants found for " + packageName);
8233                } else {
8234                    for (UriPermission perm : perms.values()) {
8235                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8236                            result.add(perm.buildPersistedPublicApiObject());
8237                        }
8238                    }
8239                }
8240            } else {
8241                final int size = mGrantedUriPermissions.size();
8242                for (int i = 0; i < size; i++) {
8243                    final ArrayMap<GrantUri, UriPermission> perms =
8244                            mGrantedUriPermissions.valueAt(i);
8245                    for (UriPermission perm : perms.values()) {
8246                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8247                            result.add(perm.buildPersistedPublicApiObject());
8248                        }
8249                    }
8250                }
8251            }
8252        }
8253        return new ParceledListSlice<android.content.UriPermission>(result);
8254    }
8255
8256    @Override
8257    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8258        synchronized (this) {
8259            ProcessRecord app =
8260                who != null ? getRecordForAppLocked(who) : null;
8261            if (app == null) return;
8262
8263            Message msg = Message.obtain();
8264            msg.what = WAIT_FOR_DEBUGGER_MSG;
8265            msg.obj = app;
8266            msg.arg1 = waiting ? 1 : 0;
8267            mUiHandler.sendMessage(msg);
8268        }
8269    }
8270
8271    @Override
8272    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8273        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8274        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8275        outInfo.availMem = Process.getFreeMemory();
8276        outInfo.totalMem = Process.getTotalMemory();
8277        outInfo.threshold = homeAppMem;
8278        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8279        outInfo.hiddenAppThreshold = cachedAppMem;
8280        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8281                ProcessList.SERVICE_ADJ);
8282        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8283                ProcessList.VISIBLE_APP_ADJ);
8284        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8285                ProcessList.FOREGROUND_APP_ADJ);
8286    }
8287
8288    // =========================================================
8289    // TASK MANAGEMENT
8290    // =========================================================
8291
8292    @Override
8293    public List<IAppTask> getAppTasks(String callingPackage) {
8294        int callingUid = Binder.getCallingUid();
8295        long ident = Binder.clearCallingIdentity();
8296
8297        synchronized(this) {
8298            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8299            try {
8300                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8301
8302                final int N = mRecentTasks.size();
8303                for (int i = 0; i < N; i++) {
8304                    TaskRecord tr = mRecentTasks.get(i);
8305                    // Skip tasks that do not match the caller.  We don't need to verify
8306                    // callingPackage, because we are also limiting to callingUid and know
8307                    // that will limit to the correct security sandbox.
8308                    if (tr.effectiveUid != callingUid) {
8309                        continue;
8310                    }
8311                    Intent intent = tr.getBaseIntent();
8312                    if (intent == null ||
8313                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8314                        continue;
8315                    }
8316                    ActivityManager.RecentTaskInfo taskInfo =
8317                            createRecentTaskInfoFromTaskRecord(tr);
8318                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8319                    list.add(taskImpl);
8320                }
8321            } finally {
8322                Binder.restoreCallingIdentity(ident);
8323            }
8324            return list;
8325        }
8326    }
8327
8328    @Override
8329    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8330        final int callingUid = Binder.getCallingUid();
8331        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8332
8333        synchronized(this) {
8334            if (DEBUG_ALL) Slog.v(
8335                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8336
8337            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8338                    callingUid);
8339
8340            // TODO: Improve with MRU list from all ActivityStacks.
8341            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8342        }
8343
8344        return list;
8345    }
8346
8347    /**
8348     * Creates a new RecentTaskInfo from a TaskRecord.
8349     */
8350    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8351        // Update the task description to reflect any changes in the task stack
8352        tr.updateTaskDescription();
8353
8354        // Compose the recent task info
8355        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8356        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8357        rti.persistentId = tr.taskId;
8358        rti.baseIntent = new Intent(tr.getBaseIntent());
8359        rti.origActivity = tr.origActivity;
8360        rti.realActivity = tr.realActivity;
8361        rti.description = tr.lastDescription;
8362        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8363        rti.userId = tr.userId;
8364        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8365        rti.firstActiveTime = tr.firstActiveTime;
8366        rti.lastActiveTime = tr.lastActiveTime;
8367        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8368        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8369        rti.numActivities = 0;
8370        if (tr.mBounds != null) {
8371            rti.bounds = new Rect(tr.mBounds);
8372        }
8373
8374        ActivityRecord base = null;
8375        ActivityRecord top = null;
8376        ActivityRecord tmp;
8377
8378        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8379            tmp = tr.mActivities.get(i);
8380            if (tmp.finishing) {
8381                continue;
8382            }
8383            base = tmp;
8384            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8385                top = base;
8386            }
8387            rti.numActivities++;
8388        }
8389
8390        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8391        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8392
8393        return rti;
8394    }
8395
8396    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8397        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8398                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8399        if (!allowed) {
8400            if (checkPermission(android.Manifest.permission.GET_TASKS,
8401                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8402                // Temporary compatibility: some existing apps on the system image may
8403                // still be requesting the old permission and not switched to the new
8404                // one; if so, we'll still allow them full access.  This means we need
8405                // to see if they are holding the old permission and are a system app.
8406                try {
8407                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8408                        allowed = true;
8409                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8410                                + " is using old GET_TASKS but privileged; allowing");
8411                    }
8412                } catch (RemoteException e) {
8413                }
8414            }
8415        }
8416        if (!allowed) {
8417            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8418                    + " does not hold REAL_GET_TASKS; limiting output");
8419        }
8420        return allowed;
8421    }
8422
8423    @Override
8424    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8425        final int callingUid = Binder.getCallingUid();
8426        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8427                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8428
8429        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8430        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8431        synchronized (this) {
8432            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8433                    callingUid);
8434            final boolean detailed = checkCallingPermission(
8435                    android.Manifest.permission.GET_DETAILED_TASKS)
8436                    == PackageManager.PERMISSION_GRANTED;
8437
8438            final int recentsCount = mRecentTasks.size();
8439            ArrayList<ActivityManager.RecentTaskInfo> res =
8440                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8441
8442            final Set<Integer> includedUsers;
8443            if (includeProfiles) {
8444                includedUsers = mUserController.getProfileIds(userId);
8445            } else {
8446                includedUsers = new HashSet<>();
8447            }
8448            includedUsers.add(Integer.valueOf(userId));
8449
8450            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8451                TaskRecord tr = mRecentTasks.get(i);
8452                // Only add calling user or related users recent tasks
8453                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8454                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8455                    continue;
8456                }
8457
8458                // Return the entry if desired by the caller.  We always return
8459                // the first entry, because callers always expect this to be the
8460                // foreground app.  We may filter others if the caller has
8461                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8462                // we should exclude the entry.
8463
8464                if (i == 0
8465                        || withExcluded
8466                        || (tr.intent == null)
8467                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8468                                == 0)) {
8469                    if (!allowed) {
8470                        // If the caller doesn't have the GET_TASKS permission, then only
8471                        // allow them to see a small subset of tasks -- their own and home.
8472                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8473                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8474                            continue;
8475                        }
8476                    }
8477                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8478                        if (tr.stack != null && tr.stack.isHomeStack()) {
8479                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8480                                    "Skipping, home stack task: " + tr);
8481                            continue;
8482                        }
8483                    }
8484                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8485                        // Don't include auto remove tasks that are finished or finishing.
8486                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8487                                "Skipping, auto-remove without activity: " + tr);
8488                        continue;
8489                    }
8490                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8491                            && !tr.isAvailable) {
8492                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8493                                "Skipping, unavail real act: " + tr);
8494                        continue;
8495                    }
8496
8497                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8498                    if (!detailed) {
8499                        rti.baseIntent.replaceExtras((Bundle)null);
8500                    }
8501
8502                    res.add(rti);
8503                    maxNum--;
8504                }
8505            }
8506            return res;
8507        }
8508    }
8509
8510    @Override
8511    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8512        synchronized (this) {
8513            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8514                    "getTaskThumbnail()");
8515            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8516                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8517            if (tr != null) {
8518                return tr.getTaskThumbnailLocked();
8519            }
8520        }
8521        return null;
8522    }
8523
8524    @Override
8525    public int addAppTask(IBinder activityToken, Intent intent,
8526            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8527        final int callingUid = Binder.getCallingUid();
8528        final long callingIdent = Binder.clearCallingIdentity();
8529
8530        try {
8531            synchronized (this) {
8532                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8533                if (r == null) {
8534                    throw new IllegalArgumentException("Activity does not exist; token="
8535                            + activityToken);
8536                }
8537                ComponentName comp = intent.getComponent();
8538                if (comp == null) {
8539                    throw new IllegalArgumentException("Intent " + intent
8540                            + " must specify explicit component");
8541                }
8542                if (thumbnail.getWidth() != mThumbnailWidth
8543                        || thumbnail.getHeight() != mThumbnailHeight) {
8544                    throw new IllegalArgumentException("Bad thumbnail size: got "
8545                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8546                            + mThumbnailWidth + "x" + mThumbnailHeight);
8547                }
8548                if (intent.getSelector() != null) {
8549                    intent.setSelector(null);
8550                }
8551                if (intent.getSourceBounds() != null) {
8552                    intent.setSourceBounds(null);
8553                }
8554                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8555                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8556                        // The caller has added this as an auto-remove task...  that makes no
8557                        // sense, so turn off auto-remove.
8558                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8559                    }
8560                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8561                    // Must be a new task.
8562                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8563                }
8564                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8565                    mLastAddedTaskActivity = null;
8566                }
8567                ActivityInfo ainfo = mLastAddedTaskActivity;
8568                if (ainfo == null) {
8569                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8570                            comp, 0, UserHandle.getUserId(callingUid));
8571                    if (ainfo.applicationInfo.uid != callingUid) {
8572                        throw new SecurityException(
8573                                "Can't add task for another application: target uid="
8574                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8575                    }
8576                }
8577
8578                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8579                        intent, description);
8580
8581                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8582                if (trimIdx >= 0) {
8583                    // If this would have caused a trim, then we'll abort because that
8584                    // means it would be added at the end of the list but then just removed.
8585                    return INVALID_TASK_ID;
8586                }
8587
8588                final int N = mRecentTasks.size();
8589                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8590                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8591                    tr.removedFromRecents();
8592                }
8593
8594                task.inRecents = true;
8595                mRecentTasks.add(task);
8596                r.task.stack.addTask(task, false, false);
8597
8598                task.setLastThumbnail(thumbnail);
8599                task.freeLastThumbnail();
8600
8601                return task.taskId;
8602            }
8603        } finally {
8604            Binder.restoreCallingIdentity(callingIdent);
8605        }
8606    }
8607
8608    @Override
8609    public Point getAppTaskThumbnailSize() {
8610        synchronized (this) {
8611            return new Point(mThumbnailWidth,  mThumbnailHeight);
8612        }
8613    }
8614
8615    @Override
8616    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8617        synchronized (this) {
8618            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8619            if (r != null) {
8620                r.setTaskDescription(td);
8621                r.task.updateTaskDescription();
8622            }
8623        }
8624    }
8625
8626    @Override
8627    public void setTaskResizeable(int taskId, boolean resizeable) {
8628        synchronized (this) {
8629            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8630                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8631            if (task == null) {
8632                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8633                return;
8634            }
8635            if (task.mResizeable != resizeable) {
8636                task.mResizeable = resizeable;
8637                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8638                mStackSupervisor.resumeTopActivitiesLocked();
8639            }
8640        }
8641    }
8642
8643    @Override
8644    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8645        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8646                "resizeTask()");
8647        long ident = Binder.clearCallingIdentity();
8648        try {
8649            synchronized (this) {
8650                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8651                if (task == null) {
8652                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8653                    return;
8654                }
8655                // Place the task in the right stack if it isn't there already based on
8656                // the requested bounds.
8657                // The stack transition logic is:
8658                // - a null bounds on a freeform task moves that task to fullscreen
8659                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8660                //   that task to freeform
8661                // - otherwise the task is not moved
8662                int stackId = task.stack.mStackId;
8663                if (!StackId.isTaskResizeAllowed(stackId)) {
8664                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8665                }
8666                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8667                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8668                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8669                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8670                }
8671                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8672                if (stackId != task.stack.mStackId) {
8673                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8674                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8675                    preserveWindow = false;
8676                }
8677
8678                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8679            }
8680        } finally {
8681            Binder.restoreCallingIdentity(ident);
8682        }
8683    }
8684
8685    @Override
8686    public Rect getTaskBounds(int taskId) {
8687        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8688                "getTaskBounds()");
8689        long ident = Binder.clearCallingIdentity();
8690        Rect rect = new Rect();
8691        try {
8692            synchronized (this) {
8693                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8694                if (task == null) {
8695                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8696                    return rect;
8697                }
8698                mWindowManager.getTaskBounds(task.taskId, rect);
8699            }
8700        } finally {
8701            Binder.restoreCallingIdentity(ident);
8702        }
8703        return rect;
8704    }
8705
8706    @Override
8707    public Bitmap getTaskDescriptionIcon(String filename) {
8708        if (!FileUtils.isValidExtFilename(filename)
8709                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8710            throw new IllegalArgumentException("Bad filename: " + filename);
8711        }
8712        return mTaskPersister.getTaskDescriptionIcon(filename);
8713    }
8714
8715    @Override
8716    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8717            throws RemoteException {
8718        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8719                opts.getCustomInPlaceResId() == 0) {
8720            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8721                    "with valid animation");
8722        }
8723        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8724        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8725                opts.getCustomInPlaceResId());
8726        mWindowManager.executeAppTransition();
8727    }
8728
8729    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
8730            boolean removeFromRecents) {
8731        if (removeFromRecents) {
8732            mRecentTasks.remove(tr);
8733            tr.removedFromRecents();
8734        }
8735        ComponentName component = tr.getBaseIntent().getComponent();
8736        if (component == null) {
8737            Slog.w(TAG, "No component for base intent of task: " + tr);
8738            return;
8739        }
8740
8741        // Find any running services associated with this app and stop if needed.
8742        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8743
8744        if (!killProcess) {
8745            return;
8746        }
8747
8748        // Determine if the process(es) for this task should be killed.
8749        final String pkg = component.getPackageName();
8750        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8751        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8752        for (int i = 0; i < pmap.size(); i++) {
8753
8754            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8755            for (int j = 0; j < uids.size(); j++) {
8756                ProcessRecord proc = uids.valueAt(j);
8757                if (proc.userId != tr.userId) {
8758                    // Don't kill process for a different user.
8759                    continue;
8760                }
8761                if (proc == mHomeProcess) {
8762                    // Don't kill the home process along with tasks from the same package.
8763                    continue;
8764                }
8765                if (!proc.pkgList.containsKey(pkg)) {
8766                    // Don't kill process that is not associated with this task.
8767                    continue;
8768                }
8769
8770                for (int k = 0; k < proc.activities.size(); k++) {
8771                    TaskRecord otherTask = proc.activities.get(k).task;
8772                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8773                        // Don't kill process(es) that has an activity in a different task that is
8774                        // also in recents.
8775                        return;
8776                    }
8777                }
8778
8779                if (proc.foregroundServices) {
8780                    // Don't kill process(es) with foreground service.
8781                    return;
8782                }
8783
8784                // Add process to kill list.
8785                procsToKill.add(proc);
8786            }
8787        }
8788
8789        // Kill the running processes.
8790        for (int i = 0; i < procsToKill.size(); i++) {
8791            ProcessRecord pr = procsToKill.get(i);
8792            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8793                    && pr.curReceiver == null) {
8794                pr.kill("remove task", true);
8795            } else {
8796                // We delay killing processes that are not in the background or running a receiver.
8797                pr.waitingToKill = "remove task";
8798            }
8799        }
8800    }
8801
8802    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8803        // Remove all tasks with activities in the specified package from the list of recent tasks
8804        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8805            TaskRecord tr = mRecentTasks.get(i);
8806            if (tr.userId != userId) continue;
8807
8808            ComponentName cn = tr.intent.getComponent();
8809            if (cn != null && cn.getPackageName().equals(packageName)) {
8810                // If the package name matches, remove the task.
8811                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
8812            }
8813        }
8814    }
8815
8816    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8817            int userId) {
8818
8819        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8820            TaskRecord tr = mRecentTasks.get(i);
8821            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8822                continue;
8823            }
8824
8825            ComponentName cn = tr.intent.getComponent();
8826            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8827                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8828            if (sameComponent) {
8829                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
8830            }
8831        }
8832    }
8833
8834    /**
8835     * Removes the task with the specified task id.
8836     *
8837     * @param taskId Identifier of the task to be removed.
8838     * @param killProcess Kill any process associated with the task if possible.
8839     * @param removeFromRecents Whether to also remove the task from recents.
8840     * @return Returns true if the given task was found and removed.
8841     */
8842    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
8843            boolean removeFromRecents) {
8844        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8845                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8846        if (tr != null) {
8847            tr.removeTaskActivitiesLocked();
8848            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
8849            if (tr.isPersistable) {
8850                notifyTaskPersisterLocked(null, true);
8851            }
8852            return true;
8853        }
8854        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8855        return false;
8856    }
8857
8858    @Override
8859    public boolean removeTask(int taskId) {
8860        synchronized (this) {
8861            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8862                    "removeTask()");
8863            long ident = Binder.clearCallingIdentity();
8864            try {
8865                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
8866            } finally {
8867                Binder.restoreCallingIdentity(ident);
8868            }
8869        }
8870    }
8871
8872    /**
8873     * TODO: Add mController hook
8874     */
8875    @Override
8876    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
8877        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8878
8879        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8880        synchronized(this) {
8881            moveTaskToFrontLocked(taskId, flags, bOptions);
8882        }
8883    }
8884
8885    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
8886        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
8887
8888        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8889                Binder.getCallingUid(), -1, -1, "Task to front")) {
8890            ActivityOptions.abort(options);
8891            return;
8892        }
8893        final long origId = Binder.clearCallingIdentity();
8894        try {
8895            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8896            if (task == null) {
8897                Slog.d(TAG, "Could not find task for id: "+ taskId);
8898                return;
8899            }
8900            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8901                mStackSupervisor.showLockTaskToast();
8902                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8903                return;
8904            }
8905            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8906            if (prev != null && prev.isRecentsActivity()) {
8907                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8908            }
8909            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8910        } finally {
8911            Binder.restoreCallingIdentity(origId);
8912        }
8913        ActivityOptions.abort(options);
8914    }
8915
8916    /**
8917     * Moves an activity, and all of the other activities within the same task, to the bottom
8918     * of the history stack.  The activity's order within the task is unchanged.
8919     *
8920     * @param token A reference to the activity we wish to move
8921     * @param nonRoot If false then this only works if the activity is the root
8922     *                of a task; if true it will work for any activity in a task.
8923     * @return Returns true if the move completed, false if not.
8924     */
8925    @Override
8926    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8927        enforceNotIsolatedCaller("moveActivityTaskToBack");
8928        synchronized(this) {
8929            final long origId = Binder.clearCallingIdentity();
8930            try {
8931                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8932                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8933                if (task != null) {
8934                    if (mStackSupervisor.isLockedTask(task)) {
8935                        mStackSupervisor.showLockTaskToast();
8936                        return false;
8937                    }
8938                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8939                }
8940            } finally {
8941                Binder.restoreCallingIdentity(origId);
8942            }
8943        }
8944        return false;
8945    }
8946
8947    @Override
8948    public void moveTaskBackwards(int task) {
8949        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8950                "moveTaskBackwards()");
8951
8952        synchronized(this) {
8953            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8954                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8955                return;
8956            }
8957            final long origId = Binder.clearCallingIdentity();
8958            moveTaskBackwardsLocked(task);
8959            Binder.restoreCallingIdentity(origId);
8960        }
8961    }
8962
8963    private final void moveTaskBackwardsLocked(int task) {
8964        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8965    }
8966
8967    @Override
8968    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8969            IActivityContainerCallback callback) throws RemoteException {
8970        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8971                "createActivityContainer()");
8972        synchronized (this) {
8973            if (parentActivityToken == null) {
8974                throw new IllegalArgumentException("parent token must not be null");
8975            }
8976            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8977            if (r == null) {
8978                return null;
8979            }
8980            if (callback == null) {
8981                throw new IllegalArgumentException("callback must not be null");
8982            }
8983            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8984        }
8985    }
8986
8987    @Override
8988    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8989        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8990                "deleteActivityContainer()");
8991        synchronized (this) {
8992            mStackSupervisor.deleteActivityContainer(container);
8993        }
8994    }
8995
8996    @Override
8997    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8998        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8999                "createStackOnDisplay()");
9000        synchronized (this) {
9001            final int stackId = mStackSupervisor.getNextStackId();
9002            final ActivityStack stack =
9003                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9004            if (stack == null) {
9005                return null;
9006            }
9007            return stack.mActivityContainer;
9008        }
9009    }
9010
9011    @Override
9012    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9013        synchronized (this) {
9014            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9015            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9016                return stack.mActivityContainer.getDisplayId();
9017            }
9018            return Display.DEFAULT_DISPLAY;
9019        }
9020    }
9021
9022    @Override
9023    public int getActivityStackId(IBinder token) throws RemoteException {
9024        synchronized (this) {
9025            ActivityStack stack = ActivityRecord.getStackLocked(token);
9026            if (stack == null) {
9027                return INVALID_STACK_ID;
9028            }
9029            return stack.mStackId;
9030        }
9031    }
9032
9033    @Override
9034    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9035        if (stackId == HOME_STACK_ID) {
9036            throw new IllegalArgumentException(
9037                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9038        }
9039        synchronized (this) {
9040            long ident = Binder.clearCallingIdentity();
9041            try {
9042                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9043                if (r == null) {
9044                    throw new IllegalArgumentException(
9045                            "moveActivityToStack: No activity record matching token=" + token);
9046                }
9047                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9048                        + " to stackId=" + stackId);
9049                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9050                        "moveActivityToStack");
9051            } finally {
9052                Binder.restoreCallingIdentity(ident);
9053            }
9054        }
9055    }
9056
9057    @Override
9058    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9059        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9060                "moveTaskToStack()");
9061        if (stackId == HOME_STACK_ID) {
9062            throw new IllegalArgumentException(
9063                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9064        }
9065        synchronized (this) {
9066            long ident = Binder.clearCallingIdentity();
9067            try {
9068                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9069                        + " to stackId=" + stackId + " toTop=" + toTop);
9070                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9071                        "moveTaskToStack");
9072            } finally {
9073                Binder.restoreCallingIdentity(ident);
9074            }
9075        }
9076    }
9077
9078    /**
9079     * Moves the input task to the docked stack.
9080     *
9081     * @param taskId Id of task to move.
9082     * @param createMode The mode the docked stack should be created in if it doesn't exist
9083     *                   already. See
9084     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9085     *                   and
9086     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9087     * @param toTop If the task and stack should be moved to the top.
9088     */
9089    @Override
9090    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) {
9091        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9092                "moveTaskToDockedStack()");
9093        synchronized (this) {
9094            long ident = Binder.clearCallingIdentity();
9095            try {
9096                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9097                        + " to createMode=" + createMode + " toTop=" + toTop);
9098                mWindowManager.setDockedStackCreateMode(createMode);
9099                mStackSupervisor.moveTaskToStackLocked(
9100                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack");
9101            } finally {
9102                Binder.restoreCallingIdentity(ident);
9103            }
9104        }
9105    }
9106
9107    /**
9108     * Moves the top activity in the input stackId to the pinned stack.
9109     *
9110     * @param stackId Id of stack to move the top activity to pinned stack.
9111     * @param bounds Bounds to use for pinned stack.
9112     *
9113     * @return True if the top activity of the input stack was successfully moved to the pinned
9114     *          stack.
9115     */
9116    @Override
9117    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9118        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9119                "moveTopActivityToPinnedStack()");
9120        synchronized (this) {
9121            long ident = Binder.clearCallingIdentity();
9122            try {
9123                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9124            } finally {
9125                Binder.restoreCallingIdentity(ident);
9126            }
9127        }
9128    }
9129
9130    @Override
9131    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9132        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9133                "resizeStack()");
9134        long ident = Binder.clearCallingIdentity();
9135        try {
9136            synchronized (this) {
9137                mStackSupervisor.resizeStackLocked(
9138                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9139            }
9140        } finally {
9141            Binder.restoreCallingIdentity(ident);
9142        }
9143    }
9144
9145    @Override
9146    public void positionTaskInStack(int taskId, int stackId, int position) {
9147        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9148                "positionTaskInStack()");
9149        if (stackId == HOME_STACK_ID) {
9150            throw new IllegalArgumentException(
9151                    "positionTaskInStack: Attempt to change the position of task "
9152                    + taskId + " in/to home stack");
9153        }
9154        synchronized (this) {
9155            long ident = Binder.clearCallingIdentity();
9156            try {
9157                if (DEBUG_STACK) Slog.d(TAG_STACK,
9158                        "positionTaskInStack: positioning task=" + taskId
9159                        + " in stackId=" + stackId + " at position=" + position);
9160                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9161            } finally {
9162                Binder.restoreCallingIdentity(ident);
9163            }
9164        }
9165    }
9166
9167    @Override
9168    public List<StackInfo> getAllStackInfos() {
9169        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9170                "getAllStackInfos()");
9171        long ident = Binder.clearCallingIdentity();
9172        try {
9173            synchronized (this) {
9174                return mStackSupervisor.getAllStackInfosLocked();
9175            }
9176        } finally {
9177            Binder.restoreCallingIdentity(ident);
9178        }
9179    }
9180
9181    @Override
9182    public StackInfo getStackInfo(int stackId) {
9183        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9184                "getStackInfo()");
9185        long ident = Binder.clearCallingIdentity();
9186        try {
9187            synchronized (this) {
9188                return mStackSupervisor.getStackInfoLocked(stackId);
9189            }
9190        } finally {
9191            Binder.restoreCallingIdentity(ident);
9192        }
9193    }
9194
9195    @Override
9196    public boolean isInHomeStack(int taskId) {
9197        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9198                "getStackInfo()");
9199        long ident = Binder.clearCallingIdentity();
9200        try {
9201            synchronized (this) {
9202                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9203                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9204                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9205            }
9206        } finally {
9207            Binder.restoreCallingIdentity(ident);
9208        }
9209    }
9210
9211    @Override
9212    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9213        synchronized(this) {
9214            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9215        }
9216    }
9217
9218    @Override
9219    public void updateDeviceOwner(String packageName) {
9220        final int callingUid = Binder.getCallingUid();
9221        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9222            throw new SecurityException("updateDeviceOwner called from non-system process");
9223        }
9224        synchronized (this) {
9225            mDeviceOwnerName = packageName;
9226        }
9227    }
9228
9229    @Override
9230    public void updateLockTaskPackages(int userId, String[] packages) {
9231        final int callingUid = Binder.getCallingUid();
9232        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9233            throw new SecurityException("updateLockTaskPackage called from non-system process");
9234        }
9235        synchronized (this) {
9236            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9237                    Arrays.toString(packages));
9238            mLockTaskPackages.put(userId, packages);
9239            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9240        }
9241    }
9242
9243
9244    void startLockTaskModeLocked(TaskRecord task) {
9245        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9246        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9247            return;
9248        }
9249
9250        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9251        // is initiated by system after the pinning request was shown and locked mode is initiated
9252        // by an authorized app directly
9253        final int callingUid = Binder.getCallingUid();
9254        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9255        long ident = Binder.clearCallingIdentity();
9256        try {
9257            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9258            if (!isSystemInitiated) {
9259                task.mLockTaskUid = callingUid;
9260                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9261                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9262                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9263                    StatusBarManagerInternal statusBarManager =
9264                            LocalServices.getService(StatusBarManagerInternal.class);
9265                    if (statusBarManager != null) {
9266                        statusBarManager.showScreenPinningRequest();
9267                    }
9268                    return;
9269                }
9270
9271                if (stack == null || task != stack.topTask()) {
9272                    throw new IllegalArgumentException("Invalid task, not in foreground");
9273                }
9274            }
9275            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9276                    "Locking fully");
9277            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9278                    ActivityManager.LOCK_TASK_MODE_PINNED :
9279                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9280                    "startLockTask", true);
9281        } finally {
9282            Binder.restoreCallingIdentity(ident);
9283        }
9284    }
9285
9286    @Override
9287    public void startLockTaskMode(int taskId) {
9288        synchronized (this) {
9289            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9290            if (task != null) {
9291                startLockTaskModeLocked(task);
9292            }
9293        }
9294    }
9295
9296    @Override
9297    public void startLockTaskMode(IBinder token) {
9298        synchronized (this) {
9299            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9300            if (r == null) {
9301                return;
9302            }
9303            final TaskRecord task = r.task;
9304            if (task != null) {
9305                startLockTaskModeLocked(task);
9306            }
9307        }
9308    }
9309
9310    @Override
9311    public void startLockTaskModeOnCurrent() throws RemoteException {
9312        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9313                "startLockTaskModeOnCurrent");
9314        long ident = Binder.clearCallingIdentity();
9315        try {
9316            synchronized (this) {
9317                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9318                if (r != null) {
9319                    startLockTaskModeLocked(r.task);
9320                }
9321            }
9322        } finally {
9323            Binder.restoreCallingIdentity(ident);
9324        }
9325    }
9326
9327    @Override
9328    public void stopLockTaskMode() {
9329        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9330        if (lockTask == null) {
9331            // Our work here is done.
9332            return;
9333        }
9334
9335        final int callingUid = Binder.getCallingUid();
9336        final int lockTaskUid = lockTask.mLockTaskUid;
9337        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9338        // It is possible lockTaskMode was started by the system process because
9339        // android:lockTaskMode is set to a locking value in the application manifest instead of
9340        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9341        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9342        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9343                callingUid != lockTaskUid
9344                && (lockTaskUid != 0
9345                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9346            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9347                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9348        }
9349
9350        long ident = Binder.clearCallingIdentity();
9351        try {
9352            Log.d(TAG, "stopLockTaskMode");
9353            // Stop lock task
9354            synchronized (this) {
9355                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9356                        "stopLockTask", true);
9357            }
9358        } finally {
9359            Binder.restoreCallingIdentity(ident);
9360        }
9361    }
9362
9363    @Override
9364    public void stopLockTaskModeOnCurrent() throws RemoteException {
9365        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9366                "stopLockTaskModeOnCurrent");
9367        long ident = Binder.clearCallingIdentity();
9368        try {
9369            stopLockTaskMode();
9370        } finally {
9371            Binder.restoreCallingIdentity(ident);
9372        }
9373    }
9374
9375    @Override
9376    public boolean isInLockTaskMode() {
9377        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9378    }
9379
9380    @Override
9381    public int getLockTaskModeState() {
9382        synchronized (this) {
9383            return mStackSupervisor.getLockTaskModeState();
9384        }
9385    }
9386
9387    @Override
9388    public void showLockTaskEscapeMessage(IBinder token) {
9389        synchronized (this) {
9390            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9391            if (r == null) {
9392                return;
9393            }
9394            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9395        }
9396    }
9397
9398    // =========================================================
9399    // CONTENT PROVIDERS
9400    // =========================================================
9401
9402    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9403        List<ProviderInfo> providers = null;
9404        try {
9405            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9406                queryContentProviders(app.processName, app.uid,
9407                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9408            providers = slice != null ? slice.getList() : null;
9409        } catch (RemoteException ex) {
9410        }
9411        if (DEBUG_MU) Slog.v(TAG_MU,
9412                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9413        int userId = app.userId;
9414        if (providers != null) {
9415            int N = providers.size();
9416            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9417            for (int i=0; i<N; i++) {
9418                ProviderInfo cpi =
9419                    (ProviderInfo)providers.get(i);
9420                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9421                        cpi.name, cpi.flags);
9422                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9423                    // This is a singleton provider, but a user besides the
9424                    // default user is asking to initialize a process it runs
9425                    // in...  well, no, it doesn't actually run in this process,
9426                    // it runs in the process of the default user.  Get rid of it.
9427                    providers.remove(i);
9428                    N--;
9429                    i--;
9430                    continue;
9431                }
9432
9433                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9434                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9435                if (cpr == null) {
9436                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9437                    mProviderMap.putProviderByClass(comp, cpr);
9438                }
9439                if (DEBUG_MU) Slog.v(TAG_MU,
9440                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9441                app.pubProviders.put(cpi.name, cpr);
9442                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9443                    // Don't add this if it is a platform component that is marked
9444                    // to run in multiple processes, because this is actually
9445                    // part of the framework so doesn't make sense to track as a
9446                    // separate apk in the process.
9447                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9448                            mProcessStats);
9449                }
9450                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9451            }
9452        }
9453        return providers;
9454    }
9455
9456    /**
9457     * Check if {@link ProcessRecord} has a possible chance at accessing the
9458     * given {@link ProviderInfo}. Final permission checking is always done
9459     * in {@link ContentProvider}.
9460     */
9461    private final String checkContentProviderPermissionLocked(
9462            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9463        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9464        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9465        boolean checkedGrants = false;
9466        if (checkUser) {
9467            // Looking for cross-user grants before enforcing the typical cross-users permissions
9468            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9469            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9470                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9471                    return null;
9472                }
9473                checkedGrants = true;
9474            }
9475            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9476                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9477            if (userId != tmpTargetUserId) {
9478                // When we actually went to determine the final targer user ID, this ended
9479                // up different than our initial check for the authority.  This is because
9480                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9481                // SELF.  So we need to re-check the grants again.
9482                checkedGrants = false;
9483            }
9484        }
9485        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9486                cpi.applicationInfo.uid, cpi.exported)
9487                == PackageManager.PERMISSION_GRANTED) {
9488            return null;
9489        }
9490        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9491                cpi.applicationInfo.uid, cpi.exported)
9492                == PackageManager.PERMISSION_GRANTED) {
9493            return null;
9494        }
9495
9496        PathPermission[] pps = cpi.pathPermissions;
9497        if (pps != null) {
9498            int i = pps.length;
9499            while (i > 0) {
9500                i--;
9501                PathPermission pp = pps[i];
9502                String pprperm = pp.getReadPermission();
9503                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9504                        cpi.applicationInfo.uid, cpi.exported)
9505                        == PackageManager.PERMISSION_GRANTED) {
9506                    return null;
9507                }
9508                String ppwperm = pp.getWritePermission();
9509                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9510                        cpi.applicationInfo.uid, cpi.exported)
9511                        == PackageManager.PERMISSION_GRANTED) {
9512                    return null;
9513                }
9514            }
9515        }
9516        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9517            return null;
9518        }
9519
9520        String msg;
9521        if (!cpi.exported) {
9522            msg = "Permission Denial: opening provider " + cpi.name
9523                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9524                    + ", uid=" + callingUid + ") that is not exported from uid "
9525                    + cpi.applicationInfo.uid;
9526        } else {
9527            msg = "Permission Denial: opening provider " + cpi.name
9528                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9529                    + ", uid=" + callingUid + ") requires "
9530                    + cpi.readPermission + " or " + cpi.writePermission;
9531        }
9532        Slog.w(TAG, msg);
9533        return msg;
9534    }
9535
9536    /**
9537     * Returns if the ContentProvider has granted a uri to callingUid
9538     */
9539    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9540        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9541        if (perms != null) {
9542            for (int i=perms.size()-1; i>=0; i--) {
9543                GrantUri grantUri = perms.keyAt(i);
9544                if (grantUri.sourceUserId == userId || !checkUser) {
9545                    if (matchesProvider(grantUri.uri, cpi)) {
9546                        return true;
9547                    }
9548                }
9549            }
9550        }
9551        return false;
9552    }
9553
9554    /**
9555     * Returns true if the uri authority is one of the authorities specified in the provider.
9556     */
9557    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9558        String uriAuth = uri.getAuthority();
9559        String cpiAuth = cpi.authority;
9560        if (cpiAuth.indexOf(';') == -1) {
9561            return cpiAuth.equals(uriAuth);
9562        }
9563        String[] cpiAuths = cpiAuth.split(";");
9564        int length = cpiAuths.length;
9565        for (int i = 0; i < length; i++) {
9566            if (cpiAuths[i].equals(uriAuth)) return true;
9567        }
9568        return false;
9569    }
9570
9571    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9572            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9573        if (r != null) {
9574            for (int i=0; i<r.conProviders.size(); i++) {
9575                ContentProviderConnection conn = r.conProviders.get(i);
9576                if (conn.provider == cpr) {
9577                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9578                            "Adding provider requested by "
9579                            + r.processName + " from process "
9580                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9581                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9582                    if (stable) {
9583                        conn.stableCount++;
9584                        conn.numStableIncs++;
9585                    } else {
9586                        conn.unstableCount++;
9587                        conn.numUnstableIncs++;
9588                    }
9589                    return conn;
9590                }
9591            }
9592            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9593            if (stable) {
9594                conn.stableCount = 1;
9595                conn.numStableIncs = 1;
9596            } else {
9597                conn.unstableCount = 1;
9598                conn.numUnstableIncs = 1;
9599            }
9600            cpr.connections.add(conn);
9601            r.conProviders.add(conn);
9602            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9603            return conn;
9604        }
9605        cpr.addExternalProcessHandleLocked(externalProcessToken);
9606        return null;
9607    }
9608
9609    boolean decProviderCountLocked(ContentProviderConnection conn,
9610            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9611        if (conn != null) {
9612            cpr = conn.provider;
9613            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9614                    "Removing provider requested by "
9615                    + conn.client.processName + " from process "
9616                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9617                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9618            if (stable) {
9619                conn.stableCount--;
9620            } else {
9621                conn.unstableCount--;
9622            }
9623            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9624                cpr.connections.remove(conn);
9625                conn.client.conProviders.remove(conn);
9626                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9627                return true;
9628            }
9629            return false;
9630        }
9631        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9632        return false;
9633    }
9634
9635    private void checkTime(long startTime, String where) {
9636        long now = SystemClock.elapsedRealtime();
9637        if ((now-startTime) > 1000) {
9638            // If we are taking more than a second, log about it.
9639            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9640        }
9641    }
9642
9643    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9644            String name, IBinder token, boolean stable, int userId) {
9645        ContentProviderRecord cpr;
9646        ContentProviderConnection conn = null;
9647        ProviderInfo cpi = null;
9648
9649        synchronized(this) {
9650            long startTime = SystemClock.elapsedRealtime();
9651
9652            ProcessRecord r = null;
9653            if (caller != null) {
9654                r = getRecordForAppLocked(caller);
9655                if (r == null) {
9656                    throw new SecurityException(
9657                            "Unable to find app for caller " + caller
9658                          + " (pid=" + Binder.getCallingPid()
9659                          + ") when getting content provider " + name);
9660                }
9661            }
9662
9663            boolean checkCrossUser = true;
9664
9665            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9666
9667            // First check if this content provider has been published...
9668            cpr = mProviderMap.getProviderByName(name, userId);
9669            // If that didn't work, check if it exists for user 0 and then
9670            // verify that it's a singleton provider before using it.
9671            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9672                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9673                if (cpr != null) {
9674                    cpi = cpr.info;
9675                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9676                            cpi.name, cpi.flags)
9677                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9678                        userId = UserHandle.USER_SYSTEM;
9679                        checkCrossUser = false;
9680                    } else {
9681                        cpr = null;
9682                        cpi = null;
9683                    }
9684                }
9685            }
9686
9687            boolean providerRunning = cpr != null;
9688            if (providerRunning) {
9689                cpi = cpr.info;
9690                String msg;
9691                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9692                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9693                        != null) {
9694                    throw new SecurityException(msg);
9695                }
9696                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9697
9698                if (r != null && cpr.canRunHere(r)) {
9699                    // This provider has been published or is in the process
9700                    // of being published...  but it is also allowed to run
9701                    // in the caller's process, so don't make a connection
9702                    // and just let the caller instantiate its own instance.
9703                    ContentProviderHolder holder = cpr.newHolder(null);
9704                    // don't give caller the provider object, it needs
9705                    // to make its own.
9706                    holder.provider = null;
9707                    return holder;
9708                }
9709
9710                final long origId = Binder.clearCallingIdentity();
9711
9712                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9713
9714                // In this case the provider instance already exists, so we can
9715                // return it right away.
9716                conn = incProviderCountLocked(r, cpr, token, stable);
9717                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9718                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9719                        // If this is a perceptible app accessing the provider,
9720                        // make sure to count it as being accessed and thus
9721                        // back up on the LRU list.  This is good because
9722                        // content providers are often expensive to start.
9723                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9724                        updateLruProcessLocked(cpr.proc, false, null);
9725                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9726                    }
9727                }
9728
9729                if (cpr.proc != null) {
9730                    if (false) {
9731                        if (cpr.name.flattenToShortString().equals(
9732                                "com.android.providers.calendar/.CalendarProvider2")) {
9733                            Slog.v(TAG, "****************** KILLING "
9734                                + cpr.name.flattenToShortString());
9735                            Process.killProcess(cpr.proc.pid);
9736                        }
9737                    }
9738                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9739                    boolean success = updateOomAdjLocked(cpr.proc);
9740                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9741                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9742                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9743                    // NOTE: there is still a race here where a signal could be
9744                    // pending on the process even though we managed to update its
9745                    // adj level.  Not sure what to do about this, but at least
9746                    // the race is now smaller.
9747                    if (!success) {
9748                        // Uh oh...  it looks like the provider's process
9749                        // has been killed on us.  We need to wait for a new
9750                        // process to be started, and make sure its death
9751                        // doesn't kill our process.
9752                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9753                                + " is crashing; detaching " + r);
9754                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9755                        checkTime(startTime, "getContentProviderImpl: before appDied");
9756                        appDiedLocked(cpr.proc);
9757                        checkTime(startTime, "getContentProviderImpl: after appDied");
9758                        if (!lastRef) {
9759                            // This wasn't the last ref our process had on
9760                            // the provider...  we have now been killed, bail.
9761                            return null;
9762                        }
9763                        providerRunning = false;
9764                        conn = null;
9765                    }
9766                }
9767
9768                Binder.restoreCallingIdentity(origId);
9769            }
9770
9771            if (!providerRunning) {
9772                try {
9773                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9774                    cpi = AppGlobals.getPackageManager().
9775                        resolveContentProvider(name,
9776                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9777                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9778                } catch (RemoteException ex) {
9779                }
9780                if (cpi == null) {
9781                    return null;
9782                }
9783                // If the provider is a singleton AND
9784                // (it's a call within the same user || the provider is a
9785                // privileged app)
9786                // Then allow connecting to the singleton provider
9787                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9788                        cpi.name, cpi.flags)
9789                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9790                if (singleton) {
9791                    userId = UserHandle.USER_SYSTEM;
9792                }
9793                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9794                checkTime(startTime, "getContentProviderImpl: got app info for user");
9795
9796                String msg;
9797                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9798                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9799                        != null) {
9800                    throw new SecurityException(msg);
9801                }
9802                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9803
9804                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9805                        && !cpi.processName.equals("system")) {
9806                    // If this content provider does not run in the system
9807                    // process, and the system is not yet ready to run other
9808                    // processes, then fail fast instead of hanging.
9809                    throw new IllegalArgumentException(
9810                            "Attempt to launch content provider before system ready");
9811                }
9812
9813                // Make sure that the user who owns this provider is running.  If not,
9814                // we don't want to allow it to run.
9815                if (!mUserController.isUserRunningLocked(userId, false)) {
9816                    Slog.w(TAG, "Unable to launch app "
9817                            + cpi.applicationInfo.packageName + "/"
9818                            + cpi.applicationInfo.uid + " for provider "
9819                            + name + ": user " + userId + " is stopped");
9820                    return null;
9821                }
9822
9823                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9824                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9825                cpr = mProviderMap.getProviderByClass(comp, userId);
9826                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9827                final boolean firstClass = cpr == null;
9828                if (firstClass) {
9829                    final long ident = Binder.clearCallingIdentity();
9830                    try {
9831                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9832                        ApplicationInfo ai =
9833                            AppGlobals.getPackageManager().
9834                                getApplicationInfo(
9835                                        cpi.applicationInfo.packageName,
9836                                        STOCK_PM_FLAGS, userId);
9837                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9838                        if (ai == null) {
9839                            Slog.w(TAG, "No package info for content provider "
9840                                    + cpi.name);
9841                            return null;
9842                        }
9843                        ai = getAppInfoForUser(ai, userId);
9844                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9845                    } catch (RemoteException ex) {
9846                        // pm is in same process, this will never happen.
9847                    } finally {
9848                        Binder.restoreCallingIdentity(ident);
9849                    }
9850                }
9851
9852                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9853
9854                if (r != null && cpr.canRunHere(r)) {
9855                    // If this is a multiprocess provider, then just return its
9856                    // info and allow the caller to instantiate it.  Only do
9857                    // this if the provider is the same user as the caller's
9858                    // process, or can run as root (so can be in any process).
9859                    return cpr.newHolder(null);
9860                }
9861
9862                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9863                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9864                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9865
9866                // This is single process, and our app is now connecting to it.
9867                // See if we are already in the process of launching this
9868                // provider.
9869                final int N = mLaunchingProviders.size();
9870                int i;
9871                for (i = 0; i < N; i++) {
9872                    if (mLaunchingProviders.get(i) == cpr) {
9873                        break;
9874                    }
9875                }
9876
9877                // If the provider is not already being launched, then get it
9878                // started.
9879                if (i >= N) {
9880                    final long origId = Binder.clearCallingIdentity();
9881
9882                    try {
9883                        // Content provider is now in use, its package can't be stopped.
9884                        try {
9885                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9886                            AppGlobals.getPackageManager().setPackageStoppedState(
9887                                    cpr.appInfo.packageName, false, userId);
9888                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9889                        } catch (RemoteException e) {
9890                        } catch (IllegalArgumentException e) {
9891                            Slog.w(TAG, "Failed trying to unstop package "
9892                                    + cpr.appInfo.packageName + ": " + e);
9893                        }
9894
9895                        // Use existing process if already started
9896                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9897                        ProcessRecord proc = getProcessRecordLocked(
9898                                cpi.processName, cpr.appInfo.uid, false);
9899                        if (proc != null && proc.thread != null) {
9900                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9901                                    "Installing in existing process " + proc);
9902                            if (!proc.pubProviders.containsKey(cpi.name)) {
9903                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9904                                proc.pubProviders.put(cpi.name, cpr);
9905                                try {
9906                                    proc.thread.scheduleInstallProvider(cpi);
9907                                } catch (RemoteException e) {
9908                                }
9909                            }
9910                        } else {
9911                            checkTime(startTime, "getContentProviderImpl: before start process");
9912                            proc = startProcessLocked(cpi.processName,
9913                                    cpr.appInfo, false, 0, "content provider",
9914                                    new ComponentName(cpi.applicationInfo.packageName,
9915                                            cpi.name), false, false, false);
9916                            checkTime(startTime, "getContentProviderImpl: after start process");
9917                            if (proc == null) {
9918                                Slog.w(TAG, "Unable to launch app "
9919                                        + cpi.applicationInfo.packageName + "/"
9920                                        + cpi.applicationInfo.uid + " for provider "
9921                                        + name + ": process is bad");
9922                                return null;
9923                            }
9924                        }
9925                        cpr.launchingApp = proc;
9926                        mLaunchingProviders.add(cpr);
9927                    } finally {
9928                        Binder.restoreCallingIdentity(origId);
9929                    }
9930                }
9931
9932                checkTime(startTime, "getContentProviderImpl: updating data structures");
9933
9934                // Make sure the provider is published (the same provider class
9935                // may be published under multiple names).
9936                if (firstClass) {
9937                    mProviderMap.putProviderByClass(comp, cpr);
9938                }
9939
9940                mProviderMap.putProviderByName(name, cpr);
9941                conn = incProviderCountLocked(r, cpr, token, stable);
9942                if (conn != null) {
9943                    conn.waiting = true;
9944                }
9945            }
9946            checkTime(startTime, "getContentProviderImpl: done!");
9947        }
9948
9949        // Wait for the provider to be published...
9950        synchronized (cpr) {
9951            while (cpr.provider == null) {
9952                if (cpr.launchingApp == null) {
9953                    Slog.w(TAG, "Unable to launch app "
9954                            + cpi.applicationInfo.packageName + "/"
9955                            + cpi.applicationInfo.uid + " for provider "
9956                            + name + ": launching app became null");
9957                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9958                            UserHandle.getUserId(cpi.applicationInfo.uid),
9959                            cpi.applicationInfo.packageName,
9960                            cpi.applicationInfo.uid, name);
9961                    return null;
9962                }
9963                try {
9964                    if (DEBUG_MU) Slog.v(TAG_MU,
9965                            "Waiting to start provider " + cpr
9966                            + " launchingApp=" + cpr.launchingApp);
9967                    if (conn != null) {
9968                        conn.waiting = true;
9969                    }
9970                    cpr.wait();
9971                } catch (InterruptedException ex) {
9972                } finally {
9973                    if (conn != null) {
9974                        conn.waiting = false;
9975                    }
9976                }
9977            }
9978        }
9979        return cpr != null ? cpr.newHolder(conn) : null;
9980    }
9981
9982    @Override
9983    public final ContentProviderHolder getContentProvider(
9984            IApplicationThread caller, String name, int userId, boolean stable) {
9985        enforceNotIsolatedCaller("getContentProvider");
9986        if (caller == null) {
9987            String msg = "null IApplicationThread when getting content provider "
9988                    + name;
9989            Slog.w(TAG, msg);
9990            throw new SecurityException(msg);
9991        }
9992        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9993        // with cross-user grant.
9994        return getContentProviderImpl(caller, name, null, stable, userId);
9995    }
9996
9997    public ContentProviderHolder getContentProviderExternal(
9998            String name, int userId, IBinder token) {
9999        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10000            "Do not have permission in call getContentProviderExternal()");
10001        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10002                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10003        return getContentProviderExternalUnchecked(name, token, userId);
10004    }
10005
10006    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10007            IBinder token, int userId) {
10008        return getContentProviderImpl(null, name, token, true, userId);
10009    }
10010
10011    /**
10012     * Drop a content provider from a ProcessRecord's bookkeeping
10013     */
10014    public void removeContentProvider(IBinder connection, boolean stable) {
10015        enforceNotIsolatedCaller("removeContentProvider");
10016        long ident = Binder.clearCallingIdentity();
10017        try {
10018            synchronized (this) {
10019                ContentProviderConnection conn;
10020                try {
10021                    conn = (ContentProviderConnection)connection;
10022                } catch (ClassCastException e) {
10023                    String msg ="removeContentProvider: " + connection
10024                            + " not a ContentProviderConnection";
10025                    Slog.w(TAG, msg);
10026                    throw new IllegalArgumentException(msg);
10027                }
10028                if (conn == null) {
10029                    throw new NullPointerException("connection is null");
10030                }
10031                if (decProviderCountLocked(conn, null, null, stable)) {
10032                    updateOomAdjLocked();
10033                }
10034            }
10035        } finally {
10036            Binder.restoreCallingIdentity(ident);
10037        }
10038    }
10039
10040    public void removeContentProviderExternal(String name, IBinder token) {
10041        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10042            "Do not have permission in call removeContentProviderExternal()");
10043        int userId = UserHandle.getCallingUserId();
10044        long ident = Binder.clearCallingIdentity();
10045        try {
10046            removeContentProviderExternalUnchecked(name, token, userId);
10047        } finally {
10048            Binder.restoreCallingIdentity(ident);
10049        }
10050    }
10051
10052    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10053        synchronized (this) {
10054            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10055            if(cpr == null) {
10056                //remove from mProvidersByClass
10057                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10058                return;
10059            }
10060
10061            //update content provider record entry info
10062            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10063            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10064            if (localCpr.hasExternalProcessHandles()) {
10065                if (localCpr.removeExternalProcessHandleLocked(token)) {
10066                    updateOomAdjLocked();
10067                } else {
10068                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10069                            + " with no external reference for token: "
10070                            + token + ".");
10071                }
10072            } else {
10073                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10074                        + " with no external references.");
10075            }
10076        }
10077    }
10078
10079    public final void publishContentProviders(IApplicationThread caller,
10080            List<ContentProviderHolder> providers) {
10081        if (providers == null) {
10082            return;
10083        }
10084
10085        enforceNotIsolatedCaller("publishContentProviders");
10086        synchronized (this) {
10087            final ProcessRecord r = getRecordForAppLocked(caller);
10088            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10089            if (r == null) {
10090                throw new SecurityException(
10091                        "Unable to find app for caller " + caller
10092                      + " (pid=" + Binder.getCallingPid()
10093                      + ") when publishing content providers");
10094            }
10095
10096            final long origId = Binder.clearCallingIdentity();
10097
10098            final int N = providers.size();
10099            for (int i = 0; i < N; i++) {
10100                ContentProviderHolder src = providers.get(i);
10101                if (src == null || src.info == null || src.provider == null) {
10102                    continue;
10103                }
10104                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10105                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10106                if (dst != null) {
10107                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10108                    mProviderMap.putProviderByClass(comp, dst);
10109                    String names[] = dst.info.authority.split(";");
10110                    for (int j = 0; j < names.length; j++) {
10111                        mProviderMap.putProviderByName(names[j], dst);
10112                    }
10113
10114                    int launchingCount = mLaunchingProviders.size();
10115                    int j;
10116                    boolean wasInLaunchingProviders = false;
10117                    for (j = 0; j < launchingCount; j++) {
10118                        if (mLaunchingProviders.get(j) == dst) {
10119                            mLaunchingProviders.remove(j);
10120                            wasInLaunchingProviders = true;
10121                            j--;
10122                            launchingCount--;
10123                        }
10124                    }
10125                    if (wasInLaunchingProviders) {
10126                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10127                    }
10128                    synchronized (dst) {
10129                        dst.provider = src.provider;
10130                        dst.proc = r;
10131                        dst.notifyAll();
10132                    }
10133                    updateOomAdjLocked(r);
10134                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10135                            src.info.authority);
10136                }
10137            }
10138
10139            Binder.restoreCallingIdentity(origId);
10140        }
10141    }
10142
10143    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10144        ContentProviderConnection conn;
10145        try {
10146            conn = (ContentProviderConnection)connection;
10147        } catch (ClassCastException e) {
10148            String msg ="refContentProvider: " + connection
10149                    + " not a ContentProviderConnection";
10150            Slog.w(TAG, msg);
10151            throw new IllegalArgumentException(msg);
10152        }
10153        if (conn == null) {
10154            throw new NullPointerException("connection is null");
10155        }
10156
10157        synchronized (this) {
10158            if (stable > 0) {
10159                conn.numStableIncs += stable;
10160            }
10161            stable = conn.stableCount + stable;
10162            if (stable < 0) {
10163                throw new IllegalStateException("stableCount < 0: " + stable);
10164            }
10165
10166            if (unstable > 0) {
10167                conn.numUnstableIncs += unstable;
10168            }
10169            unstable = conn.unstableCount + unstable;
10170            if (unstable < 0) {
10171                throw new IllegalStateException("unstableCount < 0: " + unstable);
10172            }
10173
10174            if ((stable+unstable) <= 0) {
10175                throw new IllegalStateException("ref counts can't go to zero here: stable="
10176                        + stable + " unstable=" + unstable);
10177            }
10178            conn.stableCount = stable;
10179            conn.unstableCount = unstable;
10180            return !conn.dead;
10181        }
10182    }
10183
10184    public void unstableProviderDied(IBinder connection) {
10185        ContentProviderConnection conn;
10186        try {
10187            conn = (ContentProviderConnection)connection;
10188        } catch (ClassCastException e) {
10189            String msg ="refContentProvider: " + connection
10190                    + " not a ContentProviderConnection";
10191            Slog.w(TAG, msg);
10192            throw new IllegalArgumentException(msg);
10193        }
10194        if (conn == null) {
10195            throw new NullPointerException("connection is null");
10196        }
10197
10198        // Safely retrieve the content provider associated with the connection.
10199        IContentProvider provider;
10200        synchronized (this) {
10201            provider = conn.provider.provider;
10202        }
10203
10204        if (provider == null) {
10205            // Um, yeah, we're way ahead of you.
10206            return;
10207        }
10208
10209        // Make sure the caller is being honest with us.
10210        if (provider.asBinder().pingBinder()) {
10211            // Er, no, still looks good to us.
10212            synchronized (this) {
10213                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10214                        + " says " + conn + " died, but we don't agree");
10215                return;
10216            }
10217        }
10218
10219        // Well look at that!  It's dead!
10220        synchronized (this) {
10221            if (conn.provider.provider != provider) {
10222                // But something changed...  good enough.
10223                return;
10224            }
10225
10226            ProcessRecord proc = conn.provider.proc;
10227            if (proc == null || proc.thread == null) {
10228                // Seems like the process is already cleaned up.
10229                return;
10230            }
10231
10232            // As far as we're concerned, this is just like receiving a
10233            // death notification...  just a bit prematurely.
10234            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10235                    + ") early provider death");
10236            final long ident = Binder.clearCallingIdentity();
10237            try {
10238                appDiedLocked(proc);
10239            } finally {
10240                Binder.restoreCallingIdentity(ident);
10241            }
10242        }
10243    }
10244
10245    @Override
10246    public void appNotRespondingViaProvider(IBinder connection) {
10247        enforceCallingPermission(
10248                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10249
10250        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10251        if (conn == null) {
10252            Slog.w(TAG, "ContentProviderConnection is null");
10253            return;
10254        }
10255
10256        final ProcessRecord host = conn.provider.proc;
10257        if (host == null) {
10258            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10259            return;
10260        }
10261
10262        final long token = Binder.clearCallingIdentity();
10263        try {
10264            appNotResponding(host, null, null, false, "ContentProvider not responding");
10265        } finally {
10266            Binder.restoreCallingIdentity(token);
10267        }
10268    }
10269
10270    public final void installSystemProviders() {
10271        List<ProviderInfo> providers;
10272        synchronized (this) {
10273            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10274            providers = generateApplicationProvidersLocked(app);
10275            if (providers != null) {
10276                for (int i=providers.size()-1; i>=0; i--) {
10277                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10278                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10279                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10280                                + ": not system .apk");
10281                        providers.remove(i);
10282                    }
10283                }
10284            }
10285        }
10286        if (providers != null) {
10287            mSystemThread.installSystemProviders(providers);
10288        }
10289
10290        mCoreSettingsObserver = new CoreSettingsObserver(this);
10291
10292        //mUsageStatsService.monitorPackages();
10293    }
10294
10295    /**
10296     * Allows apps to retrieve the MIME type of a URI.
10297     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10298     * users, then it does not need permission to access the ContentProvider.
10299     * Either, it needs cross-user uri grants.
10300     *
10301     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10302     *
10303     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10304     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10305     */
10306    public String getProviderMimeType(Uri uri, int userId) {
10307        enforceNotIsolatedCaller("getProviderMimeType");
10308        final String name = uri.getAuthority();
10309        int callingUid = Binder.getCallingUid();
10310        int callingPid = Binder.getCallingPid();
10311        long ident = 0;
10312        boolean clearedIdentity = false;
10313        synchronized (this) {
10314            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10315        }
10316        if (canClearIdentity(callingPid, callingUid, userId)) {
10317            clearedIdentity = true;
10318            ident = Binder.clearCallingIdentity();
10319        }
10320        ContentProviderHolder holder = null;
10321        try {
10322            holder = getContentProviderExternalUnchecked(name, null, userId);
10323            if (holder != null) {
10324                return holder.provider.getType(uri);
10325            }
10326        } catch (RemoteException e) {
10327            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10328            return null;
10329        } finally {
10330            // We need to clear the identity to call removeContentProviderExternalUnchecked
10331            if (!clearedIdentity) {
10332                ident = Binder.clearCallingIdentity();
10333            }
10334            try {
10335                if (holder != null) {
10336                    removeContentProviderExternalUnchecked(name, null, userId);
10337                }
10338            } finally {
10339                Binder.restoreCallingIdentity(ident);
10340            }
10341        }
10342
10343        return null;
10344    }
10345
10346    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10347        if (UserHandle.getUserId(callingUid) == userId) {
10348            return true;
10349        }
10350        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10351                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10352                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10353                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10354                return true;
10355        }
10356        return false;
10357    }
10358
10359    // =========================================================
10360    // GLOBAL MANAGEMENT
10361    // =========================================================
10362
10363    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10364            boolean isolated, int isolatedUid) {
10365        String proc = customProcess != null ? customProcess : info.processName;
10366        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10367        final int userId = UserHandle.getUserId(info.uid);
10368        int uid = info.uid;
10369        if (isolated) {
10370            if (isolatedUid == 0) {
10371                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10372                while (true) {
10373                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10374                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10375                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10376                    }
10377                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10378                    mNextIsolatedProcessUid++;
10379                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10380                        // No process for this uid, use it.
10381                        break;
10382                    }
10383                    stepsLeft--;
10384                    if (stepsLeft <= 0) {
10385                        return null;
10386                    }
10387                }
10388            } else {
10389                // Special case for startIsolatedProcess (internal only), where
10390                // the uid of the isolated process is specified by the caller.
10391                uid = isolatedUid;
10392            }
10393        }
10394        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10395        if (!mBooted && !mBooting
10396                && userId == UserHandle.USER_SYSTEM
10397                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10398            r.persistent = true;
10399        }
10400        addProcessNameLocked(r);
10401        return r;
10402    }
10403
10404    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10405            String abiOverride) {
10406        ProcessRecord app;
10407        if (!isolated) {
10408            app = getProcessRecordLocked(info.processName, info.uid, true);
10409        } else {
10410            app = null;
10411        }
10412
10413        if (app == null) {
10414            app = newProcessRecordLocked(info, null, isolated, 0);
10415            updateLruProcessLocked(app, false, null);
10416            updateOomAdjLocked();
10417        }
10418
10419        // This package really, really can not be stopped.
10420        try {
10421            AppGlobals.getPackageManager().setPackageStoppedState(
10422                    info.packageName, false, UserHandle.getUserId(app.uid));
10423        } catch (RemoteException e) {
10424        } catch (IllegalArgumentException e) {
10425            Slog.w(TAG, "Failed trying to unstop package "
10426                    + info.packageName + ": " + e);
10427        }
10428
10429        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10430            app.persistent = true;
10431            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10432        }
10433        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10434            mPersistentStartingProcesses.add(app);
10435            startProcessLocked(app, "added application", app.processName, abiOverride,
10436                    null /* entryPoint */, null /* entryPointArgs */);
10437        }
10438
10439        return app;
10440    }
10441
10442    public void unhandledBack() {
10443        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10444                "unhandledBack()");
10445
10446        synchronized(this) {
10447            final long origId = Binder.clearCallingIdentity();
10448            try {
10449                getFocusedStack().unhandledBackLocked();
10450            } finally {
10451                Binder.restoreCallingIdentity(origId);
10452            }
10453        }
10454    }
10455
10456    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10457        enforceNotIsolatedCaller("openContentUri");
10458        final int userId = UserHandle.getCallingUserId();
10459        String name = uri.getAuthority();
10460        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10461        ParcelFileDescriptor pfd = null;
10462        if (cph != null) {
10463            // We record the binder invoker's uid in thread-local storage before
10464            // going to the content provider to open the file.  Later, in the code
10465            // that handles all permissions checks, we look for this uid and use
10466            // that rather than the Activity Manager's own uid.  The effect is that
10467            // we do the check against the caller's permissions even though it looks
10468            // to the content provider like the Activity Manager itself is making
10469            // the request.
10470            Binder token = new Binder();
10471            sCallerIdentity.set(new Identity(
10472                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10473            try {
10474                pfd = cph.provider.openFile(null, uri, "r", null, token);
10475            } catch (FileNotFoundException e) {
10476                // do nothing; pfd will be returned null
10477            } finally {
10478                // Ensure that whatever happens, we clean up the identity state
10479                sCallerIdentity.remove();
10480                // Ensure we're done with the provider.
10481                removeContentProviderExternalUnchecked(name, null, userId);
10482            }
10483        } else {
10484            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10485        }
10486        return pfd;
10487    }
10488
10489    // Actually is sleeping or shutting down or whatever else in the future
10490    // is an inactive state.
10491    public boolean isSleepingOrShuttingDown() {
10492        return isSleeping() || mShuttingDown;
10493    }
10494
10495    public boolean isSleeping() {
10496        return mSleeping;
10497    }
10498
10499    void onWakefulnessChanged(int wakefulness) {
10500        synchronized(this) {
10501            mWakefulness = wakefulness;
10502            updateSleepIfNeededLocked();
10503        }
10504    }
10505
10506    void finishRunningVoiceLocked() {
10507        if (mRunningVoice != null) {
10508            mRunningVoice = null;
10509            mVoiceWakeLock.release();
10510            updateSleepIfNeededLocked();
10511        }
10512    }
10513
10514    void startTimeTrackingFocusedActivityLocked() {
10515        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10516            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10517        }
10518    }
10519
10520    void updateSleepIfNeededLocked() {
10521        if (mSleeping && !shouldSleepLocked()) {
10522            mSleeping = false;
10523            startTimeTrackingFocusedActivityLocked();
10524            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10525            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10526            updateOomAdjLocked();
10527        } else if (!mSleeping && shouldSleepLocked()) {
10528            mSleeping = true;
10529            if (mCurAppTimeTracker != null) {
10530                mCurAppTimeTracker.stop();
10531            }
10532            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10533            mStackSupervisor.goingToSleepLocked();
10534            updateOomAdjLocked();
10535
10536            // Initialize the wake times of all processes.
10537            checkExcessivePowerUsageLocked(false);
10538            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10539            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10540            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10541        }
10542    }
10543
10544    private boolean shouldSleepLocked() {
10545        // Resume applications while running a voice interactor.
10546        if (mRunningVoice != null) {
10547            return false;
10548        }
10549
10550        // TODO: Transform the lock screen state into a sleep token instead.
10551        switch (mWakefulness) {
10552            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10553            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10554            case PowerManagerInternal.WAKEFULNESS_DOZING:
10555                // Pause applications whenever the lock screen is shown or any sleep
10556                // tokens have been acquired.
10557                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10558            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10559            default:
10560                // If we're asleep then pause applications unconditionally.
10561                return true;
10562        }
10563    }
10564
10565    /** Pokes the task persister. */
10566    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10567        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10568            // Never persist the home stack.
10569            return;
10570        }
10571        mTaskPersister.wakeup(task, flush);
10572    }
10573
10574    /** Notifies all listeners when the task stack has changed. */
10575    void notifyTaskStackChangedLocked() {
10576        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10577        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10578        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10579    }
10580
10581    @Override
10582    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10583        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10584    }
10585
10586    @Override
10587    public boolean shutdown(int timeout) {
10588        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10589                != PackageManager.PERMISSION_GRANTED) {
10590            throw new SecurityException("Requires permission "
10591                    + android.Manifest.permission.SHUTDOWN);
10592        }
10593
10594        boolean timedout = false;
10595
10596        synchronized(this) {
10597            mShuttingDown = true;
10598            updateEventDispatchingLocked();
10599            timedout = mStackSupervisor.shutdownLocked(timeout);
10600        }
10601
10602        mAppOpsService.shutdown();
10603        if (mUsageStatsService != null) {
10604            mUsageStatsService.prepareShutdown();
10605        }
10606        mBatteryStatsService.shutdown();
10607        synchronized (this) {
10608            mProcessStats.shutdownLocked();
10609            notifyTaskPersisterLocked(null, true);
10610        }
10611
10612        return timedout;
10613    }
10614
10615    public final void activitySlept(IBinder token) {
10616        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10617
10618        final long origId = Binder.clearCallingIdentity();
10619
10620        synchronized (this) {
10621            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10622            if (r != null) {
10623                mStackSupervisor.activitySleptLocked(r);
10624            }
10625        }
10626
10627        Binder.restoreCallingIdentity(origId);
10628    }
10629
10630    private String lockScreenShownToString() {
10631        switch (mLockScreenShown) {
10632            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10633            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10634            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10635            default: return "Unknown=" + mLockScreenShown;
10636        }
10637    }
10638
10639    void logLockScreen(String msg) {
10640        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10641                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10642                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10643                + " mSleeping=" + mSleeping);
10644    }
10645
10646    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10647        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10648        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10649            boolean wasRunningVoice = mRunningVoice != null;
10650            mRunningVoice = session;
10651            if (!wasRunningVoice) {
10652                mVoiceWakeLock.acquire();
10653                updateSleepIfNeededLocked();
10654            }
10655        }
10656    }
10657
10658    private void updateEventDispatchingLocked() {
10659        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10660    }
10661
10662    public void setLockScreenShown(boolean shown) {
10663        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10664                != PackageManager.PERMISSION_GRANTED) {
10665            throw new SecurityException("Requires permission "
10666                    + android.Manifest.permission.DEVICE_POWER);
10667        }
10668
10669        synchronized(this) {
10670            long ident = Binder.clearCallingIdentity();
10671            try {
10672                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10673                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10674                updateSleepIfNeededLocked();
10675            } finally {
10676                Binder.restoreCallingIdentity(ident);
10677            }
10678        }
10679    }
10680
10681    @Override
10682    public void stopAppSwitches() {
10683        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10684                != PackageManager.PERMISSION_GRANTED) {
10685            throw new SecurityException("Requires permission "
10686                    + android.Manifest.permission.STOP_APP_SWITCHES);
10687        }
10688
10689        synchronized(this) {
10690            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10691                    + APP_SWITCH_DELAY_TIME;
10692            mDidAppSwitch = false;
10693            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10694            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10695            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10696        }
10697    }
10698
10699    public void resumeAppSwitches() {
10700        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10701                != PackageManager.PERMISSION_GRANTED) {
10702            throw new SecurityException("Requires permission "
10703                    + android.Manifest.permission.STOP_APP_SWITCHES);
10704        }
10705
10706        synchronized(this) {
10707            // Note that we don't execute any pending app switches... we will
10708            // let those wait until either the timeout, or the next start
10709            // activity request.
10710            mAppSwitchesAllowedTime = 0;
10711        }
10712    }
10713
10714    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10715            int callingPid, int callingUid, String name) {
10716        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10717            return true;
10718        }
10719
10720        int perm = checkComponentPermission(
10721                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10722                sourceUid, -1, true);
10723        if (perm == PackageManager.PERMISSION_GRANTED) {
10724            return true;
10725        }
10726
10727        // If the actual IPC caller is different from the logical source, then
10728        // also see if they are allowed to control app switches.
10729        if (callingUid != -1 && callingUid != sourceUid) {
10730            perm = checkComponentPermission(
10731                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10732                    callingUid, -1, true);
10733            if (perm == PackageManager.PERMISSION_GRANTED) {
10734                return true;
10735            }
10736        }
10737
10738        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10739        return false;
10740    }
10741
10742    public void setDebugApp(String packageName, boolean waitForDebugger,
10743            boolean persistent) {
10744        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10745                "setDebugApp()");
10746
10747        long ident = Binder.clearCallingIdentity();
10748        try {
10749            // Note that this is not really thread safe if there are multiple
10750            // callers into it at the same time, but that's not a situation we
10751            // care about.
10752            if (persistent) {
10753                final ContentResolver resolver = mContext.getContentResolver();
10754                Settings.Global.putString(
10755                    resolver, Settings.Global.DEBUG_APP,
10756                    packageName);
10757                Settings.Global.putInt(
10758                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10759                    waitForDebugger ? 1 : 0);
10760            }
10761
10762            synchronized (this) {
10763                if (!persistent) {
10764                    mOrigDebugApp = mDebugApp;
10765                    mOrigWaitForDebugger = mWaitForDebugger;
10766                }
10767                mDebugApp = packageName;
10768                mWaitForDebugger = waitForDebugger;
10769                mDebugTransient = !persistent;
10770                if (packageName != null) {
10771                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10772                            false, UserHandle.USER_ALL, "set debug app");
10773                }
10774            }
10775        } finally {
10776            Binder.restoreCallingIdentity(ident);
10777        }
10778    }
10779
10780    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10781        synchronized (this) {
10782            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10783            if (!isDebuggable) {
10784                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10785                    throw new SecurityException("Process not debuggable: " + app.packageName);
10786                }
10787            }
10788
10789            mTrackAllocationApp = processName;
10790        }
10791    }
10792
10793    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10794        synchronized (this) {
10795            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10796            if (!isDebuggable) {
10797                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10798                    throw new SecurityException("Process not debuggable: " + app.packageName);
10799                }
10800            }
10801            mProfileApp = processName;
10802            mProfileFile = profilerInfo.profileFile;
10803            if (mProfileFd != null) {
10804                try {
10805                    mProfileFd.close();
10806                } catch (IOException e) {
10807                }
10808                mProfileFd = null;
10809            }
10810            mProfileFd = profilerInfo.profileFd;
10811            mSamplingInterval = profilerInfo.samplingInterval;
10812            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10813            mProfileType = 0;
10814        }
10815    }
10816
10817    @Override
10818    public void setAlwaysFinish(boolean enabled) {
10819        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10820                "setAlwaysFinish()");
10821
10822        Settings.Global.putInt(
10823                mContext.getContentResolver(),
10824                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10825
10826        synchronized (this) {
10827            mAlwaysFinishActivities = enabled;
10828        }
10829    }
10830
10831    @Override
10832    public void setActivityController(IActivityController controller) {
10833        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10834                "setActivityController()");
10835        synchronized (this) {
10836            mController = controller;
10837            Watchdog.getInstance().setActivityController(controller);
10838        }
10839    }
10840
10841    @Override
10842    public void setUserIsMonkey(boolean userIsMonkey) {
10843        synchronized (this) {
10844            synchronized (mPidsSelfLocked) {
10845                final int callingPid = Binder.getCallingPid();
10846                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10847                if (precessRecord == null) {
10848                    throw new SecurityException("Unknown process: " + callingPid);
10849                }
10850                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10851                    throw new SecurityException("Only an instrumentation process "
10852                            + "with a UiAutomation can call setUserIsMonkey");
10853                }
10854            }
10855            mUserIsMonkey = userIsMonkey;
10856        }
10857    }
10858
10859    @Override
10860    public boolean isUserAMonkey() {
10861        synchronized (this) {
10862            // If there is a controller also implies the user is a monkey.
10863            return (mUserIsMonkey || mController != null);
10864        }
10865    }
10866
10867    public void requestBugReport() {
10868        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10869        SystemProperties.set("ctl.start", "bugreport");
10870    }
10871
10872    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10873        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10874    }
10875
10876    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10877        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10878            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10879        }
10880        return KEY_DISPATCHING_TIMEOUT;
10881    }
10882
10883    @Override
10884    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10885        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10886                != PackageManager.PERMISSION_GRANTED) {
10887            throw new SecurityException("Requires permission "
10888                    + android.Manifest.permission.FILTER_EVENTS);
10889        }
10890        ProcessRecord proc;
10891        long timeout;
10892        synchronized (this) {
10893            synchronized (mPidsSelfLocked) {
10894                proc = mPidsSelfLocked.get(pid);
10895            }
10896            timeout = getInputDispatchingTimeoutLocked(proc);
10897        }
10898
10899        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10900            return -1;
10901        }
10902
10903        return timeout;
10904    }
10905
10906    /**
10907     * Handle input dispatching timeouts.
10908     * Returns whether input dispatching should be aborted or not.
10909     */
10910    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10911            final ActivityRecord activity, final ActivityRecord parent,
10912            final boolean aboveSystem, String reason) {
10913        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10914                != PackageManager.PERMISSION_GRANTED) {
10915            throw new SecurityException("Requires permission "
10916                    + android.Manifest.permission.FILTER_EVENTS);
10917        }
10918
10919        final String annotation;
10920        if (reason == null) {
10921            annotation = "Input dispatching timed out";
10922        } else {
10923            annotation = "Input dispatching timed out (" + reason + ")";
10924        }
10925
10926        if (proc != null) {
10927            synchronized (this) {
10928                if (proc.debugging) {
10929                    return false;
10930                }
10931
10932                if (mDidDexOpt) {
10933                    // Give more time since we were dexopting.
10934                    mDidDexOpt = false;
10935                    return false;
10936                }
10937
10938                if (proc.instrumentationClass != null) {
10939                    Bundle info = new Bundle();
10940                    info.putString("shortMsg", "keyDispatchingTimedOut");
10941                    info.putString("longMsg", annotation);
10942                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10943                    return true;
10944                }
10945            }
10946            mHandler.post(new Runnable() {
10947                @Override
10948                public void run() {
10949                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10950                }
10951            });
10952        }
10953
10954        return true;
10955    }
10956
10957    @Override
10958    public Bundle getAssistContextExtras(int requestType) {
10959        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10960                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10961        if (pae == null) {
10962            return null;
10963        }
10964        synchronized (pae) {
10965            while (!pae.haveResult) {
10966                try {
10967                    pae.wait();
10968                } catch (InterruptedException e) {
10969                }
10970            }
10971        }
10972        synchronized (this) {
10973            buildAssistBundleLocked(pae, pae.result);
10974            mPendingAssistExtras.remove(pae);
10975            mUiHandler.removeCallbacks(pae);
10976        }
10977        return pae.extras;
10978    }
10979
10980    @Override
10981    public boolean isAssistDataAllowedOnCurrentActivity() {
10982        int userId;
10983        synchronized (this) {
10984            userId = mUserController.getCurrentUserIdLocked();
10985            ActivityRecord activity = getFocusedStack().topActivity();
10986            if (activity == null) {
10987                return false;
10988            }
10989            userId = activity.userId;
10990        }
10991        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10992                Context.DEVICE_POLICY_SERVICE);
10993        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10994    }
10995
10996    @Override
10997    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10998        long ident = Binder.clearCallingIdentity();
10999        try {
11000            synchronized (this) {
11001                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11002                ActivityRecord top = getFocusedStack().topActivity();
11003                if (top != caller) {
11004                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11005                            + " is not current top " + top);
11006                    return false;
11007                }
11008                if (!top.nowVisible) {
11009                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11010                            + " is not visible");
11011                    return false;
11012                }
11013            }
11014            AssistUtils utils = new AssistUtils(mContext);
11015            return utils.showSessionForActiveService(args,
11016                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11017        } finally {
11018            Binder.restoreCallingIdentity(ident);
11019        }
11020    }
11021
11022    @Override
11023    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11024            IBinder activityToken) {
11025        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11026                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11027    }
11028
11029    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11030            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11031            long timeout) {
11032        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11033                "enqueueAssistContext()");
11034        synchronized (this) {
11035            ActivityRecord activity = getFocusedStack().topActivity();
11036            if (activity == null) {
11037                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11038                return null;
11039            }
11040            if (activity.app == null || activity.app.thread == null) {
11041                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11042                return null;
11043            }
11044            if (activityToken != null) {
11045                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11046                if (activity != caller) {
11047                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11048                            + " is not current top " + activity);
11049                    return null;
11050                }
11051            }
11052            PendingAssistExtras pae;
11053            Bundle extras = new Bundle();
11054            if (args != null) {
11055                extras.putAll(args);
11056            }
11057            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11058            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11059            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11060            try {
11061                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11062                        requestType);
11063                mPendingAssistExtras.add(pae);
11064                mUiHandler.postDelayed(pae, timeout);
11065            } catch (RemoteException e) {
11066                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11067                return null;
11068            }
11069            return pae;
11070        }
11071    }
11072
11073    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11074        IResultReceiver receiver;
11075        synchronized (this) {
11076            mPendingAssistExtras.remove(pae);
11077            receiver = pae.receiver;
11078        }
11079        if (receiver != null) {
11080            // Caller wants result sent back to them.
11081            try {
11082                pae.receiver.send(0, null);
11083            } catch (RemoteException e) {
11084            }
11085        }
11086    }
11087
11088    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11089        if (result != null) {
11090            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11091        }
11092        if (pae.hint != null) {
11093            pae.extras.putBoolean(pae.hint, true);
11094        }
11095    }
11096
11097    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11098            AssistContent content, Uri referrer) {
11099        PendingAssistExtras pae = (PendingAssistExtras)token;
11100        synchronized (pae) {
11101            pae.result = extras;
11102            pae.structure = structure;
11103            pae.content = content;
11104            if (referrer != null) {
11105                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11106            }
11107            pae.haveResult = true;
11108            pae.notifyAll();
11109            if (pae.intent == null && pae.receiver == null) {
11110                // Caller is just waiting for the result.
11111                return;
11112            }
11113        }
11114
11115        // We are now ready to launch the assist activity.
11116        IResultReceiver sendReceiver = null;
11117        Bundle sendBundle = null;
11118        synchronized (this) {
11119            buildAssistBundleLocked(pae, extras);
11120            boolean exists = mPendingAssistExtras.remove(pae);
11121            mUiHandler.removeCallbacks(pae);
11122            if (!exists) {
11123                // Timed out.
11124                return;
11125            }
11126            if ((sendReceiver=pae.receiver) != null) {
11127                // Caller wants result sent back to them.
11128                sendBundle = new Bundle();
11129                sendBundle.putBundle("data", pae.extras);
11130                sendBundle.putParcelable("structure", pae.structure);
11131                sendBundle.putParcelable("content", pae.content);
11132            }
11133        }
11134        if (sendReceiver != null) {
11135            try {
11136                sendReceiver.send(0, sendBundle);
11137            } catch (RemoteException e) {
11138            }
11139            return;
11140        }
11141
11142        long ident = Binder.clearCallingIdentity();
11143        try {
11144            pae.intent.replaceExtras(pae.extras);
11145            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11146                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11147                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11148            closeSystemDialogs("assist");
11149            try {
11150                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11151            } catch (ActivityNotFoundException e) {
11152                Slog.w(TAG, "No activity to handle assist action.", e);
11153            }
11154        } finally {
11155            Binder.restoreCallingIdentity(ident);
11156        }
11157    }
11158
11159    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11160            Bundle args) {
11161        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11162                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11163    }
11164
11165    public void registerProcessObserver(IProcessObserver observer) {
11166        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11167                "registerProcessObserver()");
11168        synchronized (this) {
11169            mProcessObservers.register(observer);
11170        }
11171    }
11172
11173    @Override
11174    public void unregisterProcessObserver(IProcessObserver observer) {
11175        synchronized (this) {
11176            mProcessObservers.unregister(observer);
11177        }
11178    }
11179
11180    public void registerUidObserver(IUidObserver observer) {
11181        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11182                "registerUidObserver()");
11183        synchronized (this) {
11184            mUidObservers.register(observer);
11185        }
11186    }
11187
11188    @Override
11189    public void unregisterUidObserver(IUidObserver observer) {
11190        synchronized (this) {
11191            mUidObservers.unregister(observer);
11192        }
11193    }
11194
11195    @Override
11196    public boolean convertFromTranslucent(IBinder token) {
11197        final long origId = Binder.clearCallingIdentity();
11198        try {
11199            synchronized (this) {
11200                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11201                if (r == null) {
11202                    return false;
11203                }
11204                final boolean translucentChanged = r.changeWindowTranslucency(true);
11205                if (translucentChanged) {
11206                    r.task.stack.releaseBackgroundResources(r);
11207                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11208                }
11209                mWindowManager.setAppFullscreen(token, true);
11210                return translucentChanged;
11211            }
11212        } finally {
11213            Binder.restoreCallingIdentity(origId);
11214        }
11215    }
11216
11217    @Override
11218    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11219        final long origId = Binder.clearCallingIdentity();
11220        try {
11221            synchronized (this) {
11222                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11223                if (r == null) {
11224                    return false;
11225                }
11226                int index = r.task.mActivities.lastIndexOf(r);
11227                if (index > 0) {
11228                    ActivityRecord under = r.task.mActivities.get(index - 1);
11229                    under.returningOptions = options;
11230                }
11231                final boolean translucentChanged = r.changeWindowTranslucency(false);
11232                if (translucentChanged) {
11233                    r.task.stack.convertActivityToTranslucent(r);
11234                }
11235                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11236                mWindowManager.setAppFullscreen(token, false);
11237                return translucentChanged;
11238            }
11239        } finally {
11240            Binder.restoreCallingIdentity(origId);
11241        }
11242    }
11243
11244    @Override
11245    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11246        final long origId = Binder.clearCallingIdentity();
11247        try {
11248            synchronized (this) {
11249                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11250                if (r != null) {
11251                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11252                }
11253            }
11254            return false;
11255        } finally {
11256            Binder.restoreCallingIdentity(origId);
11257        }
11258    }
11259
11260    @Override
11261    public boolean isBackgroundVisibleBehind(IBinder token) {
11262        final long origId = Binder.clearCallingIdentity();
11263        try {
11264            synchronized (this) {
11265                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11266                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11267                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11268                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11269                return visible;
11270            }
11271        } finally {
11272            Binder.restoreCallingIdentity(origId);
11273        }
11274    }
11275
11276    @Override
11277    public ActivityOptions getActivityOptions(IBinder token) {
11278        final long origId = Binder.clearCallingIdentity();
11279        try {
11280            synchronized (this) {
11281                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11282                if (r != null) {
11283                    final ActivityOptions activityOptions = r.pendingOptions;
11284                    r.pendingOptions = null;
11285                    return activityOptions;
11286                }
11287                return null;
11288            }
11289        } finally {
11290            Binder.restoreCallingIdentity(origId);
11291        }
11292    }
11293
11294    @Override
11295    public void setImmersive(IBinder token, boolean immersive) {
11296        synchronized(this) {
11297            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11298            if (r == null) {
11299                throw new IllegalArgumentException();
11300            }
11301            r.immersive = immersive;
11302
11303            // update associated state if we're frontmost
11304            if (r == mFocusedActivity) {
11305                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11306                applyUpdateLockStateLocked(r);
11307            }
11308        }
11309    }
11310
11311    @Override
11312    public boolean isImmersive(IBinder token) {
11313        synchronized (this) {
11314            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11315            if (r == null) {
11316                throw new IllegalArgumentException();
11317            }
11318            return r.immersive;
11319        }
11320    }
11321
11322    public boolean isTopActivityImmersive() {
11323        enforceNotIsolatedCaller("startActivity");
11324        synchronized (this) {
11325            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11326            return (r != null) ? r.immersive : false;
11327        }
11328    }
11329
11330    @Override
11331    public boolean isTopOfTask(IBinder token) {
11332        synchronized (this) {
11333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11334            if (r == null) {
11335                throw new IllegalArgumentException();
11336            }
11337            return r.task.getTopActivity() == r;
11338        }
11339    }
11340
11341    public final void enterSafeMode() {
11342        synchronized(this) {
11343            // It only makes sense to do this before the system is ready
11344            // and started launching other packages.
11345            if (!mSystemReady) {
11346                try {
11347                    AppGlobals.getPackageManager().enterSafeMode();
11348                } catch (RemoteException e) {
11349                }
11350            }
11351
11352            mSafeMode = true;
11353        }
11354    }
11355
11356    public final void showSafeModeOverlay() {
11357        View v = LayoutInflater.from(mContext).inflate(
11358                com.android.internal.R.layout.safe_mode, null);
11359        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11360        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11361        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11362        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11363        lp.gravity = Gravity.BOTTOM | Gravity.START;
11364        lp.format = v.getBackground().getOpacity();
11365        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11366                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11367        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11368        ((WindowManager)mContext.getSystemService(
11369                Context.WINDOW_SERVICE)).addView(v, lp);
11370    }
11371
11372    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11373        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11374            return;
11375        }
11376        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11377        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11378        synchronized (stats) {
11379            if (mBatteryStatsService.isOnBattery()) {
11380                mBatteryStatsService.enforceCallingPermission();
11381                int MY_UID = Binder.getCallingUid();
11382                final int uid;
11383                if (sender == null) {
11384                    uid = sourceUid;
11385                } else {
11386                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11387                }
11388                BatteryStatsImpl.Uid.Pkg pkg =
11389                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11390                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11391                pkg.noteWakeupAlarmLocked(tag);
11392            }
11393        }
11394    }
11395
11396    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11397        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11398            return;
11399        }
11400        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11401        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11402        synchronized (stats) {
11403            mBatteryStatsService.enforceCallingPermission();
11404            int MY_UID = Binder.getCallingUid();
11405            final int uid;
11406            if (sender == null) {
11407                uid = sourceUid;
11408            } else {
11409                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11410            }
11411            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11412        }
11413    }
11414
11415    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11416        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11417            return;
11418        }
11419        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11420        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11421        synchronized (stats) {
11422            mBatteryStatsService.enforceCallingPermission();
11423            int MY_UID = Binder.getCallingUid();
11424            final int uid;
11425            if (sender == null) {
11426                uid = sourceUid;
11427            } else {
11428                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11429            }
11430            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11431        }
11432    }
11433
11434    public boolean killPids(int[] pids, String pReason, boolean secure) {
11435        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11436            throw new SecurityException("killPids only available to the system");
11437        }
11438        String reason = (pReason == null) ? "Unknown" : pReason;
11439        // XXX Note: don't acquire main activity lock here, because the window
11440        // manager calls in with its locks held.
11441
11442        boolean killed = false;
11443        synchronized (mPidsSelfLocked) {
11444            int[] types = new int[pids.length];
11445            int worstType = 0;
11446            for (int i=0; i<pids.length; i++) {
11447                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11448                if (proc != null) {
11449                    int type = proc.setAdj;
11450                    types[i] = type;
11451                    if (type > worstType) {
11452                        worstType = type;
11453                    }
11454                }
11455            }
11456
11457            // If the worst oom_adj is somewhere in the cached proc LRU range,
11458            // then constrain it so we will kill all cached procs.
11459            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11460                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11461                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11462            }
11463
11464            // If this is not a secure call, don't let it kill processes that
11465            // are important.
11466            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11467                worstType = ProcessList.SERVICE_ADJ;
11468            }
11469
11470            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11471            for (int i=0; i<pids.length; i++) {
11472                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11473                if (proc == null) {
11474                    continue;
11475                }
11476                int adj = proc.setAdj;
11477                if (adj >= worstType && !proc.killedByAm) {
11478                    proc.kill(reason, true);
11479                    killed = true;
11480                }
11481            }
11482        }
11483        return killed;
11484    }
11485
11486    @Override
11487    public void killUid(int appId, int userId, String reason) {
11488        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11489        synchronized (this) {
11490            final long identity = Binder.clearCallingIdentity();
11491            try {
11492                killPackageProcessesLocked(null, appId, userId,
11493                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11494                        reason != null ? reason : "kill uid");
11495            } finally {
11496                Binder.restoreCallingIdentity(identity);
11497            }
11498        }
11499    }
11500
11501    @Override
11502    public boolean killProcessesBelowForeground(String reason) {
11503        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11504            throw new SecurityException("killProcessesBelowForeground() only available to system");
11505        }
11506
11507        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11508    }
11509
11510    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11511        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11512            throw new SecurityException("killProcessesBelowAdj() only available to system");
11513        }
11514
11515        boolean killed = false;
11516        synchronized (mPidsSelfLocked) {
11517            final int size = mPidsSelfLocked.size();
11518            for (int i = 0; i < size; i++) {
11519                final int pid = mPidsSelfLocked.keyAt(i);
11520                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11521                if (proc == null) continue;
11522
11523                final int adj = proc.setAdj;
11524                if (adj > belowAdj && !proc.killedByAm) {
11525                    proc.kill(reason, true);
11526                    killed = true;
11527                }
11528            }
11529        }
11530        return killed;
11531    }
11532
11533    @Override
11534    public void hang(final IBinder who, boolean allowRestart) {
11535        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11536                != PackageManager.PERMISSION_GRANTED) {
11537            throw new SecurityException("Requires permission "
11538                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11539        }
11540
11541        final IBinder.DeathRecipient death = new DeathRecipient() {
11542            @Override
11543            public void binderDied() {
11544                synchronized (this) {
11545                    notifyAll();
11546                }
11547            }
11548        };
11549
11550        try {
11551            who.linkToDeath(death, 0);
11552        } catch (RemoteException e) {
11553            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11554            return;
11555        }
11556
11557        synchronized (this) {
11558            Watchdog.getInstance().setAllowRestart(allowRestart);
11559            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11560            synchronized (death) {
11561                while (who.isBinderAlive()) {
11562                    try {
11563                        death.wait();
11564                    } catch (InterruptedException e) {
11565                    }
11566                }
11567            }
11568            Watchdog.getInstance().setAllowRestart(true);
11569        }
11570    }
11571
11572    @Override
11573    public void restart() {
11574        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11575                != PackageManager.PERMISSION_GRANTED) {
11576            throw new SecurityException("Requires permission "
11577                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11578        }
11579
11580        Log.i(TAG, "Sending shutdown broadcast...");
11581
11582        BroadcastReceiver br = new BroadcastReceiver() {
11583            @Override public void onReceive(Context context, Intent intent) {
11584                // Now the broadcast is done, finish up the low-level shutdown.
11585                Log.i(TAG, "Shutting down activity manager...");
11586                shutdown(10000);
11587                Log.i(TAG, "Shutdown complete, restarting!");
11588                Process.killProcess(Process.myPid());
11589                System.exit(10);
11590            }
11591        };
11592
11593        // First send the high-level shut down broadcast.
11594        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11595        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11596        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11597        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11598        mContext.sendOrderedBroadcastAsUser(intent,
11599                UserHandle.ALL, null, br, mHandler, 0, null, null);
11600        */
11601        br.onReceive(mContext, intent);
11602    }
11603
11604    private long getLowRamTimeSinceIdle(long now) {
11605        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11606    }
11607
11608    @Override
11609    public void performIdleMaintenance() {
11610        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11611                != PackageManager.PERMISSION_GRANTED) {
11612            throw new SecurityException("Requires permission "
11613                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11614        }
11615
11616        synchronized (this) {
11617            final long now = SystemClock.uptimeMillis();
11618            final long timeSinceLastIdle = now - mLastIdleTime;
11619            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11620            mLastIdleTime = now;
11621            mLowRamTimeSinceLastIdle = 0;
11622            if (mLowRamStartTime != 0) {
11623                mLowRamStartTime = now;
11624            }
11625
11626            StringBuilder sb = new StringBuilder(128);
11627            sb.append("Idle maintenance over ");
11628            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11629            sb.append(" low RAM for ");
11630            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11631            Slog.i(TAG, sb.toString());
11632
11633            // If at least 1/3 of our time since the last idle period has been spent
11634            // with RAM low, then we want to kill processes.
11635            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11636
11637            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11638                ProcessRecord proc = mLruProcesses.get(i);
11639                if (proc.notCachedSinceIdle) {
11640                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11641                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11642                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11643                        if (doKilling && proc.initialIdlePss != 0
11644                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11645                            sb = new StringBuilder(128);
11646                            sb.append("Kill");
11647                            sb.append(proc.processName);
11648                            sb.append(" in idle maint: pss=");
11649                            sb.append(proc.lastPss);
11650                            sb.append(", initialPss=");
11651                            sb.append(proc.initialIdlePss);
11652                            sb.append(", period=");
11653                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11654                            sb.append(", lowRamPeriod=");
11655                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11656                            Slog.wtfQuiet(TAG, sb.toString());
11657                            proc.kill("idle maint (pss " + proc.lastPss
11658                                    + " from " + proc.initialIdlePss + ")", true);
11659                        }
11660                    }
11661                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11662                    proc.notCachedSinceIdle = true;
11663                    proc.initialIdlePss = 0;
11664                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11665                            mTestPssMode, isSleeping(), now);
11666                }
11667            }
11668
11669            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11670            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11671        }
11672    }
11673
11674    private void retrieveSettings() {
11675        final ContentResolver resolver = mContext.getContentResolver();
11676        String debugApp = Settings.Global.getString(resolver, Settings.Global.DEBUG_APP);
11677        boolean waitForDebugger = Settings.Global.getInt(
11678            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11679        boolean alwaysFinishActivities = Settings.Global.getInt(
11680            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11681        boolean forceRtl = Settings.Global.getInt(
11682                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11683        int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
11684        boolean forceResizable = Settings.Global.getInt(
11685                resolver, Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
11686                defaultForceResizable) != 0;
11687        // Transfer any global setting for forcing RTL layout, into a System Property
11688        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11689
11690        Configuration configuration = new Configuration();
11691        Settings.System.getConfiguration(resolver, configuration);
11692        if (forceRtl) {
11693            // This will take care of setting the correct layout direction flags
11694            configuration.setLayoutDirection(configuration.locale);
11695        }
11696
11697        synchronized (this) {
11698            mDebugApp = mOrigDebugApp = debugApp;
11699            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11700            mAlwaysFinishActivities = alwaysFinishActivities;
11701            mForceResizableActivites = forceResizable;
11702            // This happens before any activities are started, so we can
11703            // change mConfiguration in-place.
11704            updateConfigurationLocked(configuration, null, true);
11705            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11706                    "Initial config: " + mConfiguration);
11707        }
11708    }
11709
11710    /** Loads resources after the current configuration has been set. */
11711    private void loadResourcesOnSystemReady() {
11712        final Resources res = mContext.getResources();
11713        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11714        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11715        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11716    }
11717
11718    public boolean testIsSystemReady() {
11719        // no need to synchronize(this) just to read & return the value
11720        return mSystemReady;
11721    }
11722
11723    private static File getCalledPreBootReceiversFile() {
11724        File dataDir = Environment.getDataDirectory();
11725        File systemDir = new File(dataDir, "system");
11726        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11727        return fname;
11728    }
11729
11730    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11731        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11732        File file = getCalledPreBootReceiversFile();
11733        FileInputStream fis = null;
11734        try {
11735            fis = new FileInputStream(file);
11736            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11737            int fvers = dis.readInt();
11738            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11739                String vers = dis.readUTF();
11740                String codename = dis.readUTF();
11741                String build = dis.readUTF();
11742                if (android.os.Build.VERSION.RELEASE.equals(vers)
11743                        && android.os.Build.VERSION.CODENAME.equals(codename)
11744                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11745                    int num = dis.readInt();
11746                    while (num > 0) {
11747                        num--;
11748                        String pkg = dis.readUTF();
11749                        String cls = dis.readUTF();
11750                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11751                    }
11752                }
11753            }
11754        } catch (FileNotFoundException e) {
11755        } catch (IOException e) {
11756            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11757        } finally {
11758            if (fis != null) {
11759                try {
11760                    fis.close();
11761                } catch (IOException e) {
11762                }
11763            }
11764        }
11765        return lastDoneReceivers;
11766    }
11767
11768    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11769        File file = getCalledPreBootReceiversFile();
11770        FileOutputStream fos = null;
11771        DataOutputStream dos = null;
11772        try {
11773            fos = new FileOutputStream(file);
11774            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11775            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11776            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11777            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11778            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11779            dos.writeInt(list.size());
11780            for (int i=0; i<list.size(); i++) {
11781                dos.writeUTF(list.get(i).getPackageName());
11782                dos.writeUTF(list.get(i).getClassName());
11783            }
11784        } catch (IOException e) {
11785            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11786            file.delete();
11787        } finally {
11788            FileUtils.sync(fos);
11789            if (dos != null) {
11790                try {
11791                    dos.close();
11792                } catch (IOException e) {
11793                    // TODO Auto-generated catch block
11794                    e.printStackTrace();
11795                }
11796            }
11797        }
11798    }
11799
11800    final class PreBootContinuation extends IIntentReceiver.Stub {
11801        final Intent intent;
11802        final Runnable onFinishCallback;
11803        final ArrayList<ComponentName> doneReceivers;
11804        final List<ResolveInfo> ris;
11805        final int[] users;
11806        int lastRi = -1;
11807        int curRi = 0;
11808        int curUser = 0;
11809
11810        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11811                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11812            intent = _intent;
11813            onFinishCallback = _onFinishCallback;
11814            doneReceivers = _doneReceivers;
11815            ris = _ris;
11816            users = _users;
11817        }
11818
11819        void go() {
11820            if (lastRi != curRi) {
11821                ActivityInfo ai = ris.get(curRi).activityInfo;
11822                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11823                intent.setComponent(comp);
11824                doneReceivers.add(comp);
11825                lastRi = curRi;
11826                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11827                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11828            }
11829            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11830                    + " for user " + users[curUser]);
11831            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11832            broadcastIntentLocked(null, null, intent, null, this,
11833                    0, null, null, null, AppOpsManager.OP_NONE,
11834                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11835        }
11836
11837        public void performReceive(Intent intent, int resultCode,
11838                String data, Bundle extras, boolean ordered,
11839                boolean sticky, int sendingUser) {
11840            curUser++;
11841            if (curUser >= users.length) {
11842                curUser = 0;
11843                curRi++;
11844                if (curRi >= ris.size()) {
11845                    // All done sending broadcasts!
11846                    if (onFinishCallback != null) {
11847                        // The raw IIntentReceiver interface is called
11848                        // with the AM lock held, so redispatch to
11849                        // execute our code without the lock.
11850                        mHandler.post(onFinishCallback);
11851                    }
11852                    return;
11853                }
11854            }
11855            go();
11856        }
11857    }
11858
11859    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11860            ArrayList<ComponentName> doneReceivers) {
11861        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11862        List<ResolveInfo> ris = null;
11863        try {
11864            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11865                    intent, null, 0, UserHandle.USER_SYSTEM);
11866        } catch (RemoteException e) {
11867        }
11868        if (ris == null) {
11869            return false;
11870        }
11871        for (int i=ris.size()-1; i>=0; i--) {
11872            if ((ris.get(i).activityInfo.applicationInfo.flags
11873                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11874                ris.remove(i);
11875            }
11876        }
11877        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11878
11879        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11880        for (int i=0; i<ris.size(); i++) {
11881            ActivityInfo ai = ris.get(i).activityInfo;
11882            ComponentName comp = new ComponentName(ai.packageName, ai.name);
11883            if (lastDoneReceivers.contains(comp)) {
11884                // We already did the pre boot receiver for this app with the current
11885                // platform version, so don't do it again...
11886                ris.remove(i);
11887                i--;
11888                // ...however, do keep it as one that has been done, so we don't
11889                // forget about it when rewriting the file of last done receivers.
11890                doneReceivers.add(comp);
11891            }
11892        }
11893
11894        if (ris.size() <= 0) {
11895            return false;
11896        }
11897
11898        // TODO: can we still do this with per user encryption?
11899        final int[] users = mUserController.getUsers();
11900        if (users.length <= 0) {
11901            return false;
11902        }
11903
11904        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11905                ris, users);
11906        cont.go();
11907        return true;
11908    }
11909
11910    public void systemReady(final Runnable goingCallback) {
11911        synchronized(this) {
11912            if (mSystemReady) {
11913                // If we're done calling all the receivers, run the next "boot phase" passed in
11914                // by the SystemServer
11915                if (goingCallback != null) {
11916                    goingCallback.run();
11917                }
11918                return;
11919            }
11920
11921            mLocalDeviceIdleController
11922                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11923
11924            // Make sure we have the current profile info, since it is needed for
11925            // security checks.
11926            mUserController.updateCurrentProfileIdsLocked();
11927
11928            mRecentTasks.clear();
11929            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
11930            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11931            mTaskPersister.startPersisting();
11932
11933            // Check to see if there are any update receivers to run.
11934            if (!mDidUpdate) {
11935                if (mWaitingUpdate) {
11936                    return;
11937                }
11938                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11939                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11940                    public void run() {
11941                        synchronized (ActivityManagerService.this) {
11942                            mDidUpdate = true;
11943                        }
11944                        showBootMessage(mContext.getText(
11945                                R.string.android_upgrading_complete),
11946                                false);
11947                        writeLastDonePreBootReceivers(doneReceivers);
11948                        systemReady(goingCallback);
11949                    }
11950                }, doneReceivers);
11951
11952                if (mWaitingUpdate) {
11953                    return;
11954                }
11955                mDidUpdate = true;
11956            }
11957
11958            mAppOpsService.systemReady();
11959            mSystemReady = true;
11960        }
11961
11962        ArrayList<ProcessRecord> procsToKill = null;
11963        synchronized(mPidsSelfLocked) {
11964            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11965                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11966                if (!isAllowedWhileBooting(proc.info)){
11967                    if (procsToKill == null) {
11968                        procsToKill = new ArrayList<ProcessRecord>();
11969                    }
11970                    procsToKill.add(proc);
11971                }
11972            }
11973        }
11974
11975        synchronized(this) {
11976            if (procsToKill != null) {
11977                for (int i=procsToKill.size()-1; i>=0; i--) {
11978                    ProcessRecord proc = procsToKill.get(i);
11979                    Slog.i(TAG, "Removing system update proc: " + proc);
11980                    removeProcessLocked(proc, true, false, "system update done");
11981                }
11982            }
11983
11984            // Now that we have cleaned up any update processes, we
11985            // are ready to start launching real processes and know that
11986            // we won't trample on them any more.
11987            mProcessesReady = true;
11988        }
11989
11990        Slog.i(TAG, "System now ready");
11991        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11992            SystemClock.uptimeMillis());
11993
11994        synchronized(this) {
11995            // Make sure we have no pre-ready processes sitting around.
11996
11997            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11998                ResolveInfo ri = mContext.getPackageManager()
11999                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12000                                STOCK_PM_FLAGS);
12001                CharSequence errorMsg = null;
12002                if (ri != null) {
12003                    ActivityInfo ai = ri.activityInfo;
12004                    ApplicationInfo app = ai.applicationInfo;
12005                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12006                        mTopAction = Intent.ACTION_FACTORY_TEST;
12007                        mTopData = null;
12008                        mTopComponent = new ComponentName(app.packageName,
12009                                ai.name);
12010                    } else {
12011                        errorMsg = mContext.getResources().getText(
12012                                com.android.internal.R.string.factorytest_not_system);
12013                    }
12014                } else {
12015                    errorMsg = mContext.getResources().getText(
12016                            com.android.internal.R.string.factorytest_no_action);
12017                }
12018                if (errorMsg != null) {
12019                    mTopAction = null;
12020                    mTopData = null;
12021                    mTopComponent = null;
12022                    Message msg = Message.obtain();
12023                    msg.what = SHOW_FACTORY_ERROR_MSG;
12024                    msg.getData().putCharSequence("msg", errorMsg);
12025                    mUiHandler.sendMessage(msg);
12026                }
12027            }
12028        }
12029
12030        retrieveSettings();
12031        loadResourcesOnSystemReady();
12032        final int currentUserId;
12033        synchronized (this) {
12034            currentUserId = mUserController.getCurrentUserIdLocked();
12035            readGrantedUriPermissionsLocked();
12036        }
12037
12038        if (goingCallback != null) goingCallback.run();
12039
12040
12041        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12042                Integer.toString(currentUserId), currentUserId);
12043        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12044                Integer.toString(currentUserId), currentUserId);
12045        mSystemServiceManager.startUser(currentUserId);
12046
12047        synchronized (this) {
12048            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12049                try {
12050                    List apps = AppGlobals.getPackageManager().
12051                        getPersistentApplications(STOCK_PM_FLAGS);
12052                    if (apps != null) {
12053                        int N = apps.size();
12054                        int i;
12055                        for (i=0; i<N; i++) {
12056                            ApplicationInfo info
12057                                = (ApplicationInfo)apps.get(i);
12058                            if (info != null &&
12059                                    !info.packageName.equals("android")) {
12060                                addAppLocked(info, false, null /* ABI override */);
12061                            }
12062                        }
12063                    }
12064                } catch (RemoteException ex) {
12065                    // pm is in same process, this will never happen.
12066                }
12067            }
12068
12069            enableSystemUserApps();
12070
12071            // Start up initial activity.
12072            mBooting = true;
12073            startHomeActivityLocked(currentUserId, "systemReady");
12074
12075            try {
12076                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12077                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12078                            + " data partition or your device will be unstable.");
12079                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
12080                }
12081            } catch (RemoteException e) {
12082            }
12083
12084            if (!Build.isBuildConsistent()) {
12085                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12086                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
12087            }
12088
12089            long ident = Binder.clearCallingIdentity();
12090            try {
12091                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12092                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12093                        | Intent.FLAG_RECEIVER_FOREGROUND);
12094                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12095                broadcastIntentLocked(null, null, intent,
12096                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12097                        null, false, false, MY_PID, Process.SYSTEM_UID,
12098                        currentUserId);
12099                intent = new Intent(Intent.ACTION_USER_STARTING);
12100                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12101                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12102                broadcastIntentLocked(null, null, intent,
12103                        null, new IIntentReceiver.Stub() {
12104                            @Override
12105                            public void performReceive(Intent intent, int resultCode, String data,
12106                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12107                                    throws RemoteException {
12108                            }
12109                        }, 0, null, null,
12110                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12111                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12112            } catch (Throwable t) {
12113                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12114            } finally {
12115                Binder.restoreCallingIdentity(ident);
12116            }
12117            mStackSupervisor.resumeTopActivitiesLocked();
12118            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12119        }
12120    }
12121
12122    private void enableSystemUserApps() {
12123        // For system user, enable apps based on the following conditions:
12124        // - app is whitelisted; or has no launcher icons; or has INTERACT_ACROSS_USERS permission
12125        // - app is not in the blacklist
12126        if (UserManager.isSplitSystemUser()) {
12127            AppsQueryHelper queryHelper = new AppsQueryHelper(mContext);
12128            Set<String> enableApps = new HashSet<>();
12129            enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
12130                            | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
12131                            | AppsQueryHelper.GET_DEFAULT_IMES,
12132                            /* systemAppsOnly */ true, UserHandle.SYSTEM));
12133            ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
12134            enableApps.addAll(wlApps);
12135            ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
12136            enableApps.removeAll(blApps);
12137
12138            List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true,
12139                    UserHandle.SYSTEM);
12140            final int systemAppsSize = systemApps.size();
12141            for (int i = 0; i < systemAppsSize; i++) {
12142                String pName = systemApps.get(i);
12143                boolean enable = enableApps.contains(pName);
12144                try {
12145                    if (enable) {
12146                        AppGlobals.getPackageManager().installExistingPackageAsUser(pName,
12147                                UserHandle.USER_SYSTEM);
12148                    } else {
12149                        AppGlobals.getPackageManager().deletePackageAsUser(pName, null,
12150                                UserHandle.USER_SYSTEM, PackageManager.DELETE_SYSTEM_APP);
12151                    }
12152                } catch (RemoteException e) {
12153                    Slog.e(TAG, "Error occured when processing package " + pName, e);
12154                }
12155            }
12156        }
12157    }
12158
12159    private boolean makeAppCrashingLocked(ProcessRecord app,
12160            String shortMsg, String longMsg, String stackTrace) {
12161        app.crashing = true;
12162        app.crashingReport = generateProcessError(app,
12163                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12164        startAppProblemLocked(app);
12165        app.stopFreezingAllLocked();
12166        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12167    }
12168
12169    private void makeAppNotRespondingLocked(ProcessRecord app,
12170            String activity, String shortMsg, String longMsg) {
12171        app.notResponding = true;
12172        app.notRespondingReport = generateProcessError(app,
12173                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12174                activity, shortMsg, longMsg, null);
12175        startAppProblemLocked(app);
12176        app.stopFreezingAllLocked();
12177    }
12178
12179    /**
12180     * Generate a process error record, suitable for attachment to a ProcessRecord.
12181     *
12182     * @param app The ProcessRecord in which the error occurred.
12183     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12184     *                      ActivityManager.AppErrorStateInfo
12185     * @param activity The activity associated with the crash, if known.
12186     * @param shortMsg Short message describing the crash.
12187     * @param longMsg Long message describing the crash.
12188     * @param stackTrace Full crash stack trace, may be null.
12189     *
12190     * @return Returns a fully-formed AppErrorStateInfo record.
12191     */
12192    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12193            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12194        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12195
12196        report.condition = condition;
12197        report.processName = app.processName;
12198        report.pid = app.pid;
12199        report.uid = app.info.uid;
12200        report.tag = activity;
12201        report.shortMsg = shortMsg;
12202        report.longMsg = longMsg;
12203        report.stackTrace = stackTrace;
12204
12205        return report;
12206    }
12207
12208    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12209        synchronized (this) {
12210            app.crashing = false;
12211            app.crashingReport = null;
12212            app.notResponding = false;
12213            app.notRespondingReport = null;
12214            if (app.anrDialog == fromDialog) {
12215                app.anrDialog = null;
12216            }
12217            if (app.waitDialog == fromDialog) {
12218                app.waitDialog = null;
12219            }
12220            if (app.pid > 0 && app.pid != MY_PID) {
12221                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12222                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12223                app.kill("user request after error", true);
12224            }
12225        }
12226    }
12227
12228    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12229            String shortMsg, String longMsg, String stackTrace) {
12230        long now = SystemClock.uptimeMillis();
12231
12232        Long crashTime;
12233        if (!app.isolated) {
12234            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12235        } else {
12236            crashTime = null;
12237        }
12238        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12239            // This process loses!
12240            Slog.w(TAG, "Process " + app.info.processName
12241                    + " has crashed too many times: killing!");
12242            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12243                    app.userId, app.info.processName, app.uid);
12244            mStackSupervisor.handleAppCrashLocked(app);
12245            if (!app.persistent) {
12246                // We don't want to start this process again until the user
12247                // explicitly does so...  but for persistent process, we really
12248                // need to keep it running.  If a persistent process is actually
12249                // repeatedly crashing, then badness for everyone.
12250                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12251                        app.info.processName);
12252                if (!app.isolated) {
12253                    // XXX We don't have a way to mark isolated processes
12254                    // as bad, since they don't have a peristent identity.
12255                    mBadProcesses.put(app.info.processName, app.uid,
12256                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12257                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12258                }
12259                app.bad = true;
12260                app.removed = true;
12261                // Don't let services in this process be restarted and potentially
12262                // annoy the user repeatedly.  Unless it is persistent, since those
12263                // processes run critical code.
12264                removeProcessLocked(app, false, false, "crash");
12265                mStackSupervisor.resumeTopActivitiesLocked();
12266                return false;
12267            }
12268            mStackSupervisor.resumeTopActivitiesLocked();
12269        } else {
12270            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12271        }
12272
12273        // Bump up the crash count of any services currently running in the proc.
12274        for (int i=app.services.size()-1; i>=0; i--) {
12275            // Any services running in the application need to be placed
12276            // back in the pending list.
12277            ServiceRecord sr = app.services.valueAt(i);
12278            sr.crashCount++;
12279        }
12280
12281        // If the crashing process is what we consider to be the "home process" and it has been
12282        // replaced by a third-party app, clear the package preferred activities from packages
12283        // with a home activity running in the process to prevent a repeatedly crashing app
12284        // from blocking the user to manually clear the list.
12285        final ArrayList<ActivityRecord> activities = app.activities;
12286        if (app == mHomeProcess && activities.size() > 0
12287                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12288            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12289                final ActivityRecord r = activities.get(activityNdx);
12290                if (r.isHomeActivity()) {
12291                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12292                    try {
12293                        ActivityThread.getPackageManager()
12294                                .clearPackagePreferredActivities(r.packageName);
12295                    } catch (RemoteException c) {
12296                        // pm is in same process, this will never happen.
12297                    }
12298                }
12299            }
12300        }
12301
12302        if (!app.isolated) {
12303            // XXX Can't keep track of crash times for isolated processes,
12304            // because they don't have a perisistent identity.
12305            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12306        }
12307
12308        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12309        return true;
12310    }
12311
12312    void startAppProblemLocked(ProcessRecord app) {
12313        // If this app is not running under the current user, then we
12314        // can't give it a report button because that would require
12315        // launching the report UI under a different user.
12316        app.errorReportReceiver = null;
12317
12318        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12319            if (app.userId == userId) {
12320                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12321                        mContext, app.info.packageName, app.info.flags);
12322            }
12323        }
12324        skipCurrentReceiverLocked(app);
12325    }
12326
12327    void skipCurrentReceiverLocked(ProcessRecord app) {
12328        for (BroadcastQueue queue : mBroadcastQueues) {
12329            queue.skipCurrentReceiverLocked(app);
12330        }
12331    }
12332
12333    /**
12334     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12335     * The application process will exit immediately after this call returns.
12336     * @param app object of the crashing app, null for the system server
12337     * @param crashInfo describing the exception
12338     */
12339    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12340        ProcessRecord r = findAppProcess(app, "Crash");
12341        final String processName = app == null ? "system_server"
12342                : (r == null ? "unknown" : r.processName);
12343
12344        handleApplicationCrashInner("crash", r, processName, crashInfo);
12345    }
12346
12347    /* Native crash reporting uses this inner version because it needs to be somewhat
12348     * decoupled from the AM-managed cleanup lifecycle
12349     */
12350    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12351            ApplicationErrorReport.CrashInfo crashInfo) {
12352        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12353                UserHandle.getUserId(Binder.getCallingUid()), processName,
12354                r == null ? -1 : r.info.flags,
12355                crashInfo.exceptionClassName,
12356                crashInfo.exceptionMessage,
12357                crashInfo.throwFileName,
12358                crashInfo.throwLineNumber);
12359
12360        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12361
12362        crashApplication(r, crashInfo);
12363    }
12364
12365    public void handleApplicationStrictModeViolation(
12366            IBinder app,
12367            int violationMask,
12368            StrictMode.ViolationInfo info) {
12369        ProcessRecord r = findAppProcess(app, "StrictMode");
12370        if (r == null) {
12371            return;
12372        }
12373
12374        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12375            Integer stackFingerprint = info.hashCode();
12376            boolean logIt = true;
12377            synchronized (mAlreadyLoggedViolatedStacks) {
12378                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12379                    logIt = false;
12380                    // TODO: sub-sample into EventLog for these, with
12381                    // the info.durationMillis?  Then we'd get
12382                    // the relative pain numbers, without logging all
12383                    // the stack traces repeatedly.  We'd want to do
12384                    // likewise in the client code, which also does
12385                    // dup suppression, before the Binder call.
12386                } else {
12387                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12388                        mAlreadyLoggedViolatedStacks.clear();
12389                    }
12390                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12391                }
12392            }
12393            if (logIt) {
12394                logStrictModeViolationToDropBox(r, info);
12395            }
12396        }
12397
12398        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12399            AppErrorResult result = new AppErrorResult();
12400            synchronized (this) {
12401                final long origId = Binder.clearCallingIdentity();
12402
12403                Message msg = Message.obtain();
12404                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12405                HashMap<String, Object> data = new HashMap<String, Object>();
12406                data.put("result", result);
12407                data.put("app", r);
12408                data.put("violationMask", violationMask);
12409                data.put("info", info);
12410                msg.obj = data;
12411                mUiHandler.sendMessage(msg);
12412
12413                Binder.restoreCallingIdentity(origId);
12414            }
12415            int res = result.get();
12416            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12417        }
12418    }
12419
12420    // Depending on the policy in effect, there could be a bunch of
12421    // these in quick succession so we try to batch these together to
12422    // minimize disk writes, number of dropbox entries, and maximize
12423    // compression, by having more fewer, larger records.
12424    private void logStrictModeViolationToDropBox(
12425            ProcessRecord process,
12426            StrictMode.ViolationInfo info) {
12427        if (info == null) {
12428            return;
12429        }
12430        final boolean isSystemApp = process == null ||
12431                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12432                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12433        final String processName = process == null ? "unknown" : process.processName;
12434        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12435        final DropBoxManager dbox = (DropBoxManager)
12436                mContext.getSystemService(Context.DROPBOX_SERVICE);
12437
12438        // Exit early if the dropbox isn't configured to accept this report type.
12439        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12440
12441        boolean bufferWasEmpty;
12442        boolean needsFlush;
12443        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12444        synchronized (sb) {
12445            bufferWasEmpty = sb.length() == 0;
12446            appendDropBoxProcessHeaders(process, processName, sb);
12447            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12448            sb.append("System-App: ").append(isSystemApp).append("\n");
12449            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12450            if (info.violationNumThisLoop != 0) {
12451                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12452            }
12453            if (info.numAnimationsRunning != 0) {
12454                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12455            }
12456            if (info.broadcastIntentAction != null) {
12457                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12458            }
12459            if (info.durationMillis != -1) {
12460                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12461            }
12462            if (info.numInstances != -1) {
12463                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12464            }
12465            if (info.tags != null) {
12466                for (String tag : info.tags) {
12467                    sb.append("Span-Tag: ").append(tag).append("\n");
12468                }
12469            }
12470            sb.append("\n");
12471            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12472                sb.append(info.crashInfo.stackTrace);
12473                sb.append("\n");
12474            }
12475            if (info.message != null) {
12476                sb.append(info.message);
12477                sb.append("\n");
12478            }
12479
12480            // Only buffer up to ~64k.  Various logging bits truncate
12481            // things at 128k.
12482            needsFlush = (sb.length() > 64 * 1024);
12483        }
12484
12485        // Flush immediately if the buffer's grown too large, or this
12486        // is a non-system app.  Non-system apps are isolated with a
12487        // different tag & policy and not batched.
12488        //
12489        // Batching is useful during internal testing with
12490        // StrictMode settings turned up high.  Without batching,
12491        // thousands of separate files could be created on boot.
12492        if (!isSystemApp || needsFlush) {
12493            new Thread("Error dump: " + dropboxTag) {
12494                @Override
12495                public void run() {
12496                    String report;
12497                    synchronized (sb) {
12498                        report = sb.toString();
12499                        sb.delete(0, sb.length());
12500                        sb.trimToSize();
12501                    }
12502                    if (report.length() != 0) {
12503                        dbox.addText(dropboxTag, report);
12504                    }
12505                }
12506            }.start();
12507            return;
12508        }
12509
12510        // System app batching:
12511        if (!bufferWasEmpty) {
12512            // An existing dropbox-writing thread is outstanding, so
12513            // we don't need to start it up.  The existing thread will
12514            // catch the buffer appends we just did.
12515            return;
12516        }
12517
12518        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12519        // (After this point, we shouldn't access AMS internal data structures.)
12520        new Thread("Error dump: " + dropboxTag) {
12521            @Override
12522            public void run() {
12523                // 5 second sleep to let stacks arrive and be batched together
12524                try {
12525                    Thread.sleep(5000);  // 5 seconds
12526                } catch (InterruptedException e) {}
12527
12528                String errorReport;
12529                synchronized (mStrictModeBuffer) {
12530                    errorReport = mStrictModeBuffer.toString();
12531                    if (errorReport.length() == 0) {
12532                        return;
12533                    }
12534                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12535                    mStrictModeBuffer.trimToSize();
12536                }
12537                dbox.addText(dropboxTag, errorReport);
12538            }
12539        }.start();
12540    }
12541
12542    /**
12543     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12544     * @param app object of the crashing app, null for the system server
12545     * @param tag reported by the caller
12546     * @param system whether this wtf is coming from the system
12547     * @param crashInfo describing the context of the error
12548     * @return true if the process should exit immediately (WTF is fatal)
12549     */
12550    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12551            final ApplicationErrorReport.CrashInfo crashInfo) {
12552        final int callingUid = Binder.getCallingUid();
12553        final int callingPid = Binder.getCallingPid();
12554
12555        if (system) {
12556            // If this is coming from the system, we could very well have low-level
12557            // system locks held, so we want to do this all asynchronously.  And we
12558            // never want this to become fatal, so there is that too.
12559            mHandler.post(new Runnable() {
12560                @Override public void run() {
12561                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12562                }
12563            });
12564            return false;
12565        }
12566
12567        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12568                crashInfo);
12569
12570        if (r != null && r.pid != Process.myPid() &&
12571                Settings.Global.getInt(mContext.getContentResolver(),
12572                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12573            crashApplication(r, crashInfo);
12574            return true;
12575        } else {
12576            return false;
12577        }
12578    }
12579
12580    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12581            final ApplicationErrorReport.CrashInfo crashInfo) {
12582        final ProcessRecord r = findAppProcess(app, "WTF");
12583        final String processName = app == null ? "system_server"
12584                : (r == null ? "unknown" : r.processName);
12585
12586        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12587                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12588
12589        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12590
12591        return r;
12592    }
12593
12594    /**
12595     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12596     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12597     */
12598    private ProcessRecord findAppProcess(IBinder app, String reason) {
12599        if (app == null) {
12600            return null;
12601        }
12602
12603        synchronized (this) {
12604            final int NP = mProcessNames.getMap().size();
12605            for (int ip=0; ip<NP; ip++) {
12606                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12607                final int NA = apps.size();
12608                for (int ia=0; ia<NA; ia++) {
12609                    ProcessRecord p = apps.valueAt(ia);
12610                    if (p.thread != null && p.thread.asBinder() == app) {
12611                        return p;
12612                    }
12613                }
12614            }
12615
12616            Slog.w(TAG, "Can't find mystery application for " + reason
12617                    + " from pid=" + Binder.getCallingPid()
12618                    + " uid=" + Binder.getCallingUid() + ": " + app);
12619            return null;
12620        }
12621    }
12622
12623    /**
12624     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12625     * to append various headers to the dropbox log text.
12626     */
12627    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12628            StringBuilder sb) {
12629        // Watchdog thread ends up invoking this function (with
12630        // a null ProcessRecord) to add the stack file to dropbox.
12631        // Do not acquire a lock on this (am) in such cases, as it
12632        // could cause a potential deadlock, if and when watchdog
12633        // is invoked due to unavailability of lock on am and it
12634        // would prevent watchdog from killing system_server.
12635        if (process == null) {
12636            sb.append("Process: ").append(processName).append("\n");
12637            return;
12638        }
12639        // Note: ProcessRecord 'process' is guarded by the service
12640        // instance.  (notably process.pkgList, which could otherwise change
12641        // concurrently during execution of this method)
12642        synchronized (this) {
12643            sb.append("Process: ").append(processName).append("\n");
12644            int flags = process.info.flags;
12645            IPackageManager pm = AppGlobals.getPackageManager();
12646            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12647            for (int ip=0; ip<process.pkgList.size(); ip++) {
12648                String pkg = process.pkgList.keyAt(ip);
12649                sb.append("Package: ").append(pkg);
12650                try {
12651                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12652                    if (pi != null) {
12653                        sb.append(" v").append(pi.versionCode);
12654                        if (pi.versionName != null) {
12655                            sb.append(" (").append(pi.versionName).append(")");
12656                        }
12657                    }
12658                } catch (RemoteException e) {
12659                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12660                }
12661                sb.append("\n");
12662            }
12663        }
12664    }
12665
12666    private static String processClass(ProcessRecord process) {
12667        if (process == null || process.pid == MY_PID) {
12668            return "system_server";
12669        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12670            return "system_app";
12671        } else {
12672            return "data_app";
12673        }
12674    }
12675
12676    /**
12677     * Write a description of an error (crash, WTF, ANR) to the drop box.
12678     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12679     * @param process which caused the error, null means the system server
12680     * @param activity which triggered the error, null if unknown
12681     * @param parent activity related to the error, null if unknown
12682     * @param subject line related to the error, null if absent
12683     * @param report in long form describing the error, null if absent
12684     * @param logFile to include in the report, null if none
12685     * @param crashInfo giving an application stack trace, null if absent
12686     */
12687    public void addErrorToDropBox(String eventType,
12688            ProcessRecord process, String processName, ActivityRecord activity,
12689            ActivityRecord parent, String subject,
12690            final String report, final File logFile,
12691            final ApplicationErrorReport.CrashInfo crashInfo) {
12692        // NOTE -- this must never acquire the ActivityManagerService lock,
12693        // otherwise the watchdog may be prevented from resetting the system.
12694
12695        final String dropboxTag = processClass(process) + "_" + eventType;
12696        final DropBoxManager dbox = (DropBoxManager)
12697                mContext.getSystemService(Context.DROPBOX_SERVICE);
12698
12699        // Exit early if the dropbox isn't configured to accept this report type.
12700        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12701
12702        final StringBuilder sb = new StringBuilder(1024);
12703        appendDropBoxProcessHeaders(process, processName, sb);
12704        if (activity != null) {
12705            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12706        }
12707        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12708            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12709        }
12710        if (parent != null && parent != activity) {
12711            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12712        }
12713        if (subject != null) {
12714            sb.append("Subject: ").append(subject).append("\n");
12715        }
12716        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12717        if (Debug.isDebuggerConnected()) {
12718            sb.append("Debugger: Connected\n");
12719        }
12720        sb.append("\n");
12721
12722        // Do the rest in a worker thread to avoid blocking the caller on I/O
12723        // (After this point, we shouldn't access AMS internal data structures.)
12724        Thread worker = new Thread("Error dump: " + dropboxTag) {
12725            @Override
12726            public void run() {
12727                if (report != null) {
12728                    sb.append(report);
12729                }
12730                if (logFile != null) {
12731                    try {
12732                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12733                                    "\n\n[[TRUNCATED]]"));
12734                    } catch (IOException e) {
12735                        Slog.e(TAG, "Error reading " + logFile, e);
12736                    }
12737                }
12738                if (crashInfo != null && crashInfo.stackTrace != null) {
12739                    sb.append(crashInfo.stackTrace);
12740                }
12741
12742                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12743                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12744                if (lines > 0) {
12745                    sb.append("\n");
12746
12747                    // Merge several logcat streams, and take the last N lines
12748                    InputStreamReader input = null;
12749                    try {
12750                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12751                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12752                                "-b", "crash",
12753                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12754
12755                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12756                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12757                        input = new InputStreamReader(logcat.getInputStream());
12758
12759                        int num;
12760                        char[] buf = new char[8192];
12761                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12762                    } catch (IOException e) {
12763                        Slog.e(TAG, "Error running logcat", e);
12764                    } finally {
12765                        if (input != null) try { input.close(); } catch (IOException e) {}
12766                    }
12767                }
12768
12769                dbox.addText(dropboxTag, sb.toString());
12770            }
12771        };
12772
12773        if (process == null) {
12774            // If process is null, we are being called from some internal code
12775            // and may be about to die -- run this synchronously.
12776            worker.run();
12777        } else {
12778            worker.start();
12779        }
12780    }
12781
12782    /**
12783     * Bring up the "unexpected error" dialog box for a crashing app.
12784     * Deal with edge cases (intercepts from instrumented applications,
12785     * ActivityController, error intent receivers, that sort of thing).
12786     * @param r the application crashing
12787     * @param crashInfo describing the failure
12788     */
12789    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12790        long timeMillis = System.currentTimeMillis();
12791        String shortMsg = crashInfo.exceptionClassName;
12792        String longMsg = crashInfo.exceptionMessage;
12793        String stackTrace = crashInfo.stackTrace;
12794        if (shortMsg != null && longMsg != null) {
12795            longMsg = shortMsg + ": " + longMsg;
12796        } else if (shortMsg != null) {
12797            longMsg = shortMsg;
12798        }
12799
12800        AppErrorResult result = new AppErrorResult();
12801        synchronized (this) {
12802            if (mController != null) {
12803                try {
12804                    String name = r != null ? r.processName : null;
12805                    int pid = r != null ? r.pid : Binder.getCallingPid();
12806                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12807                    if (!mController.appCrashed(name, pid,
12808                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12809                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12810                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12811                            Slog.w(TAG, "Skip killing native crashed app " + name
12812                                    + "(" + pid + ") during testing");
12813                        } else {
12814                            Slog.w(TAG, "Force-killing crashed app " + name
12815                                    + " at watcher's request");
12816                            if (r != null) {
12817                                r.kill("crash", true);
12818                            } else {
12819                                // Huh.
12820                                Process.killProcess(pid);
12821                                killProcessGroup(uid, pid);
12822                            }
12823                        }
12824                        return;
12825                    }
12826                } catch (RemoteException e) {
12827                    mController = null;
12828                    Watchdog.getInstance().setActivityController(null);
12829                }
12830            }
12831
12832            final long origId = Binder.clearCallingIdentity();
12833
12834            // If this process is running instrumentation, finish it.
12835            if (r != null && r.instrumentationClass != null) {
12836                Slog.w(TAG, "Error in app " + r.processName
12837                      + " running instrumentation " + r.instrumentationClass + ":");
12838                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12839                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12840                Bundle info = new Bundle();
12841                info.putString("shortMsg", shortMsg);
12842                info.putString("longMsg", longMsg);
12843                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12844                Binder.restoreCallingIdentity(origId);
12845                return;
12846            }
12847
12848            // Log crash in battery stats.
12849            if (r != null) {
12850                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12851            }
12852
12853            // If we can't identify the process or it's already exceeded its crash quota,
12854            // quit right away without showing a crash dialog.
12855            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12856                Binder.restoreCallingIdentity(origId);
12857                return;
12858            }
12859
12860            Message msg = Message.obtain();
12861            msg.what = SHOW_ERROR_MSG;
12862            HashMap data = new HashMap();
12863            data.put("result", result);
12864            data.put("app", r);
12865            msg.obj = data;
12866            mUiHandler.sendMessage(msg);
12867
12868            Binder.restoreCallingIdentity(origId);
12869        }
12870
12871        int res = result.get();
12872
12873        Intent appErrorIntent = null;
12874        synchronized (this) {
12875            if (r != null && !r.isolated) {
12876                // XXX Can't keep track of crash time for isolated processes,
12877                // since they don't have a persistent identity.
12878                mProcessCrashTimes.put(r.info.processName, r.uid,
12879                        SystemClock.uptimeMillis());
12880            }
12881            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12882                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12883            }
12884        }
12885
12886        if (appErrorIntent != null) {
12887            try {
12888                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12889            } catch (ActivityNotFoundException e) {
12890                Slog.w(TAG, "bug report receiver dissappeared", e);
12891            }
12892        }
12893    }
12894
12895    Intent createAppErrorIntentLocked(ProcessRecord r,
12896            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12897        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12898        if (report == null) {
12899            return null;
12900        }
12901        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12902        result.setComponent(r.errorReportReceiver);
12903        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12904        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12905        return result;
12906    }
12907
12908    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12909            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12910        if (r.errorReportReceiver == null) {
12911            return null;
12912        }
12913
12914        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12915            return null;
12916        }
12917
12918        ApplicationErrorReport report = new ApplicationErrorReport();
12919        report.packageName = r.info.packageName;
12920        report.installerPackageName = r.errorReportReceiver.getPackageName();
12921        report.processName = r.processName;
12922        report.time = timeMillis;
12923        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12924
12925        if (r.crashing || r.forceCrashReport) {
12926            report.type = ApplicationErrorReport.TYPE_CRASH;
12927            report.crashInfo = crashInfo;
12928        } else if (r.notResponding) {
12929            report.type = ApplicationErrorReport.TYPE_ANR;
12930            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12931
12932            report.anrInfo.activity = r.notRespondingReport.tag;
12933            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12934            report.anrInfo.info = r.notRespondingReport.longMsg;
12935        }
12936
12937        return report;
12938    }
12939
12940    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12941        enforceNotIsolatedCaller("getProcessesInErrorState");
12942        // assume our apps are happy - lazy create the list
12943        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12944
12945        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12946                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12947        int userId = UserHandle.getUserId(Binder.getCallingUid());
12948
12949        synchronized (this) {
12950
12951            // iterate across all processes
12952            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12953                ProcessRecord app = mLruProcesses.get(i);
12954                if (!allUsers && app.userId != userId) {
12955                    continue;
12956                }
12957                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12958                    // This one's in trouble, so we'll generate a report for it
12959                    // crashes are higher priority (in case there's a crash *and* an anr)
12960                    ActivityManager.ProcessErrorStateInfo report = null;
12961                    if (app.crashing) {
12962                        report = app.crashingReport;
12963                    } else if (app.notResponding) {
12964                        report = app.notRespondingReport;
12965                    }
12966
12967                    if (report != null) {
12968                        if (errList == null) {
12969                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12970                        }
12971                        errList.add(report);
12972                    } else {
12973                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12974                                " crashing = " + app.crashing +
12975                                " notResponding = " + app.notResponding);
12976                    }
12977                }
12978            }
12979        }
12980
12981        return errList;
12982    }
12983
12984    static int procStateToImportance(int procState, int memAdj,
12985            ActivityManager.RunningAppProcessInfo currApp) {
12986        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12987        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12988            currApp.lru = memAdj;
12989        } else {
12990            currApp.lru = 0;
12991        }
12992        return imp;
12993    }
12994
12995    private void fillInProcMemInfo(ProcessRecord app,
12996            ActivityManager.RunningAppProcessInfo outInfo) {
12997        outInfo.pid = app.pid;
12998        outInfo.uid = app.info.uid;
12999        if (mHeavyWeightProcess == app) {
13000            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13001        }
13002        if (app.persistent) {
13003            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13004        }
13005        if (app.activities.size() > 0) {
13006            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13007        }
13008        outInfo.lastTrimLevel = app.trimMemoryLevel;
13009        int adj = app.curAdj;
13010        int procState = app.curProcState;
13011        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13012        outInfo.importanceReasonCode = app.adjTypeCode;
13013        outInfo.processState = app.curProcState;
13014    }
13015
13016    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13017        enforceNotIsolatedCaller("getRunningAppProcesses");
13018
13019        final int callingUid = Binder.getCallingUid();
13020
13021        // Lazy instantiation of list
13022        List<ActivityManager.RunningAppProcessInfo> runList = null;
13023        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13024                callingUid) == PackageManager.PERMISSION_GRANTED;
13025        final int userId = UserHandle.getUserId(callingUid);
13026        final boolean allUids = isGetTasksAllowed(
13027                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13028
13029        synchronized (this) {
13030            // Iterate across all processes
13031            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13032                ProcessRecord app = mLruProcesses.get(i);
13033                if ((!allUsers && app.userId != userId)
13034                        || (!allUids && app.uid != callingUid)) {
13035                    continue;
13036                }
13037                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13038                    // Generate process state info for running application
13039                    ActivityManager.RunningAppProcessInfo currApp =
13040                        new ActivityManager.RunningAppProcessInfo(app.processName,
13041                                app.pid, app.getPackageList());
13042                    fillInProcMemInfo(app, currApp);
13043                    if (app.adjSource instanceof ProcessRecord) {
13044                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13045                        currApp.importanceReasonImportance =
13046                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13047                                        app.adjSourceProcState);
13048                    } else if (app.adjSource instanceof ActivityRecord) {
13049                        ActivityRecord r = (ActivityRecord)app.adjSource;
13050                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13051                    }
13052                    if (app.adjTarget instanceof ComponentName) {
13053                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13054                    }
13055                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13056                    //        + " lru=" + currApp.lru);
13057                    if (runList == null) {
13058                        runList = new ArrayList<>();
13059                    }
13060                    runList.add(currApp);
13061                }
13062            }
13063        }
13064        return runList;
13065    }
13066
13067    public List<ApplicationInfo> getRunningExternalApplications() {
13068        enforceNotIsolatedCaller("getRunningExternalApplications");
13069        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13070        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13071        if (runningApps != null && runningApps.size() > 0) {
13072            Set<String> extList = new HashSet<String>();
13073            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13074                if (app.pkgList != null) {
13075                    for (String pkg : app.pkgList) {
13076                        extList.add(pkg);
13077                    }
13078                }
13079            }
13080            IPackageManager pm = AppGlobals.getPackageManager();
13081            for (String pkg : extList) {
13082                try {
13083                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13084                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13085                        retList.add(info);
13086                    }
13087                } catch (RemoteException e) {
13088                }
13089            }
13090        }
13091        return retList;
13092    }
13093
13094    @Override
13095    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13096        enforceNotIsolatedCaller("getMyMemoryState");
13097        synchronized (this) {
13098            ProcessRecord proc;
13099            synchronized (mPidsSelfLocked) {
13100                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13101            }
13102            fillInProcMemInfo(proc, outInfo);
13103        }
13104    }
13105
13106    @Override
13107    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13108            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13109        (new ActivityManagerShellCommand(this, false)).exec(
13110                this, in, out, err, args, resultReceiver);
13111    }
13112
13113    @Override
13114    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13115        if (checkCallingPermission(android.Manifest.permission.DUMP)
13116                != PackageManager.PERMISSION_GRANTED) {
13117            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13118                    + Binder.getCallingPid()
13119                    + ", uid=" + Binder.getCallingUid()
13120                    + " without permission "
13121                    + android.Manifest.permission.DUMP);
13122            return;
13123        }
13124
13125        boolean dumpAll = false;
13126        boolean dumpClient = false;
13127        String dumpPackage = null;
13128
13129        int opti = 0;
13130        while (opti < args.length) {
13131            String opt = args[opti];
13132            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13133                break;
13134            }
13135            opti++;
13136            if ("-a".equals(opt)) {
13137                dumpAll = true;
13138            } else if ("-c".equals(opt)) {
13139                dumpClient = true;
13140            } else if ("-p".equals(opt)) {
13141                if (opti < args.length) {
13142                    dumpPackage = args[opti];
13143                    opti++;
13144                } else {
13145                    pw.println("Error: -p option requires package argument");
13146                    return;
13147                }
13148                dumpClient = true;
13149            } else if ("-h".equals(opt)) {
13150                ActivityManagerShellCommand.dumpHelp(pw, true);
13151                return;
13152            } else {
13153                pw.println("Unknown argument: " + opt + "; use -h for help");
13154            }
13155        }
13156
13157        long origId = Binder.clearCallingIdentity();
13158        boolean more = false;
13159        // Is the caller requesting to dump a particular piece of data?
13160        if (opti < args.length) {
13161            String cmd = args[opti];
13162            opti++;
13163            if ("activities".equals(cmd) || "a".equals(cmd)) {
13164                synchronized (this) {
13165                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13166                }
13167            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13168                synchronized (this) {
13169                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13170                }
13171            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13172                String[] newArgs;
13173                String name;
13174                if (opti >= args.length) {
13175                    name = null;
13176                    newArgs = EMPTY_STRING_ARRAY;
13177                } else {
13178                    dumpPackage = args[opti];
13179                    opti++;
13180                    newArgs = new String[args.length - opti];
13181                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13182                            args.length - opti);
13183                }
13184                synchronized (this) {
13185                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13186                }
13187            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13188                String[] newArgs;
13189                String name;
13190                if (opti >= args.length) {
13191                    name = null;
13192                    newArgs = EMPTY_STRING_ARRAY;
13193                } else {
13194                    dumpPackage = args[opti];
13195                    opti++;
13196                    newArgs = new String[args.length - opti];
13197                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13198                            args.length - opti);
13199                }
13200                synchronized (this) {
13201                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13202                }
13203            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13204                String[] newArgs;
13205                String name;
13206                if (opti >= args.length) {
13207                    name = null;
13208                    newArgs = EMPTY_STRING_ARRAY;
13209                } else {
13210                    dumpPackage = args[opti];
13211                    opti++;
13212                    newArgs = new String[args.length - opti];
13213                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13214                            args.length - opti);
13215                }
13216                synchronized (this) {
13217                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13218                }
13219            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13220                synchronized (this) {
13221                    dumpOomLocked(fd, pw, args, opti, true);
13222                }
13223            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13224                synchronized (this) {
13225                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13226                }
13227            } else if ("provider".equals(cmd)) {
13228                String[] newArgs;
13229                String name;
13230                if (opti >= args.length) {
13231                    name = null;
13232                    newArgs = EMPTY_STRING_ARRAY;
13233                } else {
13234                    name = args[opti];
13235                    opti++;
13236                    newArgs = new String[args.length - opti];
13237                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13238                }
13239                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13240                    pw.println("No providers match: " + name);
13241                    pw.println("Use -h for help.");
13242                }
13243            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13244                synchronized (this) {
13245                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13246                }
13247            } else if ("service".equals(cmd)) {
13248                String[] newArgs;
13249                String name;
13250                if (opti >= args.length) {
13251                    name = null;
13252                    newArgs = EMPTY_STRING_ARRAY;
13253                } else {
13254                    name = args[opti];
13255                    opti++;
13256                    newArgs = new String[args.length - opti];
13257                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13258                            args.length - opti);
13259                }
13260                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13261                    pw.println("No services match: " + name);
13262                    pw.println("Use -h for help.");
13263                }
13264            } else if ("package".equals(cmd)) {
13265                String[] newArgs;
13266                if (opti >= args.length) {
13267                    pw.println("package: no package name specified");
13268                    pw.println("Use -h for help.");
13269                } else {
13270                    dumpPackage = args[opti];
13271                    opti++;
13272                    newArgs = new String[args.length - opti];
13273                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13274                            args.length - opti);
13275                    args = newArgs;
13276                    opti = 0;
13277                    more = true;
13278                }
13279            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13280                synchronized (this) {
13281                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13282                }
13283            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13284                synchronized (this) {
13285                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13286                }
13287            } else {
13288                // Dumping a single activity?
13289                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13290                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13291                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13292                    if (res < 0) {
13293                        pw.println("Bad activity command, or no activities match: " + cmd);
13294                        pw.println("Use -h for help.");
13295                    }
13296                }
13297            }
13298            if (!more) {
13299                Binder.restoreCallingIdentity(origId);
13300                return;
13301            }
13302        }
13303
13304        // No piece of data specified, dump everything.
13305        synchronized (this) {
13306            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13307            pw.println();
13308            if (dumpAll) {
13309                pw.println("-------------------------------------------------------------------------------");
13310            }
13311            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13312            pw.println();
13313            if (dumpAll) {
13314                pw.println("-------------------------------------------------------------------------------");
13315            }
13316            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13317            pw.println();
13318            if (dumpAll) {
13319                pw.println("-------------------------------------------------------------------------------");
13320            }
13321            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13322            pw.println();
13323            if (dumpAll) {
13324                pw.println("-------------------------------------------------------------------------------");
13325            }
13326            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13327            pw.println();
13328            if (dumpAll) {
13329                pw.println("-------------------------------------------------------------------------------");
13330            }
13331            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13332            pw.println();
13333            if (dumpAll) {
13334                pw.println("-------------------------------------------------------------------------------");
13335            }
13336            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13337            if (mAssociations.size() > 0) {
13338                pw.println();
13339                if (dumpAll) {
13340                    pw.println("-------------------------------------------------------------------------------");
13341                }
13342                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13343            }
13344            pw.println();
13345            if (dumpAll) {
13346                pw.println("-------------------------------------------------------------------------------");
13347            }
13348            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13349        }
13350        Binder.restoreCallingIdentity(origId);
13351    }
13352
13353    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13354            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13355        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13356
13357        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13358                dumpPackage);
13359        boolean needSep = printedAnything;
13360
13361        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13362                dumpPackage, needSep, "  mFocusedActivity: ");
13363        if (printed) {
13364            printedAnything = true;
13365            needSep = false;
13366        }
13367
13368        if (dumpPackage == null) {
13369            if (needSep) {
13370                pw.println();
13371            }
13372            needSep = true;
13373            printedAnything = true;
13374            mStackSupervisor.dump(pw, "  ");
13375        }
13376
13377        if (!printedAnything) {
13378            pw.println("  (nothing)");
13379        }
13380    }
13381
13382    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13383            int opti, boolean dumpAll, String dumpPackage) {
13384        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13385
13386        boolean printedAnything = false;
13387
13388        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13389            boolean printedHeader = false;
13390
13391            final int N = mRecentTasks.size();
13392            for (int i=0; i<N; i++) {
13393                TaskRecord tr = mRecentTasks.get(i);
13394                if (dumpPackage != null) {
13395                    if (tr.realActivity == null ||
13396                            !dumpPackage.equals(tr.realActivity)) {
13397                        continue;
13398                    }
13399                }
13400                if (!printedHeader) {
13401                    pw.println("  Recent tasks:");
13402                    printedHeader = true;
13403                    printedAnything = true;
13404                }
13405                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13406                        pw.println(tr);
13407                if (dumpAll) {
13408                    mRecentTasks.get(i).dump(pw, "    ");
13409                }
13410            }
13411        }
13412
13413        if (!printedAnything) {
13414            pw.println("  (nothing)");
13415        }
13416    }
13417
13418    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13419            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13420        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13421
13422        int dumpUid = 0;
13423        if (dumpPackage != null) {
13424            IPackageManager pm = AppGlobals.getPackageManager();
13425            try {
13426                dumpUid = pm.getPackageUid(dumpPackage, 0);
13427            } catch (RemoteException e) {
13428            }
13429        }
13430
13431        boolean printedAnything = false;
13432
13433        final long now = SystemClock.uptimeMillis();
13434
13435        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13436            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13437                    = mAssociations.valueAt(i1);
13438            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13439                SparseArray<ArrayMap<String, Association>> sourceUids
13440                        = targetComponents.valueAt(i2);
13441                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13442                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13443                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13444                        Association ass = sourceProcesses.valueAt(i4);
13445                        if (dumpPackage != null) {
13446                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13447                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13448                                continue;
13449                            }
13450                        }
13451                        printedAnything = true;
13452                        pw.print("  ");
13453                        pw.print(ass.mTargetProcess);
13454                        pw.print("/");
13455                        UserHandle.formatUid(pw, ass.mTargetUid);
13456                        pw.print(" <- ");
13457                        pw.print(ass.mSourceProcess);
13458                        pw.print("/");
13459                        UserHandle.formatUid(pw, ass.mSourceUid);
13460                        pw.println();
13461                        pw.print("    via ");
13462                        pw.print(ass.mTargetComponent.flattenToShortString());
13463                        pw.println();
13464                        pw.print("    ");
13465                        long dur = ass.mTime;
13466                        if (ass.mNesting > 0) {
13467                            dur += now - ass.mStartTime;
13468                        }
13469                        TimeUtils.formatDuration(dur, pw);
13470                        pw.print(" (");
13471                        pw.print(ass.mCount);
13472                        pw.println(" times)");
13473                        if (ass.mNesting > 0) {
13474                            pw.print("    ");
13475                            pw.print(" Currently active: ");
13476                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13477                            pw.println();
13478                        }
13479                    }
13480                }
13481            }
13482
13483        }
13484
13485        if (!printedAnything) {
13486            pw.println("  (nothing)");
13487        }
13488    }
13489
13490    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13491            int opti, boolean dumpAll, String dumpPackage) {
13492        boolean needSep = false;
13493        boolean printedAnything = false;
13494        int numPers = 0;
13495
13496        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13497
13498        if (dumpAll) {
13499            final int NP = mProcessNames.getMap().size();
13500            for (int ip=0; ip<NP; ip++) {
13501                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13502                final int NA = procs.size();
13503                for (int ia=0; ia<NA; ia++) {
13504                    ProcessRecord r = procs.valueAt(ia);
13505                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13506                        continue;
13507                    }
13508                    if (!needSep) {
13509                        pw.println("  All known processes:");
13510                        needSep = true;
13511                        printedAnything = true;
13512                    }
13513                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13514                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13515                        pw.print(" "); pw.println(r);
13516                    r.dump(pw, "    ");
13517                    if (r.persistent) {
13518                        numPers++;
13519                    }
13520                }
13521            }
13522        }
13523
13524        if (mIsolatedProcesses.size() > 0) {
13525            boolean printed = false;
13526            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13527                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13528                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13529                    continue;
13530                }
13531                if (!printed) {
13532                    if (needSep) {
13533                        pw.println();
13534                    }
13535                    pw.println("  Isolated process list (sorted by uid):");
13536                    printedAnything = true;
13537                    printed = true;
13538                    needSep = true;
13539                }
13540                pw.println(String.format("%sIsolated #%2d: %s",
13541                        "    ", i, r.toString()));
13542            }
13543        }
13544
13545        if (mActiveUids.size() > 0) {
13546            boolean printed = false;
13547            int whichAppId = -1;
13548            if (dumpPackage != null) {
13549                try {
13550                    ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13551                            dumpPackage, 0);
13552                    whichAppId = UserHandle.getAppId(info.uid);
13553                } catch (NameNotFoundException e) {
13554                    e.printStackTrace();
13555                }
13556            }
13557            for (int i=0; i<mActiveUids.size(); i++) {
13558                UidRecord uidRec = mActiveUids.valueAt(i);
13559                if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13560                    continue;
13561                }
13562                if (!printed) {
13563                    printed = true;
13564                    if (needSep) {
13565                        pw.println();
13566                    }
13567                    pw.println("  UID states:");
13568                    needSep = true;
13569                    printedAnything = true;
13570                }
13571                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13572                pw.print(": "); pw.println(uidRec);
13573            }
13574        }
13575
13576        if (mLruProcesses.size() > 0) {
13577            if (needSep) {
13578                pw.println();
13579            }
13580            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13581                    pw.print(" total, non-act at ");
13582                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13583                    pw.print(", non-svc at ");
13584                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13585                    pw.println("):");
13586            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13587            needSep = true;
13588            printedAnything = true;
13589        }
13590
13591        if (dumpAll || dumpPackage != null) {
13592            synchronized (mPidsSelfLocked) {
13593                boolean printed = false;
13594                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13595                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13596                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13597                        continue;
13598                    }
13599                    if (!printed) {
13600                        if (needSep) pw.println();
13601                        needSep = true;
13602                        pw.println("  PID mappings:");
13603                        printed = true;
13604                        printedAnything = true;
13605                    }
13606                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13607                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13608                }
13609            }
13610        }
13611
13612        if (mForegroundProcesses.size() > 0) {
13613            synchronized (mPidsSelfLocked) {
13614                boolean printed = false;
13615                for (int i=0; i<mForegroundProcesses.size(); i++) {
13616                    ProcessRecord r = mPidsSelfLocked.get(
13617                            mForegroundProcesses.valueAt(i).pid);
13618                    if (dumpPackage != null && (r == null
13619                            || !r.pkgList.containsKey(dumpPackage))) {
13620                        continue;
13621                    }
13622                    if (!printed) {
13623                        if (needSep) pw.println();
13624                        needSep = true;
13625                        pw.println("  Foreground Processes:");
13626                        printed = true;
13627                        printedAnything = true;
13628                    }
13629                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13630                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13631                }
13632            }
13633        }
13634
13635        if (mPersistentStartingProcesses.size() > 0) {
13636            if (needSep) pw.println();
13637            needSep = true;
13638            printedAnything = true;
13639            pw.println("  Persisent processes that are starting:");
13640            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13641                    "Starting Norm", "Restarting PERS", dumpPackage);
13642        }
13643
13644        if (mRemovedProcesses.size() > 0) {
13645            if (needSep) pw.println();
13646            needSep = true;
13647            printedAnything = true;
13648            pw.println("  Processes that are being removed:");
13649            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13650                    "Removed Norm", "Removed PERS", dumpPackage);
13651        }
13652
13653        if (mProcessesOnHold.size() > 0) {
13654            if (needSep) pw.println();
13655            needSep = true;
13656            printedAnything = true;
13657            pw.println("  Processes that are on old until the system is ready:");
13658            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13659                    "OnHold Norm", "OnHold PERS", dumpPackage);
13660        }
13661
13662        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13663
13664        if (mProcessCrashTimes.getMap().size() > 0) {
13665            boolean printed = false;
13666            long now = SystemClock.uptimeMillis();
13667            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13668            final int NP = pmap.size();
13669            for (int ip=0; ip<NP; ip++) {
13670                String pname = pmap.keyAt(ip);
13671                SparseArray<Long> uids = pmap.valueAt(ip);
13672                final int N = uids.size();
13673                for (int i=0; i<N; i++) {
13674                    int puid = uids.keyAt(i);
13675                    ProcessRecord r = mProcessNames.get(pname, puid);
13676                    if (dumpPackage != null && (r == null
13677                            || !r.pkgList.containsKey(dumpPackage))) {
13678                        continue;
13679                    }
13680                    if (!printed) {
13681                        if (needSep) pw.println();
13682                        needSep = true;
13683                        pw.println("  Time since processes crashed:");
13684                        printed = true;
13685                        printedAnything = true;
13686                    }
13687                    pw.print("    Process "); pw.print(pname);
13688                            pw.print(" uid "); pw.print(puid);
13689                            pw.print(": last crashed ");
13690                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13691                            pw.println(" ago");
13692                }
13693            }
13694        }
13695
13696        if (mBadProcesses.getMap().size() > 0) {
13697            boolean printed = false;
13698            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13699            final int NP = pmap.size();
13700            for (int ip=0; ip<NP; ip++) {
13701                String pname = pmap.keyAt(ip);
13702                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13703                final int N = uids.size();
13704                for (int i=0; i<N; i++) {
13705                    int puid = uids.keyAt(i);
13706                    ProcessRecord r = mProcessNames.get(pname, puid);
13707                    if (dumpPackage != null && (r == null
13708                            || !r.pkgList.containsKey(dumpPackage))) {
13709                        continue;
13710                    }
13711                    if (!printed) {
13712                        if (needSep) pw.println();
13713                        needSep = true;
13714                        pw.println("  Bad processes:");
13715                        printedAnything = true;
13716                    }
13717                    BadProcessInfo info = uids.valueAt(i);
13718                    pw.print("    Bad process "); pw.print(pname);
13719                            pw.print(" uid "); pw.print(puid);
13720                            pw.print(": crashed at time "); pw.println(info.time);
13721                    if (info.shortMsg != null) {
13722                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13723                    }
13724                    if (info.longMsg != null) {
13725                        pw.print("      Long msg: "); pw.println(info.longMsg);
13726                    }
13727                    if (info.stack != null) {
13728                        pw.println("      Stack:");
13729                        int lastPos = 0;
13730                        for (int pos=0; pos<info.stack.length(); pos++) {
13731                            if (info.stack.charAt(pos) == '\n') {
13732                                pw.print("        ");
13733                                pw.write(info.stack, lastPos, pos-lastPos);
13734                                pw.println();
13735                                lastPos = pos+1;
13736                            }
13737                        }
13738                        if (lastPos < info.stack.length()) {
13739                            pw.print("        ");
13740                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13741                            pw.println();
13742                        }
13743                    }
13744                }
13745            }
13746        }
13747
13748        if (dumpPackage == null) {
13749            pw.println();
13750            needSep = false;
13751            mUserController.dump(pw, dumpAll);
13752        }
13753        if (mHomeProcess != null && (dumpPackage == null
13754                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13755            if (needSep) {
13756                pw.println();
13757                needSep = false;
13758            }
13759            pw.println("  mHomeProcess: " + mHomeProcess);
13760        }
13761        if (mPreviousProcess != null && (dumpPackage == null
13762                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13763            if (needSep) {
13764                pw.println();
13765                needSep = false;
13766            }
13767            pw.println("  mPreviousProcess: " + mPreviousProcess);
13768        }
13769        if (dumpAll) {
13770            StringBuilder sb = new StringBuilder(128);
13771            sb.append("  mPreviousProcessVisibleTime: ");
13772            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13773            pw.println(sb);
13774        }
13775        if (mHeavyWeightProcess != null && (dumpPackage == null
13776                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13777            if (needSep) {
13778                pw.println();
13779                needSep = false;
13780            }
13781            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13782        }
13783        if (dumpPackage == null) {
13784            pw.println("  mConfiguration: " + mConfiguration);
13785        }
13786        if (dumpAll) {
13787            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13788            if (mCompatModePackages.getPackages().size() > 0) {
13789                boolean printed = false;
13790                for (Map.Entry<String, Integer> entry
13791                        : mCompatModePackages.getPackages().entrySet()) {
13792                    String pkg = entry.getKey();
13793                    int mode = entry.getValue();
13794                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13795                        continue;
13796                    }
13797                    if (!printed) {
13798                        pw.println("  mScreenCompatPackages:");
13799                        printed = true;
13800                    }
13801                    pw.print("    "); pw.print(pkg); pw.print(": ");
13802                            pw.print(mode); pw.println();
13803                }
13804            }
13805        }
13806        if (dumpPackage == null) {
13807            pw.println("  mWakefulness="
13808                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13809            pw.println("  mSleepTokens=" + mSleepTokens);
13810            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13811                    + lockScreenShownToString());
13812            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13813            if (mRunningVoice != null) {
13814                pw.println("  mRunningVoice=" + mRunningVoice);
13815                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13816            }
13817        }
13818        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13819                || mOrigWaitForDebugger) {
13820            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13821                    || dumpPackage.equals(mOrigDebugApp)) {
13822                if (needSep) {
13823                    pw.println();
13824                    needSep = false;
13825                }
13826                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13827                        + " mDebugTransient=" + mDebugTransient
13828                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13829            }
13830        }
13831        if (mCurAppTimeTracker != null) {
13832            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13833        }
13834        if (mMemWatchProcesses.getMap().size() > 0) {
13835            pw.println("  Mem watch processes:");
13836            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13837                    = mMemWatchProcesses.getMap();
13838            for (int i=0; i<procs.size(); i++) {
13839                final String proc = procs.keyAt(i);
13840                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13841                for (int j=0; j<uids.size(); j++) {
13842                    if (needSep) {
13843                        pw.println();
13844                        needSep = false;
13845                    }
13846                    StringBuilder sb = new StringBuilder();
13847                    sb.append("    ").append(proc).append('/');
13848                    UserHandle.formatUid(sb, uids.keyAt(j));
13849                    Pair<Long, String> val = uids.valueAt(j);
13850                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13851                    if (val.second != null) {
13852                        sb.append(", report to ").append(val.second);
13853                    }
13854                    pw.println(sb.toString());
13855                }
13856            }
13857            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13858            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13859            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13860                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13861        }
13862        if (mTrackAllocationApp != null) {
13863            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13864                if (needSep) {
13865                    pw.println();
13866                    needSep = false;
13867                }
13868                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13869            }
13870        }
13871        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13872                || mProfileFd != null) {
13873            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13874                if (needSep) {
13875                    pw.println();
13876                    needSep = false;
13877                }
13878                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13879                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13880                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13881                        + mAutoStopProfiler);
13882                pw.println("  mProfileType=" + mProfileType);
13883            }
13884        }
13885        if (dumpPackage == null) {
13886            if (mAlwaysFinishActivities || mController != null) {
13887                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13888                        + " mController=" + mController);
13889            }
13890            if (dumpAll) {
13891                pw.println("  Total persistent processes: " + numPers);
13892                pw.println("  mProcessesReady=" + mProcessesReady
13893                        + " mSystemReady=" + mSystemReady
13894                        + " mBooted=" + mBooted
13895                        + " mFactoryTest=" + mFactoryTest);
13896                pw.println("  mBooting=" + mBooting
13897                        + " mCallFinishBooting=" + mCallFinishBooting
13898                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13899                pw.print("  mLastPowerCheckRealtime=");
13900                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13901                        pw.println("");
13902                pw.print("  mLastPowerCheckUptime=");
13903                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13904                        pw.println("");
13905                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13906                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13907                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13908                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13909                        + " (" + mLruProcesses.size() + " total)"
13910                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13911                        + " mNumServiceProcs=" + mNumServiceProcs
13912                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13913                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13914                        + " mLastMemoryLevel" + mLastMemoryLevel
13915                        + " mLastNumProcesses" + mLastNumProcesses);
13916                long now = SystemClock.uptimeMillis();
13917                pw.print("  mLastIdleTime=");
13918                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13919                        pw.print(" mLowRamSinceLastIdle=");
13920                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13921                        pw.println();
13922            }
13923        }
13924
13925        if (!printedAnything) {
13926            pw.println("  (nothing)");
13927        }
13928    }
13929
13930    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13931            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13932        if (mProcessesToGc.size() > 0) {
13933            boolean printed = false;
13934            long now = SystemClock.uptimeMillis();
13935            for (int i=0; i<mProcessesToGc.size(); i++) {
13936                ProcessRecord proc = mProcessesToGc.get(i);
13937                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13938                    continue;
13939                }
13940                if (!printed) {
13941                    if (needSep) pw.println();
13942                    needSep = true;
13943                    pw.println("  Processes that are waiting to GC:");
13944                    printed = true;
13945                }
13946                pw.print("    Process "); pw.println(proc);
13947                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13948                        pw.print(", last gced=");
13949                        pw.print(now-proc.lastRequestedGc);
13950                        pw.print(" ms ago, last lowMem=");
13951                        pw.print(now-proc.lastLowMemory);
13952                        pw.println(" ms ago");
13953
13954            }
13955        }
13956        return needSep;
13957    }
13958
13959    void printOomLevel(PrintWriter pw, String name, int adj) {
13960        pw.print("    ");
13961        if (adj >= 0) {
13962            pw.print(' ');
13963            if (adj < 10) pw.print(' ');
13964        } else {
13965            if (adj > -10) pw.print(' ');
13966        }
13967        pw.print(adj);
13968        pw.print(": ");
13969        pw.print(name);
13970        pw.print(" (");
13971        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
13972        pw.println(")");
13973    }
13974
13975    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13976            int opti, boolean dumpAll) {
13977        boolean needSep = false;
13978
13979        if (mLruProcesses.size() > 0) {
13980            if (needSep) pw.println();
13981            needSep = true;
13982            pw.println("  OOM levels:");
13983            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13984            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13985            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13986            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13987            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13988            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13989            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13990            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13991            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13992            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13993            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13994            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13995            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13996            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13997
13998            if (needSep) pw.println();
13999            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14000                    pw.print(" total, non-act at ");
14001                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14002                    pw.print(", non-svc at ");
14003                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14004                    pw.println("):");
14005            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14006            needSep = true;
14007        }
14008
14009        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14010
14011        pw.println();
14012        pw.println("  mHomeProcess: " + mHomeProcess);
14013        pw.println("  mPreviousProcess: " + mPreviousProcess);
14014        if (mHeavyWeightProcess != null) {
14015            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14016        }
14017
14018        return true;
14019    }
14020
14021    /**
14022     * There are three ways to call this:
14023     *  - no provider specified: dump all the providers
14024     *  - a flattened component name that matched an existing provider was specified as the
14025     *    first arg: dump that one provider
14026     *  - the first arg isn't the flattened component name of an existing provider:
14027     *    dump all providers whose component contains the first arg as a substring
14028     */
14029    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14030            int opti, boolean dumpAll) {
14031        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14032    }
14033
14034    static class ItemMatcher {
14035        ArrayList<ComponentName> components;
14036        ArrayList<String> strings;
14037        ArrayList<Integer> objects;
14038        boolean all;
14039
14040        ItemMatcher() {
14041            all = true;
14042        }
14043
14044        void build(String name) {
14045            ComponentName componentName = ComponentName.unflattenFromString(name);
14046            if (componentName != null) {
14047                if (components == null) {
14048                    components = new ArrayList<ComponentName>();
14049                }
14050                components.add(componentName);
14051                all = false;
14052            } else {
14053                int objectId = 0;
14054                // Not a '/' separated full component name; maybe an object ID?
14055                try {
14056                    objectId = Integer.parseInt(name, 16);
14057                    if (objects == null) {
14058                        objects = new ArrayList<Integer>();
14059                    }
14060                    objects.add(objectId);
14061                    all = false;
14062                } catch (RuntimeException e) {
14063                    // Not an integer; just do string match.
14064                    if (strings == null) {
14065                        strings = new ArrayList<String>();
14066                    }
14067                    strings.add(name);
14068                    all = false;
14069                }
14070            }
14071        }
14072
14073        int build(String[] args, int opti) {
14074            for (; opti<args.length; opti++) {
14075                String name = args[opti];
14076                if ("--".equals(name)) {
14077                    return opti+1;
14078                }
14079                build(name);
14080            }
14081            return opti;
14082        }
14083
14084        boolean match(Object object, ComponentName comp) {
14085            if (all) {
14086                return true;
14087            }
14088            if (components != null) {
14089                for (int i=0; i<components.size(); i++) {
14090                    if (components.get(i).equals(comp)) {
14091                        return true;
14092                    }
14093                }
14094            }
14095            if (objects != null) {
14096                for (int i=0; i<objects.size(); i++) {
14097                    if (System.identityHashCode(object) == objects.get(i)) {
14098                        return true;
14099                    }
14100                }
14101            }
14102            if (strings != null) {
14103                String flat = comp.flattenToString();
14104                for (int i=0; i<strings.size(); i++) {
14105                    if (flat.contains(strings.get(i))) {
14106                        return true;
14107                    }
14108                }
14109            }
14110            return false;
14111        }
14112    }
14113
14114    /**
14115     * There are three things that cmd can be:
14116     *  - a flattened component name that matches an existing activity
14117     *  - the cmd arg isn't the flattened component name of an existing activity:
14118     *    dump all activity whose component contains the cmd as a substring
14119     *  - A hex number of the ActivityRecord object instance.
14120     */
14121    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14122            int opti, boolean dumpAll) {
14123        ArrayList<ActivityRecord> activities;
14124
14125        synchronized (this) {
14126            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14127        }
14128
14129        if (activities.size() <= 0) {
14130            return false;
14131        }
14132
14133        String[] newArgs = new String[args.length - opti];
14134        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14135
14136        TaskRecord lastTask = null;
14137        boolean needSep = false;
14138        for (int i=activities.size()-1; i>=0; i--) {
14139            ActivityRecord r = activities.get(i);
14140            if (needSep) {
14141                pw.println();
14142            }
14143            needSep = true;
14144            synchronized (this) {
14145                if (lastTask != r.task) {
14146                    lastTask = r.task;
14147                    pw.print("TASK "); pw.print(lastTask.affinity);
14148                            pw.print(" id="); pw.println(lastTask.taskId);
14149                    if (dumpAll) {
14150                        lastTask.dump(pw, "  ");
14151                    }
14152                }
14153            }
14154            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14155        }
14156        return true;
14157    }
14158
14159    /**
14160     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14161     * there is a thread associated with the activity.
14162     */
14163    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14164            final ActivityRecord r, String[] args, boolean dumpAll) {
14165        String innerPrefix = prefix + "  ";
14166        synchronized (this) {
14167            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14168                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14169                    pw.print(" pid=");
14170                    if (r.app != null) pw.println(r.app.pid);
14171                    else pw.println("(not running)");
14172            if (dumpAll) {
14173                r.dump(pw, innerPrefix);
14174            }
14175        }
14176        if (r.app != null && r.app.thread != null) {
14177            // flush anything that is already in the PrintWriter since the thread is going
14178            // to write to the file descriptor directly
14179            pw.flush();
14180            try {
14181                TransferPipe tp = new TransferPipe();
14182                try {
14183                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14184                            r.appToken, innerPrefix, args);
14185                    tp.go(fd);
14186                } finally {
14187                    tp.kill();
14188                }
14189            } catch (IOException e) {
14190                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14191            } catch (RemoteException e) {
14192                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14193            }
14194        }
14195    }
14196
14197    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14198            int opti, boolean dumpAll, String dumpPackage) {
14199        boolean needSep = false;
14200        boolean onlyHistory = false;
14201        boolean printedAnything = false;
14202
14203        if ("history".equals(dumpPackage)) {
14204            if (opti < args.length && "-s".equals(args[opti])) {
14205                dumpAll = false;
14206            }
14207            onlyHistory = true;
14208            dumpPackage = null;
14209        }
14210
14211        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14212        if (!onlyHistory && dumpAll) {
14213            if (mRegisteredReceivers.size() > 0) {
14214                boolean printed = false;
14215                Iterator it = mRegisteredReceivers.values().iterator();
14216                while (it.hasNext()) {
14217                    ReceiverList r = (ReceiverList)it.next();
14218                    if (dumpPackage != null && (r.app == null ||
14219                            !dumpPackage.equals(r.app.info.packageName))) {
14220                        continue;
14221                    }
14222                    if (!printed) {
14223                        pw.println("  Registered Receivers:");
14224                        needSep = true;
14225                        printed = true;
14226                        printedAnything = true;
14227                    }
14228                    pw.print("  * "); pw.println(r);
14229                    r.dump(pw, "    ");
14230                }
14231            }
14232
14233            if (mReceiverResolver.dump(pw, needSep ?
14234                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14235                    "    ", dumpPackage, false, false)) {
14236                needSep = true;
14237                printedAnything = true;
14238            }
14239        }
14240
14241        for (BroadcastQueue q : mBroadcastQueues) {
14242            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14243            printedAnything |= needSep;
14244        }
14245
14246        needSep = true;
14247
14248        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14249            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14250                if (needSep) {
14251                    pw.println();
14252                }
14253                needSep = true;
14254                printedAnything = true;
14255                pw.print("  Sticky broadcasts for user ");
14256                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14257                StringBuilder sb = new StringBuilder(128);
14258                for (Map.Entry<String, ArrayList<Intent>> ent
14259                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14260                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14261                    if (dumpAll) {
14262                        pw.println(":");
14263                        ArrayList<Intent> intents = ent.getValue();
14264                        final int N = intents.size();
14265                        for (int i=0; i<N; i++) {
14266                            sb.setLength(0);
14267                            sb.append("    Intent: ");
14268                            intents.get(i).toShortString(sb, false, true, false, false);
14269                            pw.println(sb.toString());
14270                            Bundle bundle = intents.get(i).getExtras();
14271                            if (bundle != null) {
14272                                pw.print("      ");
14273                                pw.println(bundle.toString());
14274                            }
14275                        }
14276                    } else {
14277                        pw.println("");
14278                    }
14279                }
14280            }
14281        }
14282
14283        if (!onlyHistory && dumpAll) {
14284            pw.println();
14285            for (BroadcastQueue queue : mBroadcastQueues) {
14286                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14287                        + queue.mBroadcastsScheduled);
14288            }
14289            pw.println("  mHandler:");
14290            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14291            needSep = true;
14292            printedAnything = true;
14293        }
14294
14295        if (!printedAnything) {
14296            pw.println("  (nothing)");
14297        }
14298    }
14299
14300    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14301            int opti, boolean dumpAll, String dumpPackage) {
14302        boolean needSep;
14303        boolean printedAnything = false;
14304
14305        ItemMatcher matcher = new ItemMatcher();
14306        matcher.build(args, opti);
14307
14308        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14309
14310        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14311        printedAnything |= needSep;
14312
14313        if (mLaunchingProviders.size() > 0) {
14314            boolean printed = false;
14315            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14316                ContentProviderRecord r = mLaunchingProviders.get(i);
14317                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14318                    continue;
14319                }
14320                if (!printed) {
14321                    if (needSep) pw.println();
14322                    needSep = true;
14323                    pw.println("  Launching content providers:");
14324                    printed = true;
14325                    printedAnything = true;
14326                }
14327                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14328                        pw.println(r);
14329            }
14330        }
14331
14332        if (!printedAnything) {
14333            pw.println("  (nothing)");
14334        }
14335    }
14336
14337    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14338            int opti, boolean dumpAll, String dumpPackage) {
14339        boolean needSep = false;
14340        boolean printedAnything = false;
14341
14342        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14343
14344        if (mGrantedUriPermissions.size() > 0) {
14345            boolean printed = false;
14346            int dumpUid = -2;
14347            if (dumpPackage != null) {
14348                try {
14349                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14350                } catch (NameNotFoundException e) {
14351                    dumpUid = -1;
14352                }
14353            }
14354            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14355                int uid = mGrantedUriPermissions.keyAt(i);
14356                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14357                    continue;
14358                }
14359                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14360                if (!printed) {
14361                    if (needSep) pw.println();
14362                    needSep = true;
14363                    pw.println("  Granted Uri Permissions:");
14364                    printed = true;
14365                    printedAnything = true;
14366                }
14367                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14368                for (UriPermission perm : perms.values()) {
14369                    pw.print("    "); pw.println(perm);
14370                    if (dumpAll) {
14371                        perm.dump(pw, "      ");
14372                    }
14373                }
14374            }
14375        }
14376
14377        if (!printedAnything) {
14378            pw.println("  (nothing)");
14379        }
14380    }
14381
14382    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14383            int opti, boolean dumpAll, String dumpPackage) {
14384        boolean printed = false;
14385
14386        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14387
14388        if (mIntentSenderRecords.size() > 0) {
14389            Iterator<WeakReference<PendingIntentRecord>> it
14390                    = mIntentSenderRecords.values().iterator();
14391            while (it.hasNext()) {
14392                WeakReference<PendingIntentRecord> ref = it.next();
14393                PendingIntentRecord rec = ref != null ? ref.get(): null;
14394                if (dumpPackage != null && (rec == null
14395                        || !dumpPackage.equals(rec.key.packageName))) {
14396                    continue;
14397                }
14398                printed = true;
14399                if (rec != null) {
14400                    pw.print("  * "); pw.println(rec);
14401                    if (dumpAll) {
14402                        rec.dump(pw, "    ");
14403                    }
14404                } else {
14405                    pw.print("  * "); pw.println(ref);
14406                }
14407            }
14408        }
14409
14410        if (!printed) {
14411            pw.println("  (nothing)");
14412        }
14413    }
14414
14415    private static final int dumpProcessList(PrintWriter pw,
14416            ActivityManagerService service, List list,
14417            String prefix, String normalLabel, String persistentLabel,
14418            String dumpPackage) {
14419        int numPers = 0;
14420        final int N = list.size()-1;
14421        for (int i=N; i>=0; i--) {
14422            ProcessRecord r = (ProcessRecord)list.get(i);
14423            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14424                continue;
14425            }
14426            pw.println(String.format("%s%s #%2d: %s",
14427                    prefix, (r.persistent ? persistentLabel : normalLabel),
14428                    i, r.toString()));
14429            if (r.persistent) {
14430                numPers++;
14431            }
14432        }
14433        return numPers;
14434    }
14435
14436    private static final boolean dumpProcessOomList(PrintWriter pw,
14437            ActivityManagerService service, List<ProcessRecord> origList,
14438            String prefix, String normalLabel, String persistentLabel,
14439            boolean inclDetails, String dumpPackage) {
14440
14441        ArrayList<Pair<ProcessRecord, Integer>> list
14442                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14443        for (int i=0; i<origList.size(); i++) {
14444            ProcessRecord r = origList.get(i);
14445            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14446                continue;
14447            }
14448            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14449        }
14450
14451        if (list.size() <= 0) {
14452            return false;
14453        }
14454
14455        Comparator<Pair<ProcessRecord, Integer>> comparator
14456                = new Comparator<Pair<ProcessRecord, Integer>>() {
14457            @Override
14458            public int compare(Pair<ProcessRecord, Integer> object1,
14459                    Pair<ProcessRecord, Integer> object2) {
14460                if (object1.first.setAdj != object2.first.setAdj) {
14461                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14462                }
14463                if (object1.second.intValue() != object2.second.intValue()) {
14464                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14465                }
14466                return 0;
14467            }
14468        };
14469
14470        Collections.sort(list, comparator);
14471
14472        final long curRealtime = SystemClock.elapsedRealtime();
14473        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14474        final long curUptime = SystemClock.uptimeMillis();
14475        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14476
14477        for (int i=list.size()-1; i>=0; i--) {
14478            ProcessRecord r = list.get(i).first;
14479            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14480            char schedGroup;
14481            switch (r.setSchedGroup) {
14482                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14483                    schedGroup = 'B';
14484                    break;
14485                case Process.THREAD_GROUP_DEFAULT:
14486                    schedGroup = 'F';
14487                    break;
14488                default:
14489                    schedGroup = '?';
14490                    break;
14491            }
14492            char foreground;
14493            if (r.foregroundActivities) {
14494                foreground = 'A';
14495            } else if (r.foregroundServices) {
14496                foreground = 'S';
14497            } else {
14498                foreground = ' ';
14499            }
14500            String procState = ProcessList.makeProcStateString(r.curProcState);
14501            pw.print(prefix);
14502            pw.print(r.persistent ? persistentLabel : normalLabel);
14503            pw.print(" #");
14504            int num = (origList.size()-1)-list.get(i).second;
14505            if (num < 10) pw.print(' ');
14506            pw.print(num);
14507            pw.print(": ");
14508            pw.print(oomAdj);
14509            pw.print(' ');
14510            pw.print(schedGroup);
14511            pw.print('/');
14512            pw.print(foreground);
14513            pw.print('/');
14514            pw.print(procState);
14515            pw.print(" trm:");
14516            if (r.trimMemoryLevel < 10) pw.print(' ');
14517            pw.print(r.trimMemoryLevel);
14518            pw.print(' ');
14519            pw.print(r.toShortString());
14520            pw.print(" (");
14521            pw.print(r.adjType);
14522            pw.println(')');
14523            if (r.adjSource != null || r.adjTarget != null) {
14524                pw.print(prefix);
14525                pw.print("    ");
14526                if (r.adjTarget instanceof ComponentName) {
14527                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14528                } else if (r.adjTarget != null) {
14529                    pw.print(r.adjTarget.toString());
14530                } else {
14531                    pw.print("{null}");
14532                }
14533                pw.print("<=");
14534                if (r.adjSource instanceof ProcessRecord) {
14535                    pw.print("Proc{");
14536                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14537                    pw.println("}");
14538                } else if (r.adjSource != null) {
14539                    pw.println(r.adjSource.toString());
14540                } else {
14541                    pw.println("{null}");
14542                }
14543            }
14544            if (inclDetails) {
14545                pw.print(prefix);
14546                pw.print("    ");
14547                pw.print("oom: max="); pw.print(r.maxAdj);
14548                pw.print(" curRaw="); pw.print(r.curRawAdj);
14549                pw.print(" setRaw="); pw.print(r.setRawAdj);
14550                pw.print(" cur="); pw.print(r.curAdj);
14551                pw.print(" set="); pw.println(r.setAdj);
14552                pw.print(prefix);
14553                pw.print("    ");
14554                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14555                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14556                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14557                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14558                pw.println();
14559                pw.print(prefix);
14560                pw.print("    ");
14561                pw.print("cached="); pw.print(r.cached);
14562                pw.print(" empty="); pw.print(r.empty);
14563                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14564
14565                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14566                    if (r.lastWakeTime != 0) {
14567                        long wtime;
14568                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14569                        synchronized (stats) {
14570                            wtime = stats.getProcessWakeTime(r.info.uid,
14571                                    r.pid, curRealtime);
14572                        }
14573                        long timeUsed = wtime - r.lastWakeTime;
14574                        pw.print(prefix);
14575                        pw.print("    ");
14576                        pw.print("keep awake over ");
14577                        TimeUtils.formatDuration(realtimeSince, pw);
14578                        pw.print(" used ");
14579                        TimeUtils.formatDuration(timeUsed, pw);
14580                        pw.print(" (");
14581                        pw.print((timeUsed*100)/realtimeSince);
14582                        pw.println("%)");
14583                    }
14584                    if (r.lastCpuTime != 0) {
14585                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14586                        pw.print(prefix);
14587                        pw.print("    ");
14588                        pw.print("run cpu over ");
14589                        TimeUtils.formatDuration(uptimeSince, pw);
14590                        pw.print(" used ");
14591                        TimeUtils.formatDuration(timeUsed, pw);
14592                        pw.print(" (");
14593                        pw.print((timeUsed*100)/uptimeSince);
14594                        pw.println("%)");
14595                    }
14596                }
14597            }
14598        }
14599        return true;
14600    }
14601
14602    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14603            String[] args) {
14604        ArrayList<ProcessRecord> procs;
14605        synchronized (this) {
14606            if (args != null && args.length > start
14607                    && args[start].charAt(0) != '-') {
14608                procs = new ArrayList<ProcessRecord>();
14609                int pid = -1;
14610                try {
14611                    pid = Integer.parseInt(args[start]);
14612                } catch (NumberFormatException e) {
14613                }
14614                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14615                    ProcessRecord proc = mLruProcesses.get(i);
14616                    if (proc.pid == pid) {
14617                        procs.add(proc);
14618                    } else if (allPkgs && proc.pkgList != null
14619                            && proc.pkgList.containsKey(args[start])) {
14620                        procs.add(proc);
14621                    } else if (proc.processName.equals(args[start])) {
14622                        procs.add(proc);
14623                    }
14624                }
14625                if (procs.size() <= 0) {
14626                    return null;
14627                }
14628            } else {
14629                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14630            }
14631        }
14632        return procs;
14633    }
14634
14635    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14636            PrintWriter pw, String[] args) {
14637        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14638        if (procs == null) {
14639            pw.println("No process found for: " + args[0]);
14640            return;
14641        }
14642
14643        long uptime = SystemClock.uptimeMillis();
14644        long realtime = SystemClock.elapsedRealtime();
14645        pw.println("Applications Graphics Acceleration Info:");
14646        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14647
14648        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14649            ProcessRecord r = procs.get(i);
14650            if (r.thread != null) {
14651                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14652                pw.flush();
14653                try {
14654                    TransferPipe tp = new TransferPipe();
14655                    try {
14656                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14657                        tp.go(fd);
14658                    } finally {
14659                        tp.kill();
14660                    }
14661                } catch (IOException e) {
14662                    pw.println("Failure while dumping the app: " + r);
14663                    pw.flush();
14664                } catch (RemoteException e) {
14665                    pw.println("Got a RemoteException while dumping the app " + r);
14666                    pw.flush();
14667                }
14668            }
14669        }
14670    }
14671
14672    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14673        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14674        if (procs == null) {
14675            pw.println("No process found for: " + args[0]);
14676            return;
14677        }
14678
14679        pw.println("Applications Database Info:");
14680
14681        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14682            ProcessRecord r = procs.get(i);
14683            if (r.thread != null) {
14684                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14685                pw.flush();
14686                try {
14687                    TransferPipe tp = new TransferPipe();
14688                    try {
14689                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14690                        tp.go(fd);
14691                    } finally {
14692                        tp.kill();
14693                    }
14694                } catch (IOException e) {
14695                    pw.println("Failure while dumping the app: " + r);
14696                    pw.flush();
14697                } catch (RemoteException e) {
14698                    pw.println("Got a RemoteException while dumping the app " + r);
14699                    pw.flush();
14700                }
14701            }
14702        }
14703    }
14704
14705    final static class MemItem {
14706        final boolean isProc;
14707        final String label;
14708        final String shortLabel;
14709        final long pss;
14710        final int id;
14711        final boolean hasActivities;
14712        ArrayList<MemItem> subitems;
14713
14714        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14715                boolean _hasActivities) {
14716            isProc = true;
14717            label = _label;
14718            shortLabel = _shortLabel;
14719            pss = _pss;
14720            id = _id;
14721            hasActivities = _hasActivities;
14722        }
14723
14724        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14725            isProc = false;
14726            label = _label;
14727            shortLabel = _shortLabel;
14728            pss = _pss;
14729            id = _id;
14730            hasActivities = false;
14731        }
14732    }
14733
14734    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14735            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14736        if (sort && !isCompact) {
14737            Collections.sort(items, new Comparator<MemItem>() {
14738                @Override
14739                public int compare(MemItem lhs, MemItem rhs) {
14740                    if (lhs.pss < rhs.pss) {
14741                        return 1;
14742                    } else if (lhs.pss > rhs.pss) {
14743                        return -1;
14744                    }
14745                    return 0;
14746                }
14747            });
14748        }
14749
14750        for (int i=0; i<items.size(); i++) {
14751            MemItem mi = items.get(i);
14752            if (!isCompact) {
14753                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14754            } else if (mi.isProc) {
14755                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14756                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14757                pw.println(mi.hasActivities ? ",a" : ",e");
14758            } else {
14759                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14760                pw.println(mi.pss);
14761            }
14762            if (mi.subitems != null) {
14763                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14764                        true, isCompact);
14765            }
14766        }
14767    }
14768
14769    // These are in KB.
14770    static final long[] DUMP_MEM_BUCKETS = new long[] {
14771        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14772        120*1024, 160*1024, 200*1024,
14773        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14774        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14775    };
14776
14777    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14778            boolean stackLike) {
14779        int start = label.lastIndexOf('.');
14780        if (start >= 0) start++;
14781        else start = 0;
14782        int end = label.length();
14783        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14784            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14785                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14786                out.append(bucket);
14787                out.append(stackLike ? "MB." : "MB ");
14788                out.append(label, start, end);
14789                return;
14790            }
14791        }
14792        out.append(memKB/1024);
14793        out.append(stackLike ? "MB." : "MB ");
14794        out.append(label, start, end);
14795    }
14796
14797    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14798            ProcessList.NATIVE_ADJ,
14799            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14800            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14801            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14802            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14803            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14804            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14805    };
14806    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14807            "Native",
14808            "System", "Persistent", "Persistent Service", "Foreground",
14809            "Visible", "Perceptible",
14810            "Heavy Weight", "Backup",
14811            "A Services", "Home",
14812            "Previous", "B Services", "Cached"
14813    };
14814    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14815            "native",
14816            "sys", "pers", "persvc", "fore",
14817            "vis", "percept",
14818            "heavy", "backup",
14819            "servicea", "home",
14820            "prev", "serviceb", "cached"
14821    };
14822
14823    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14824            long realtime, boolean isCheckinRequest, boolean isCompact) {
14825        if (isCheckinRequest || isCompact) {
14826            // short checkin version
14827            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14828        } else {
14829            pw.println("Applications Memory Usage (in Kilobytes):");
14830            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14831        }
14832    }
14833
14834    private static final int KSM_SHARED = 0;
14835    private static final int KSM_SHARING = 1;
14836    private static final int KSM_UNSHARED = 2;
14837    private static final int KSM_VOLATILE = 3;
14838
14839    private final long[] getKsmInfo() {
14840        long[] longOut = new long[4];
14841        final int[] SINGLE_LONG_FORMAT = new int[] {
14842            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14843        };
14844        long[] longTmp = new long[1];
14845        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14846                SINGLE_LONG_FORMAT, null, longTmp, null);
14847        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14848        longTmp[0] = 0;
14849        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14850                SINGLE_LONG_FORMAT, null, longTmp, null);
14851        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14852        longTmp[0] = 0;
14853        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14854                SINGLE_LONG_FORMAT, null, longTmp, null);
14855        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14856        longTmp[0] = 0;
14857        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14858                SINGLE_LONG_FORMAT, null, longTmp, null);
14859        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14860        return longOut;
14861    }
14862
14863    private static String stringifySize(long size, int order) {
14864        Locale locale = Locale.US;
14865        switch (order) {
14866            case 1:
14867                return String.format(locale, "%,13d", size);
14868            case 1024:
14869                return String.format(locale, "%,9dK", size / 1024);
14870            case 1024 * 1024:
14871                return String.format(locale, "%,5dM", size / 1024 / 1024);
14872            case 1024 * 1024 * 1024:
14873                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
14874            default:
14875                throw new IllegalArgumentException("Invalid size order");
14876        }
14877    }
14878
14879    private static String stringifyKBSize(long size) {
14880        return stringifySize(size * 1024, 1024);
14881    }
14882
14883    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14884            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14885        boolean dumpDetails = false;
14886        boolean dumpFullDetails = false;
14887        boolean dumpDalvik = false;
14888        boolean dumpSummaryOnly = false;
14889        boolean oomOnly = false;
14890        boolean isCompact = false;
14891        boolean localOnly = false;
14892        boolean packages = false;
14893
14894        int opti = 0;
14895        while (opti < args.length) {
14896            String opt = args[opti];
14897            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14898                break;
14899            }
14900            opti++;
14901            if ("-a".equals(opt)) {
14902                dumpDetails = true;
14903                dumpFullDetails = true;
14904                dumpDalvik = true;
14905            } else if ("-d".equals(opt)) {
14906                dumpDalvik = true;
14907            } else if ("-c".equals(opt)) {
14908                isCompact = true;
14909            } else if ("-s".equals(opt)) {
14910                dumpDetails = true;
14911                dumpSummaryOnly = true;
14912            } else if ("--oom".equals(opt)) {
14913                oomOnly = true;
14914            } else if ("--local".equals(opt)) {
14915                localOnly = true;
14916            } else if ("--package".equals(opt)) {
14917                packages = true;
14918            } else if ("-h".equals(opt)) {
14919                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14920                pw.println("  -a: include all available information for each process.");
14921                pw.println("  -d: include dalvik details.");
14922                pw.println("  -c: dump in a compact machine-parseable representation.");
14923                pw.println("  -s: dump only summary of application memory usage.");
14924                pw.println("  --oom: only show processes organized by oom adj.");
14925                pw.println("  --local: only collect details locally, don't call process.");
14926                pw.println("  --package: interpret process arg as package, dumping all");
14927                pw.println("             processes that have loaded that package.");
14928                pw.println("If [process] is specified it can be the name or ");
14929                pw.println("pid of a specific process to dump.");
14930                return;
14931            } else {
14932                pw.println("Unknown argument: " + opt + "; use -h for help");
14933            }
14934        }
14935
14936        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14937        long uptime = SystemClock.uptimeMillis();
14938        long realtime = SystemClock.elapsedRealtime();
14939        final long[] tmpLong = new long[1];
14940
14941        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14942        if (procs == null) {
14943            // No Java processes.  Maybe they want to print a native process.
14944            if (args != null && args.length > opti
14945                    && args[opti].charAt(0) != '-') {
14946                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14947                        = new ArrayList<ProcessCpuTracker.Stats>();
14948                updateCpuStatsNow();
14949                int findPid = -1;
14950                try {
14951                    findPid = Integer.parseInt(args[opti]);
14952                } catch (NumberFormatException e) {
14953                }
14954                synchronized (mProcessCpuTracker) {
14955                    final int N = mProcessCpuTracker.countStats();
14956                    for (int i=0; i<N; i++) {
14957                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14958                        if (st.pid == findPid || (st.baseName != null
14959                                && st.baseName.equals(args[opti]))) {
14960                            nativeProcs.add(st);
14961                        }
14962                    }
14963                }
14964                if (nativeProcs.size() > 0) {
14965                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14966                            isCompact);
14967                    Debug.MemoryInfo mi = null;
14968                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14969                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14970                        final int pid = r.pid;
14971                        if (!isCheckinRequest && dumpDetails) {
14972                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14973                        }
14974                        if (mi == null) {
14975                            mi = new Debug.MemoryInfo();
14976                        }
14977                        if (dumpDetails || (!brief && !oomOnly)) {
14978                            Debug.getMemoryInfo(pid, mi);
14979                        } else {
14980                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14981                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14982                        }
14983                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14984                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14985                        if (isCheckinRequest) {
14986                            pw.println();
14987                        }
14988                    }
14989                    return;
14990                }
14991            }
14992            pw.println("No process found for: " + args[opti]);
14993            return;
14994        }
14995
14996        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14997            dumpDetails = true;
14998        }
14999
15000        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15001
15002        String[] innerArgs = new String[args.length-opti];
15003        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15004
15005        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15006        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15007        long nativePss = 0;
15008        long dalvikPss = 0;
15009        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15010                EmptyArray.LONG;
15011        long otherPss = 0;
15012        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15013
15014        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15015        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15016                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15017
15018        long totalPss = 0;
15019        long cachedPss = 0;
15020
15021        Debug.MemoryInfo mi = null;
15022        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15023            final ProcessRecord r = procs.get(i);
15024            final IApplicationThread thread;
15025            final int pid;
15026            final int oomAdj;
15027            final boolean hasActivities;
15028            synchronized (this) {
15029                thread = r.thread;
15030                pid = r.pid;
15031                oomAdj = r.getSetAdjWithServices();
15032                hasActivities = r.activities.size() > 0;
15033            }
15034            if (thread != null) {
15035                if (!isCheckinRequest && dumpDetails) {
15036                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15037                }
15038                if (mi == null) {
15039                    mi = new Debug.MemoryInfo();
15040                }
15041                if (dumpDetails || (!brief && !oomOnly)) {
15042                    Debug.getMemoryInfo(pid, mi);
15043                } else {
15044                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15045                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15046                }
15047                if (dumpDetails) {
15048                    if (localOnly) {
15049                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15050                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15051                        if (isCheckinRequest) {
15052                            pw.println();
15053                        }
15054                    } else {
15055                        try {
15056                            pw.flush();
15057                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15058                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15059                        } catch (RemoteException e) {
15060                            if (!isCheckinRequest) {
15061                                pw.println("Got RemoteException!");
15062                                pw.flush();
15063                            }
15064                        }
15065                    }
15066                }
15067
15068                final long myTotalPss = mi.getTotalPss();
15069                final long myTotalUss = mi.getTotalUss();
15070
15071                synchronized (this) {
15072                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15073                        // Record this for posterity if the process has been stable.
15074                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15075                    }
15076                }
15077
15078                if (!isCheckinRequest && mi != null) {
15079                    totalPss += myTotalPss;
15080                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15081                            (hasActivities ? " / activities)" : ")"),
15082                            r.processName, myTotalPss, pid, hasActivities);
15083                    procMems.add(pssItem);
15084                    procMemsMap.put(pid, pssItem);
15085
15086                    nativePss += mi.nativePss;
15087                    dalvikPss += mi.dalvikPss;
15088                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15089                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15090                    }
15091                    otherPss += mi.otherPss;
15092                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15093                        long mem = mi.getOtherPss(j);
15094                        miscPss[j] += mem;
15095                        otherPss -= mem;
15096                    }
15097
15098                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15099                        cachedPss += myTotalPss;
15100                    }
15101
15102                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15103                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15104                                || oomIndex == (oomPss.length-1)) {
15105                            oomPss[oomIndex] += myTotalPss;
15106                            if (oomProcs[oomIndex] == null) {
15107                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15108                            }
15109                            oomProcs[oomIndex].add(pssItem);
15110                            break;
15111                        }
15112                    }
15113                }
15114            }
15115        }
15116
15117        long nativeProcTotalPss = 0;
15118
15119        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15120            // If we are showing aggregations, also look for native processes to
15121            // include so that our aggregations are more accurate.
15122            updateCpuStatsNow();
15123            mi = null;
15124            synchronized (mProcessCpuTracker) {
15125                final int N = mProcessCpuTracker.countStats();
15126                for (int i=0; i<N; i++) {
15127                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15128                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15129                        if (mi == null) {
15130                            mi = new Debug.MemoryInfo();
15131                        }
15132                        if (!brief && !oomOnly) {
15133                            Debug.getMemoryInfo(st.pid, mi);
15134                        } else {
15135                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15136                            mi.nativePrivateDirty = (int)tmpLong[0];
15137                        }
15138
15139                        final long myTotalPss = mi.getTotalPss();
15140                        totalPss += myTotalPss;
15141                        nativeProcTotalPss += myTotalPss;
15142
15143                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15144                                st.name, myTotalPss, st.pid, false);
15145                        procMems.add(pssItem);
15146
15147                        nativePss += mi.nativePss;
15148                        dalvikPss += mi.dalvikPss;
15149                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15150                            dalvikSubitemPss[j] += mi.getOtherPss(
15151                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15152                        }
15153                        otherPss += mi.otherPss;
15154                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15155                            long mem = mi.getOtherPss(j);
15156                            miscPss[j] += mem;
15157                            otherPss -= mem;
15158                        }
15159                        oomPss[0] += myTotalPss;
15160                        if (oomProcs[0] == null) {
15161                            oomProcs[0] = new ArrayList<MemItem>();
15162                        }
15163                        oomProcs[0].add(pssItem);
15164                    }
15165                }
15166            }
15167
15168            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15169
15170            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15171            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15172            if (dalvikSubitemPss.length > 0) {
15173                dalvikItem.subitems = new ArrayList<MemItem>();
15174                for (int j=0; j<dalvikSubitemPss.length; j++) {
15175                    final String name = Debug.MemoryInfo.getOtherLabel(
15176                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15177                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15178                }
15179            }
15180            catMems.add(dalvikItem);
15181            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15182            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15183                String label = Debug.MemoryInfo.getOtherLabel(j);
15184                catMems.add(new MemItem(label, label, miscPss[j], j));
15185            }
15186
15187            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15188            for (int j=0; j<oomPss.length; j++) {
15189                if (oomPss[j] != 0) {
15190                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15191                            : DUMP_MEM_OOM_LABEL[j];
15192                    MemItem item = new MemItem(label, label, oomPss[j],
15193                            DUMP_MEM_OOM_ADJ[j]);
15194                    item.subitems = oomProcs[j];
15195                    oomMems.add(item);
15196                }
15197            }
15198
15199            if (!brief && !oomOnly && !isCompact) {
15200                pw.println();
15201                pw.println("Total PSS by process:");
15202                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15203                pw.println();
15204            }
15205            if (!isCompact) {
15206                pw.println("Total PSS by OOM adjustment:");
15207            }
15208            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15209            if (!brief && !oomOnly) {
15210                PrintWriter out = categoryPw != null ? categoryPw : pw;
15211                if (!isCompact) {
15212                    out.println();
15213                    out.println("Total PSS by category:");
15214                }
15215                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15216            }
15217            if (!isCompact) {
15218                pw.println();
15219            }
15220            MemInfoReader memInfo = new MemInfoReader();
15221            memInfo.readMemInfo();
15222            if (nativeProcTotalPss > 0) {
15223                synchronized (this) {
15224                    final long cachedKb = memInfo.getCachedSizeKb();
15225                    final long freeKb = memInfo.getFreeSizeKb();
15226                    final long zramKb = memInfo.getZramTotalSizeKb();
15227                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15228                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15229                            kernelKb*1024, nativeProcTotalPss*1024);
15230                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15231                            nativeProcTotalPss);
15232                }
15233            }
15234            if (!brief) {
15235                if (!isCompact) {
15236                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15237                    pw.print(" (status ");
15238                    switch (mLastMemoryLevel) {
15239                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15240                            pw.println("normal)");
15241                            break;
15242                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15243                            pw.println("moderate)");
15244                            break;
15245                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15246                            pw.println("low)");
15247                            break;
15248                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15249                            pw.println("critical)");
15250                            break;
15251                        default:
15252                            pw.print(mLastMemoryLevel);
15253                            pw.println(")");
15254                            break;
15255                    }
15256                    pw.print(" Free RAM: ");
15257                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15258                            + memInfo.getFreeSizeKb()));
15259                    pw.print(" (");
15260                    pw.print(stringifyKBSize(cachedPss));
15261                    pw.print(" cached pss + ");
15262                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15263                    pw.print(" cached kernel + ");
15264                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15265                    pw.println(" free)");
15266                } else {
15267                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15268                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15269                            + memInfo.getFreeSizeKb()); pw.print(",");
15270                    pw.println(totalPss - cachedPss);
15271                }
15272            }
15273            if (!isCompact) {
15274                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15275                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15276                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15277                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15278                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15279                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15280                        - memInfo.getKernelUsedSizeKb()));
15281            }
15282            if (!brief) {
15283                if (memInfo.getZramTotalSizeKb() != 0) {
15284                    if (!isCompact) {
15285                        pw.print("     ZRAM: ");
15286                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15287                                pw.print(" physical used for ");
15288                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15289                                        - memInfo.getSwapFreeSizeKb()));
15290                                pw.print(" in swap (");
15291                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15292                                pw.println(" total swap)");
15293                    } else {
15294                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15295                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15296                                pw.println(memInfo.getSwapFreeSizeKb());
15297                    }
15298                }
15299                final long[] ksm = getKsmInfo();
15300                if (!isCompact) {
15301                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15302                            || ksm[KSM_VOLATILE] != 0) {
15303                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15304                                pw.print(" saved from shared ");
15305                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15306                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15307                                pw.print(" unshared; ");
15308                                pw.print(stringifyKBSize(
15309                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15310                    }
15311                    pw.print("   Tuning: ");
15312                    pw.print(ActivityManager.staticGetMemoryClass());
15313                    pw.print(" (large ");
15314                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15315                    pw.print("), oom ");
15316                    pw.print(stringifySize(
15317                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15318                    pw.print(", restore limit ");
15319                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15320                    if (ActivityManager.isLowRamDeviceStatic()) {
15321                        pw.print(" (low-ram)");
15322                    }
15323                    if (ActivityManager.isHighEndGfx()) {
15324                        pw.print(" (high-end-gfx)");
15325                    }
15326                    pw.println();
15327                } else {
15328                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15329                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15330                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15331                    pw.print("tuning,");
15332                    pw.print(ActivityManager.staticGetMemoryClass());
15333                    pw.print(',');
15334                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15335                    pw.print(',');
15336                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15337                    if (ActivityManager.isLowRamDeviceStatic()) {
15338                        pw.print(",low-ram");
15339                    }
15340                    if (ActivityManager.isHighEndGfx()) {
15341                        pw.print(",high-end-gfx");
15342                    }
15343                    pw.println();
15344                }
15345            }
15346        }
15347    }
15348
15349    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15350            long memtrack, String name) {
15351        sb.append("  ");
15352        sb.append(ProcessList.makeOomAdjString(oomAdj));
15353        sb.append(' ');
15354        sb.append(ProcessList.makeProcStateString(procState));
15355        sb.append(' ');
15356        ProcessList.appendRamKb(sb, pss);
15357        sb.append(": ");
15358        sb.append(name);
15359        if (memtrack > 0) {
15360            sb.append(" (");
15361            sb.append(stringifyKBSize(memtrack));
15362            sb.append(" memtrack)");
15363        }
15364    }
15365
15366    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15367        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15368        sb.append(" (pid ");
15369        sb.append(mi.pid);
15370        sb.append(") ");
15371        sb.append(mi.adjType);
15372        sb.append('\n');
15373        if (mi.adjReason != null) {
15374            sb.append("                      ");
15375            sb.append(mi.adjReason);
15376            sb.append('\n');
15377        }
15378    }
15379
15380    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15381        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15382        for (int i=0, N=memInfos.size(); i<N; i++) {
15383            ProcessMemInfo mi = memInfos.get(i);
15384            infoMap.put(mi.pid, mi);
15385        }
15386        updateCpuStatsNow();
15387        long[] memtrackTmp = new long[1];
15388        synchronized (mProcessCpuTracker) {
15389            final int N = mProcessCpuTracker.countStats();
15390            for (int i=0; i<N; i++) {
15391                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15392                if (st.vsize > 0) {
15393                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15394                    if (pss > 0) {
15395                        if (infoMap.indexOfKey(st.pid) < 0) {
15396                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15397                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15398                            mi.pss = pss;
15399                            mi.memtrack = memtrackTmp[0];
15400                            memInfos.add(mi);
15401                        }
15402                    }
15403                }
15404            }
15405        }
15406
15407        long totalPss = 0;
15408        long totalMemtrack = 0;
15409        for (int i=0, N=memInfos.size(); i<N; i++) {
15410            ProcessMemInfo mi = memInfos.get(i);
15411            if (mi.pss == 0) {
15412                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15413                mi.memtrack = memtrackTmp[0];
15414            }
15415            totalPss += mi.pss;
15416            totalMemtrack += mi.memtrack;
15417        }
15418        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15419            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15420                if (lhs.oomAdj != rhs.oomAdj) {
15421                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15422                }
15423                if (lhs.pss != rhs.pss) {
15424                    return lhs.pss < rhs.pss ? 1 : -1;
15425                }
15426                return 0;
15427            }
15428        });
15429
15430        StringBuilder tag = new StringBuilder(128);
15431        StringBuilder stack = new StringBuilder(128);
15432        tag.append("Low on memory -- ");
15433        appendMemBucket(tag, totalPss, "total", false);
15434        appendMemBucket(stack, totalPss, "total", true);
15435
15436        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15437        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15438        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15439
15440        boolean firstLine = true;
15441        int lastOomAdj = Integer.MIN_VALUE;
15442        long extraNativeRam = 0;
15443        long extraNativeMemtrack = 0;
15444        long cachedPss = 0;
15445        for (int i=0, N=memInfos.size(); i<N; i++) {
15446            ProcessMemInfo mi = memInfos.get(i);
15447
15448            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15449                cachedPss += mi.pss;
15450            }
15451
15452            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15453                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15454                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15455                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15456                if (lastOomAdj != mi.oomAdj) {
15457                    lastOomAdj = mi.oomAdj;
15458                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15459                        tag.append(" / ");
15460                    }
15461                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15462                        if (firstLine) {
15463                            stack.append(":");
15464                            firstLine = false;
15465                        }
15466                        stack.append("\n\t at ");
15467                    } else {
15468                        stack.append("$");
15469                    }
15470                } else {
15471                    tag.append(" ");
15472                    stack.append("$");
15473                }
15474                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15475                    appendMemBucket(tag, mi.pss, mi.name, false);
15476                }
15477                appendMemBucket(stack, mi.pss, mi.name, true);
15478                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15479                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15480                    stack.append("(");
15481                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15482                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15483                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15484                            stack.append(":");
15485                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15486                        }
15487                    }
15488                    stack.append(")");
15489                }
15490            }
15491
15492            appendMemInfo(fullNativeBuilder, mi);
15493            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15494                // The short form only has native processes that are >= 512K.
15495                if (mi.pss >= 512) {
15496                    appendMemInfo(shortNativeBuilder, mi);
15497                } else {
15498                    extraNativeRam += mi.pss;
15499                    extraNativeMemtrack += mi.memtrack;
15500                }
15501            } else {
15502                // Short form has all other details, but if we have collected RAM
15503                // from smaller native processes let's dump a summary of that.
15504                if (extraNativeRam > 0) {
15505                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15506                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15507                    shortNativeBuilder.append('\n');
15508                    extraNativeRam = 0;
15509                }
15510                appendMemInfo(fullJavaBuilder, mi);
15511            }
15512        }
15513
15514        fullJavaBuilder.append("           ");
15515        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15516        fullJavaBuilder.append(": TOTAL");
15517        if (totalMemtrack > 0) {
15518            fullJavaBuilder.append(" (");
15519            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15520            fullJavaBuilder.append(" memtrack)");
15521        } else {
15522        }
15523        fullJavaBuilder.append("\n");
15524
15525        MemInfoReader memInfo = new MemInfoReader();
15526        memInfo.readMemInfo();
15527        final long[] infos = memInfo.getRawInfo();
15528
15529        StringBuilder memInfoBuilder = new StringBuilder(1024);
15530        Debug.getMemInfo(infos);
15531        memInfoBuilder.append("  MemInfo: ");
15532        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15533        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15534        memInfoBuilder.append(stringifyKBSize(
15535                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15536        memInfoBuilder.append(stringifyKBSize(
15537                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15538        memInfoBuilder.append(stringifyKBSize(
15539                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15540        memInfoBuilder.append("           ");
15541        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15542        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15543        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15544        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15545        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15546            memInfoBuilder.append("  ZRAM: ");
15547            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15548            memInfoBuilder.append(" RAM, ");
15549            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15550            memInfoBuilder.append(" swap total, ");
15551            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15552            memInfoBuilder.append(" swap free\n");
15553        }
15554        final long[] ksm = getKsmInfo();
15555        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15556                || ksm[KSM_VOLATILE] != 0) {
15557            memInfoBuilder.append("  KSM: ");
15558            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15559            memInfoBuilder.append(" saved from shared ");
15560            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15561            memInfoBuilder.append("\n       ");
15562            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15563            memInfoBuilder.append(" unshared; ");
15564            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15565            memInfoBuilder.append(" volatile\n");
15566        }
15567        memInfoBuilder.append("  Free RAM: ");
15568        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15569                + memInfo.getFreeSizeKb()));
15570        memInfoBuilder.append("\n");
15571        memInfoBuilder.append("  Used RAM: ");
15572        memInfoBuilder.append(stringifyKBSize(
15573                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15574        memInfoBuilder.append("\n");
15575        memInfoBuilder.append("  Lost RAM: ");
15576        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15577                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15578                - memInfo.getKernelUsedSizeKb()));
15579        memInfoBuilder.append("\n");
15580        Slog.i(TAG, "Low on memory:");
15581        Slog.i(TAG, shortNativeBuilder.toString());
15582        Slog.i(TAG, fullJavaBuilder.toString());
15583        Slog.i(TAG, memInfoBuilder.toString());
15584
15585        StringBuilder dropBuilder = new StringBuilder(1024);
15586        /*
15587        StringWriter oomSw = new StringWriter();
15588        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15589        StringWriter catSw = new StringWriter();
15590        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15591        String[] emptyArgs = new String[] { };
15592        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15593        oomPw.flush();
15594        String oomString = oomSw.toString();
15595        */
15596        dropBuilder.append("Low on memory:");
15597        dropBuilder.append(stack);
15598        dropBuilder.append('\n');
15599        dropBuilder.append(fullNativeBuilder);
15600        dropBuilder.append(fullJavaBuilder);
15601        dropBuilder.append('\n');
15602        dropBuilder.append(memInfoBuilder);
15603        dropBuilder.append('\n');
15604        /*
15605        dropBuilder.append(oomString);
15606        dropBuilder.append('\n');
15607        */
15608        StringWriter catSw = new StringWriter();
15609        synchronized (ActivityManagerService.this) {
15610            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15611            String[] emptyArgs = new String[] { };
15612            catPw.println();
15613            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15614            catPw.println();
15615            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15616                    false, false, null);
15617            catPw.println();
15618            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15619            catPw.flush();
15620        }
15621        dropBuilder.append(catSw.toString());
15622        addErrorToDropBox("lowmem", null, "system_server", null,
15623                null, tag.toString(), dropBuilder.toString(), null, null);
15624        //Slog.i(TAG, "Sent to dropbox:");
15625        //Slog.i(TAG, dropBuilder.toString());
15626        synchronized (ActivityManagerService.this) {
15627            long now = SystemClock.uptimeMillis();
15628            if (mLastMemUsageReportTime < now) {
15629                mLastMemUsageReportTime = now;
15630            }
15631        }
15632    }
15633
15634    /**
15635     * Searches array of arguments for the specified string
15636     * @param args array of argument strings
15637     * @param value value to search for
15638     * @return true if the value is contained in the array
15639     */
15640    private static boolean scanArgs(String[] args, String value) {
15641        if (args != null) {
15642            for (String arg : args) {
15643                if (value.equals(arg)) {
15644                    return true;
15645                }
15646            }
15647        }
15648        return false;
15649    }
15650
15651    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15652            ContentProviderRecord cpr, boolean always) {
15653        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15654
15655        if (!inLaunching || always) {
15656            synchronized (cpr) {
15657                cpr.launchingApp = null;
15658                cpr.notifyAll();
15659            }
15660            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15661            String names[] = cpr.info.authority.split(";");
15662            for (int j = 0; j < names.length; j++) {
15663                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15664            }
15665        }
15666
15667        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15668            ContentProviderConnection conn = cpr.connections.get(i);
15669            if (conn.waiting) {
15670                // If this connection is waiting for the provider, then we don't
15671                // need to mess with its process unless we are always removing
15672                // or for some reason the provider is not currently launching.
15673                if (inLaunching && !always) {
15674                    continue;
15675                }
15676            }
15677            ProcessRecord capp = conn.client;
15678            conn.dead = true;
15679            if (conn.stableCount > 0) {
15680                if (!capp.persistent && capp.thread != null
15681                        && capp.pid != 0
15682                        && capp.pid != MY_PID) {
15683                    capp.kill("depends on provider "
15684                            + cpr.name.flattenToShortString()
15685                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15686                }
15687            } else if (capp.thread != null && conn.provider.provider != null) {
15688                try {
15689                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15690                } catch (RemoteException e) {
15691                }
15692                // In the protocol here, we don't expect the client to correctly
15693                // clean up this connection, we'll just remove it.
15694                cpr.connections.remove(i);
15695                if (conn.client.conProviders.remove(conn)) {
15696                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15697                }
15698            }
15699        }
15700
15701        if (inLaunching && always) {
15702            mLaunchingProviders.remove(cpr);
15703        }
15704        return inLaunching;
15705    }
15706
15707    /**
15708     * Main code for cleaning up a process when it has gone away.  This is
15709     * called both as a result of the process dying, or directly when stopping
15710     * a process when running in single process mode.
15711     *
15712     * @return Returns true if the given process has been restarted, so the
15713     * app that was passed in must remain on the process lists.
15714     */
15715    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15716            boolean restarting, boolean allowRestart, int index) {
15717        if (index >= 0) {
15718            removeLruProcessLocked(app);
15719            ProcessList.remove(app.pid);
15720        }
15721
15722        mProcessesToGc.remove(app);
15723        mPendingPssProcesses.remove(app);
15724
15725        // Dismiss any open dialogs.
15726        if (app.crashDialog != null && !app.forceCrashReport) {
15727            app.crashDialog.dismiss();
15728            app.crashDialog = null;
15729        }
15730        if (app.anrDialog != null) {
15731            app.anrDialog.dismiss();
15732            app.anrDialog = null;
15733        }
15734        if (app.waitDialog != null) {
15735            app.waitDialog.dismiss();
15736            app.waitDialog = null;
15737        }
15738
15739        app.crashing = false;
15740        app.notResponding = false;
15741
15742        app.resetPackageList(mProcessStats);
15743        app.unlinkDeathRecipient();
15744        app.makeInactive(mProcessStats);
15745        app.waitingToKill = null;
15746        app.forcingToForeground = null;
15747        updateProcessForegroundLocked(app, false, false);
15748        app.foregroundActivities = false;
15749        app.hasShownUi = false;
15750        app.treatLikeActivity = false;
15751        app.hasAboveClient = false;
15752        app.hasClientActivities = false;
15753
15754        mServices.killServicesLocked(app, allowRestart);
15755
15756        boolean restart = false;
15757
15758        // Remove published content providers.
15759        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15760            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15761            final boolean always = app.bad || !allowRestart;
15762            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15763            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15764                // We left the provider in the launching list, need to
15765                // restart it.
15766                restart = true;
15767            }
15768
15769            cpr.provider = null;
15770            cpr.proc = null;
15771        }
15772        app.pubProviders.clear();
15773
15774        // Take care of any launching providers waiting for this process.
15775        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15776            restart = true;
15777        }
15778
15779        // Unregister from connected content providers.
15780        if (!app.conProviders.isEmpty()) {
15781            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15782                ContentProviderConnection conn = app.conProviders.get(i);
15783                conn.provider.connections.remove(conn);
15784                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15785                        conn.provider.name);
15786            }
15787            app.conProviders.clear();
15788        }
15789
15790        // At this point there may be remaining entries in mLaunchingProviders
15791        // where we were the only one waiting, so they are no longer of use.
15792        // Look for these and clean up if found.
15793        // XXX Commented out for now.  Trying to figure out a way to reproduce
15794        // the actual situation to identify what is actually going on.
15795        if (false) {
15796            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15797                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15798                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15799                    synchronized (cpr) {
15800                        cpr.launchingApp = null;
15801                        cpr.notifyAll();
15802                    }
15803                }
15804            }
15805        }
15806
15807        skipCurrentReceiverLocked(app);
15808
15809        // Unregister any receivers.
15810        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15811            removeReceiverLocked(app.receivers.valueAt(i));
15812        }
15813        app.receivers.clear();
15814
15815        // If the app is undergoing backup, tell the backup manager about it
15816        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15817            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15818                    + mBackupTarget.appInfo + " died during backup");
15819            try {
15820                IBackupManager bm = IBackupManager.Stub.asInterface(
15821                        ServiceManager.getService(Context.BACKUP_SERVICE));
15822                bm.agentDisconnected(app.info.packageName);
15823            } catch (RemoteException e) {
15824                // can't happen; backup manager is local
15825            }
15826        }
15827
15828        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15829            ProcessChangeItem item = mPendingProcessChanges.get(i);
15830            if (item.pid == app.pid) {
15831                mPendingProcessChanges.remove(i);
15832                mAvailProcessChanges.add(item);
15833            }
15834        }
15835        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15836
15837        // If the caller is restarting this app, then leave it in its
15838        // current lists and let the caller take care of it.
15839        if (restarting) {
15840            return false;
15841        }
15842
15843        if (!app.persistent || app.isolated) {
15844            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15845                    "Removing non-persistent process during cleanup: " + app);
15846            removeProcessNameLocked(app.processName, app.uid);
15847            if (mHeavyWeightProcess == app) {
15848                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15849                        mHeavyWeightProcess.userId, 0));
15850                mHeavyWeightProcess = null;
15851            }
15852        } else if (!app.removed) {
15853            // This app is persistent, so we need to keep its record around.
15854            // If it is not already on the pending app list, add it there
15855            // and start a new process for it.
15856            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15857                mPersistentStartingProcesses.add(app);
15858                restart = true;
15859            }
15860        }
15861        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15862                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15863        mProcessesOnHold.remove(app);
15864
15865        if (app == mHomeProcess) {
15866            mHomeProcess = null;
15867        }
15868        if (app == mPreviousProcess) {
15869            mPreviousProcess = null;
15870        }
15871
15872        if (restart && !app.isolated) {
15873            // We have components that still need to be running in the
15874            // process, so re-launch it.
15875            if (index < 0) {
15876                ProcessList.remove(app.pid);
15877            }
15878            addProcessNameLocked(app);
15879            startProcessLocked(app, "restart", app.processName);
15880            return true;
15881        } else if (app.pid > 0 && app.pid != MY_PID) {
15882            // Goodbye!
15883            boolean removed;
15884            synchronized (mPidsSelfLocked) {
15885                mPidsSelfLocked.remove(app.pid);
15886                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15887            }
15888            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15889            if (app.isolated) {
15890                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15891            }
15892            app.setPid(0);
15893        }
15894        return false;
15895    }
15896
15897    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15898        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15899            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15900            if (cpr.launchingApp == app) {
15901                return true;
15902            }
15903        }
15904        return false;
15905    }
15906
15907    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15908        // Look through the content providers we are waiting to have launched,
15909        // and if any run in this process then either schedule a restart of
15910        // the process or kill the client waiting for it if this process has
15911        // gone bad.
15912        boolean restart = false;
15913        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15914            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15915            if (cpr.launchingApp == app) {
15916                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15917                    restart = true;
15918                } else {
15919                    removeDyingProviderLocked(app, cpr, true);
15920                }
15921            }
15922        }
15923        return restart;
15924    }
15925
15926    // =========================================================
15927    // SERVICES
15928    // =========================================================
15929
15930    @Override
15931    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15932            int flags) {
15933        enforceNotIsolatedCaller("getServices");
15934        synchronized (this) {
15935            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15936        }
15937    }
15938
15939    @Override
15940    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15941        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15942        synchronized (this) {
15943            return mServices.getRunningServiceControlPanelLocked(name);
15944        }
15945    }
15946
15947    @Override
15948    public ComponentName startService(IApplicationThread caller, Intent service,
15949            String resolvedType, String callingPackage, int userId)
15950            throws TransactionTooLargeException {
15951        enforceNotIsolatedCaller("startService");
15952        // Refuse possible leaked file descriptors
15953        if (service != null && service.hasFileDescriptors() == true) {
15954            throw new IllegalArgumentException("File descriptors passed in Intent");
15955        }
15956
15957        if (callingPackage == null) {
15958            throw new IllegalArgumentException("callingPackage cannot be null");
15959        }
15960
15961        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15962                "startService: " + service + " type=" + resolvedType);
15963        synchronized(this) {
15964            final int callingPid = Binder.getCallingPid();
15965            final int callingUid = Binder.getCallingUid();
15966            final long origId = Binder.clearCallingIdentity();
15967            ComponentName res = mServices.startServiceLocked(caller, service,
15968                    resolvedType, callingPid, callingUid, callingPackage, userId);
15969            Binder.restoreCallingIdentity(origId);
15970            return res;
15971        }
15972    }
15973
15974    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15975            String callingPackage, int userId)
15976            throws TransactionTooLargeException {
15977        synchronized(this) {
15978            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15979                    "startServiceInPackage: " + service + " type=" + resolvedType);
15980            final long origId = Binder.clearCallingIdentity();
15981            ComponentName res = mServices.startServiceLocked(null, service,
15982                    resolvedType, -1, uid, callingPackage, userId);
15983            Binder.restoreCallingIdentity(origId);
15984            return res;
15985        }
15986    }
15987
15988    @Override
15989    public int stopService(IApplicationThread caller, Intent service,
15990            String resolvedType, int userId) {
15991        enforceNotIsolatedCaller("stopService");
15992        // Refuse possible leaked file descriptors
15993        if (service != null && service.hasFileDescriptors() == true) {
15994            throw new IllegalArgumentException("File descriptors passed in Intent");
15995        }
15996
15997        synchronized(this) {
15998            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15999        }
16000    }
16001
16002    @Override
16003    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16004        enforceNotIsolatedCaller("peekService");
16005        // Refuse possible leaked file descriptors
16006        if (service != null && service.hasFileDescriptors() == true) {
16007            throw new IllegalArgumentException("File descriptors passed in Intent");
16008        }
16009
16010        if (callingPackage == null) {
16011            throw new IllegalArgumentException("callingPackage cannot be null");
16012        }
16013
16014        synchronized(this) {
16015            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16016        }
16017    }
16018
16019    @Override
16020    public boolean stopServiceToken(ComponentName className, IBinder token,
16021            int startId) {
16022        synchronized(this) {
16023            return mServices.stopServiceTokenLocked(className, token, startId);
16024        }
16025    }
16026
16027    @Override
16028    public void setServiceForeground(ComponentName className, IBinder token,
16029            int id, Notification notification, boolean removeNotification) {
16030        synchronized(this) {
16031            mServices.setServiceForegroundLocked(className, token, id, notification,
16032                    removeNotification);
16033        }
16034    }
16035
16036    @Override
16037    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16038            boolean requireFull, String name, String callerPackage) {
16039        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16040                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16041    }
16042
16043    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16044            String className, int flags) {
16045        boolean result = false;
16046        // For apps that don't have pre-defined UIDs, check for permission
16047        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16048            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16049                if (ActivityManager.checkUidPermission(
16050                        INTERACT_ACROSS_USERS,
16051                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16052                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16053                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16054                            + " requests FLAG_SINGLE_USER, but app does not hold "
16055                            + INTERACT_ACROSS_USERS;
16056                    Slog.w(TAG, msg);
16057                    throw new SecurityException(msg);
16058                }
16059                // Permission passed
16060                result = true;
16061            }
16062        } else if ("system".equals(componentProcessName)) {
16063            result = true;
16064        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16065            // Phone app and persistent apps are allowed to export singleuser providers.
16066            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16067                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16068        }
16069        if (DEBUG_MU) Slog.v(TAG_MU,
16070                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16071                + Integer.toHexString(flags) + ") = " + result);
16072        return result;
16073    }
16074
16075    /**
16076     * Checks to see if the caller is in the same app as the singleton
16077     * component, or the component is in a special app. It allows special apps
16078     * to export singleton components but prevents exporting singleton
16079     * components for regular apps.
16080     */
16081    boolean isValidSingletonCall(int callingUid, int componentUid) {
16082        int componentAppId = UserHandle.getAppId(componentUid);
16083        return UserHandle.isSameApp(callingUid, componentUid)
16084                || componentAppId == Process.SYSTEM_UID
16085                || componentAppId == Process.PHONE_UID
16086                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16087                        == PackageManager.PERMISSION_GRANTED;
16088    }
16089
16090    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16091            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16092            int userId) throws TransactionTooLargeException {
16093        enforceNotIsolatedCaller("bindService");
16094
16095        // Refuse possible leaked file descriptors
16096        if (service != null && service.hasFileDescriptors() == true) {
16097            throw new IllegalArgumentException("File descriptors passed in Intent");
16098        }
16099
16100        if (callingPackage == null) {
16101            throw new IllegalArgumentException("callingPackage cannot be null");
16102        }
16103
16104        synchronized(this) {
16105            return mServices.bindServiceLocked(caller, token, service,
16106                    resolvedType, connection, flags, callingPackage, userId);
16107        }
16108    }
16109
16110    public boolean unbindService(IServiceConnection connection) {
16111        synchronized (this) {
16112            return mServices.unbindServiceLocked(connection);
16113        }
16114    }
16115
16116    public void publishService(IBinder token, Intent intent, IBinder service) {
16117        // Refuse possible leaked file descriptors
16118        if (intent != null && intent.hasFileDescriptors() == true) {
16119            throw new IllegalArgumentException("File descriptors passed in Intent");
16120        }
16121
16122        synchronized(this) {
16123            if (!(token instanceof ServiceRecord)) {
16124                throw new IllegalArgumentException("Invalid service token");
16125            }
16126            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16127        }
16128    }
16129
16130    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16131        // Refuse possible leaked file descriptors
16132        if (intent != null && intent.hasFileDescriptors() == true) {
16133            throw new IllegalArgumentException("File descriptors passed in Intent");
16134        }
16135
16136        synchronized(this) {
16137            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16138        }
16139    }
16140
16141    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16142        synchronized(this) {
16143            if (!(token instanceof ServiceRecord)) {
16144                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16145                throw new IllegalArgumentException("Invalid service token");
16146            }
16147            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16148        }
16149    }
16150
16151    // =========================================================
16152    // BACKUP AND RESTORE
16153    // =========================================================
16154
16155    // Cause the target app to be launched if necessary and its backup agent
16156    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16157    // activity manager to announce its creation.
16158    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16159        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16160                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16161        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16162
16163        synchronized(this) {
16164            // !!! TODO: currently no check here that we're already bound
16165            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16166            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16167            synchronized (stats) {
16168                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16169            }
16170
16171            // Backup agent is now in use, its package can't be stopped.
16172            try {
16173                AppGlobals.getPackageManager().setPackageStoppedState(
16174                        app.packageName, false, UserHandle.getUserId(app.uid));
16175            } catch (RemoteException e) {
16176            } catch (IllegalArgumentException e) {
16177                Slog.w(TAG, "Failed trying to unstop package "
16178                        + app.packageName + ": " + e);
16179            }
16180
16181            BackupRecord r = new BackupRecord(ss, app, backupMode);
16182            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16183                    ? new ComponentName(app.packageName, app.backupAgentName)
16184                    : new ComponentName("android", "FullBackupAgent");
16185            // startProcessLocked() returns existing proc's record if it's already running
16186            ProcessRecord proc = startProcessLocked(app.processName, app,
16187                    false, 0, "backup", hostingName, false, false, false);
16188            if (proc == null) {
16189                Slog.e(TAG, "Unable to start backup agent process " + r);
16190                return false;
16191            }
16192
16193            r.app = proc;
16194            mBackupTarget = r;
16195            mBackupAppName = app.packageName;
16196
16197            // Try not to kill the process during backup
16198            updateOomAdjLocked(proc);
16199
16200            // If the process is already attached, schedule the creation of the backup agent now.
16201            // If it is not yet live, this will be done when it attaches to the framework.
16202            if (proc.thread != null) {
16203                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16204                try {
16205                    proc.thread.scheduleCreateBackupAgent(app,
16206                            compatibilityInfoForPackageLocked(app), backupMode);
16207                } catch (RemoteException e) {
16208                    // Will time out on the backup manager side
16209                }
16210            } else {
16211                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16212            }
16213            // Invariants: at this point, the target app process exists and the application
16214            // is either already running or in the process of coming up.  mBackupTarget and
16215            // mBackupAppName describe the app, so that when it binds back to the AM we
16216            // know that it's scheduled for a backup-agent operation.
16217        }
16218
16219        return true;
16220    }
16221
16222    @Override
16223    public void clearPendingBackup() {
16224        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16225        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16226
16227        synchronized (this) {
16228            mBackupTarget = null;
16229            mBackupAppName = null;
16230        }
16231    }
16232
16233    // A backup agent has just come up
16234    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16235        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16236                + " = " + agent);
16237
16238        synchronized(this) {
16239            if (!agentPackageName.equals(mBackupAppName)) {
16240                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16241                return;
16242            }
16243        }
16244
16245        long oldIdent = Binder.clearCallingIdentity();
16246        try {
16247            IBackupManager bm = IBackupManager.Stub.asInterface(
16248                    ServiceManager.getService(Context.BACKUP_SERVICE));
16249            bm.agentConnected(agentPackageName, agent);
16250        } catch (RemoteException e) {
16251            // can't happen; the backup manager service is local
16252        } catch (Exception e) {
16253            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16254            e.printStackTrace();
16255        } finally {
16256            Binder.restoreCallingIdentity(oldIdent);
16257        }
16258    }
16259
16260    // done with this agent
16261    public void unbindBackupAgent(ApplicationInfo appInfo) {
16262        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16263        if (appInfo == null) {
16264            Slog.w(TAG, "unbind backup agent for null app");
16265            return;
16266        }
16267
16268        synchronized(this) {
16269            try {
16270                if (mBackupAppName == null) {
16271                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16272                    return;
16273                }
16274
16275                if (!mBackupAppName.equals(appInfo.packageName)) {
16276                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16277                    return;
16278                }
16279
16280                // Not backing this app up any more; reset its OOM adjustment
16281                final ProcessRecord proc = mBackupTarget.app;
16282                updateOomAdjLocked(proc);
16283
16284                // If the app crashed during backup, 'thread' will be null here
16285                if (proc.thread != null) {
16286                    try {
16287                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16288                                compatibilityInfoForPackageLocked(appInfo));
16289                    } catch (Exception e) {
16290                        Slog.e(TAG, "Exception when unbinding backup agent:");
16291                        e.printStackTrace();
16292                    }
16293                }
16294            } finally {
16295                mBackupTarget = null;
16296                mBackupAppName = null;
16297            }
16298        }
16299    }
16300    // =========================================================
16301    // BROADCASTS
16302    // =========================================================
16303
16304    boolean isPendingBroadcastProcessLocked(int pid) {
16305        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16306                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16307    }
16308
16309    void skipPendingBroadcastLocked(int pid) {
16310            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16311            for (BroadcastQueue queue : mBroadcastQueues) {
16312                queue.skipPendingBroadcastLocked(pid);
16313            }
16314    }
16315
16316    // The app just attached; send any pending broadcasts that it should receive
16317    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16318        boolean didSomething = false;
16319        for (BroadcastQueue queue : mBroadcastQueues) {
16320            didSomething |= queue.sendPendingBroadcastsLocked(app);
16321        }
16322        return didSomething;
16323    }
16324
16325    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16326            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16327        enforceNotIsolatedCaller("registerReceiver");
16328        ArrayList<Intent> stickyIntents = null;
16329        ProcessRecord callerApp = null;
16330        int callingUid;
16331        int callingPid;
16332        synchronized(this) {
16333            if (caller != null) {
16334                callerApp = getRecordForAppLocked(caller);
16335                if (callerApp == null) {
16336                    throw new SecurityException(
16337                            "Unable to find app for caller " + caller
16338                            + " (pid=" + Binder.getCallingPid()
16339                            + ") when registering receiver " + receiver);
16340                }
16341                if (callerApp.info.uid != Process.SYSTEM_UID &&
16342                        !callerApp.pkgList.containsKey(callerPackage) &&
16343                        !"android".equals(callerPackage)) {
16344                    throw new SecurityException("Given caller package " + callerPackage
16345                            + " is not running in process " + callerApp);
16346                }
16347                callingUid = callerApp.info.uid;
16348                callingPid = callerApp.pid;
16349            } else {
16350                callerPackage = null;
16351                callingUid = Binder.getCallingUid();
16352                callingPid = Binder.getCallingPid();
16353            }
16354
16355            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16356                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16357
16358            Iterator<String> actions = filter.actionsIterator();
16359            if (actions == null) {
16360                ArrayList<String> noAction = new ArrayList<String>(1);
16361                noAction.add(null);
16362                actions = noAction.iterator();
16363            }
16364
16365            // Collect stickies of users
16366            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16367            while (actions.hasNext()) {
16368                String action = actions.next();
16369                for (int id : userIds) {
16370                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16371                    if (stickies != null) {
16372                        ArrayList<Intent> intents = stickies.get(action);
16373                        if (intents != null) {
16374                            if (stickyIntents == null) {
16375                                stickyIntents = new ArrayList<Intent>();
16376                            }
16377                            stickyIntents.addAll(intents);
16378                        }
16379                    }
16380                }
16381            }
16382        }
16383
16384        ArrayList<Intent> allSticky = null;
16385        if (stickyIntents != null) {
16386            final ContentResolver resolver = mContext.getContentResolver();
16387            // Look for any matching sticky broadcasts...
16388            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16389                Intent intent = stickyIntents.get(i);
16390                // If intent has scheme "content", it will need to acccess
16391                // provider that needs to lock mProviderMap in ActivityThread
16392                // and also it may need to wait application response, so we
16393                // cannot lock ActivityManagerService here.
16394                if (filter.match(resolver, intent, true, TAG) >= 0) {
16395                    if (allSticky == null) {
16396                        allSticky = new ArrayList<Intent>();
16397                    }
16398                    allSticky.add(intent);
16399                }
16400            }
16401        }
16402
16403        // The first sticky in the list is returned directly back to the client.
16404        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16405        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16406        if (receiver == null) {
16407            return sticky;
16408        }
16409
16410        synchronized (this) {
16411            if (callerApp != null && (callerApp.thread == null
16412                    || callerApp.thread.asBinder() != caller.asBinder())) {
16413                // Original caller already died
16414                return null;
16415            }
16416            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16417            if (rl == null) {
16418                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16419                        userId, receiver);
16420                if (rl.app != null) {
16421                    rl.app.receivers.add(rl);
16422                } else {
16423                    try {
16424                        receiver.asBinder().linkToDeath(rl, 0);
16425                    } catch (RemoteException e) {
16426                        return sticky;
16427                    }
16428                    rl.linkedToDeath = true;
16429                }
16430                mRegisteredReceivers.put(receiver.asBinder(), rl);
16431            } else if (rl.uid != callingUid) {
16432                throw new IllegalArgumentException(
16433                        "Receiver requested to register for uid " + callingUid
16434                        + " was previously registered for uid " + rl.uid);
16435            } else if (rl.pid != callingPid) {
16436                throw new IllegalArgumentException(
16437                        "Receiver requested to register for pid " + callingPid
16438                        + " was previously registered for pid " + rl.pid);
16439            } else if (rl.userId != userId) {
16440                throw new IllegalArgumentException(
16441                        "Receiver requested to register for user " + userId
16442                        + " was previously registered for user " + rl.userId);
16443            }
16444            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16445                    permission, callingUid, userId);
16446            rl.add(bf);
16447            if (!bf.debugCheck()) {
16448                Slog.w(TAG, "==> For Dynamic broadcast");
16449            }
16450            mReceiverResolver.addFilter(bf);
16451
16452            // Enqueue broadcasts for all existing stickies that match
16453            // this filter.
16454            if (allSticky != null) {
16455                ArrayList receivers = new ArrayList();
16456                receivers.add(bf);
16457
16458                final int stickyCount = allSticky.size();
16459                for (int i = 0; i < stickyCount; i++) {
16460                    Intent intent = allSticky.get(i);
16461                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16462                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16463                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16464                            null, 0, null, null, false, true, true, -1);
16465                    queue.enqueueParallelBroadcastLocked(r);
16466                    queue.scheduleBroadcastsLocked();
16467                }
16468            }
16469
16470            return sticky;
16471        }
16472    }
16473
16474    public void unregisterReceiver(IIntentReceiver receiver) {
16475        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16476
16477        final long origId = Binder.clearCallingIdentity();
16478        try {
16479            boolean doTrim = false;
16480
16481            synchronized(this) {
16482                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16483                if (rl != null) {
16484                    final BroadcastRecord r = rl.curBroadcast;
16485                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16486                        final boolean doNext = r.queue.finishReceiverLocked(
16487                                r, r.resultCode, r.resultData, r.resultExtras,
16488                                r.resultAbort, false);
16489                        if (doNext) {
16490                            doTrim = true;
16491                            r.queue.processNextBroadcast(false);
16492                        }
16493                    }
16494
16495                    if (rl.app != null) {
16496                        rl.app.receivers.remove(rl);
16497                    }
16498                    removeReceiverLocked(rl);
16499                    if (rl.linkedToDeath) {
16500                        rl.linkedToDeath = false;
16501                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16502                    }
16503                }
16504            }
16505
16506            // If we actually concluded any broadcasts, we might now be able
16507            // to trim the recipients' apps from our working set
16508            if (doTrim) {
16509                trimApplications();
16510                return;
16511            }
16512
16513        } finally {
16514            Binder.restoreCallingIdentity(origId);
16515        }
16516    }
16517
16518    void removeReceiverLocked(ReceiverList rl) {
16519        mRegisteredReceivers.remove(rl.receiver.asBinder());
16520        for (int i = rl.size() - 1; i >= 0; i--) {
16521            mReceiverResolver.removeFilter(rl.get(i));
16522        }
16523    }
16524
16525    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16526        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16527            ProcessRecord r = mLruProcesses.get(i);
16528            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16529                try {
16530                    r.thread.dispatchPackageBroadcast(cmd, packages);
16531                } catch (RemoteException ex) {
16532                }
16533            }
16534        }
16535    }
16536
16537    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16538            int callingUid, int[] users) {
16539        List<ResolveInfo> receivers = null;
16540        try {
16541            HashSet<ComponentName> singleUserReceivers = null;
16542            boolean scannedFirstReceivers = false;
16543            for (int user : users) {
16544                // Skip users that have Shell restrictions
16545                if (callingUid == Process.SHELL_UID
16546                        && mUserController.hasUserRestriction(
16547                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16548                    continue;
16549                }
16550                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16551                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16552                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16553                    // If this is not the system user, we need to check for
16554                    // any receivers that should be filtered out.
16555                    for (int i=0; i<newReceivers.size(); i++) {
16556                        ResolveInfo ri = newReceivers.get(i);
16557                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16558                            newReceivers.remove(i);
16559                            i--;
16560                        }
16561                    }
16562                }
16563                if (newReceivers != null && newReceivers.size() == 0) {
16564                    newReceivers = null;
16565                }
16566                if (receivers == null) {
16567                    receivers = newReceivers;
16568                } else if (newReceivers != null) {
16569                    // We need to concatenate the additional receivers
16570                    // found with what we have do far.  This would be easy,
16571                    // but we also need to de-dup any receivers that are
16572                    // singleUser.
16573                    if (!scannedFirstReceivers) {
16574                        // Collect any single user receivers we had already retrieved.
16575                        scannedFirstReceivers = true;
16576                        for (int i=0; i<receivers.size(); i++) {
16577                            ResolveInfo ri = receivers.get(i);
16578                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16579                                ComponentName cn = new ComponentName(
16580                                        ri.activityInfo.packageName, ri.activityInfo.name);
16581                                if (singleUserReceivers == null) {
16582                                    singleUserReceivers = new HashSet<ComponentName>();
16583                                }
16584                                singleUserReceivers.add(cn);
16585                            }
16586                        }
16587                    }
16588                    // Add the new results to the existing results, tracking
16589                    // and de-dupping single user receivers.
16590                    for (int i=0; i<newReceivers.size(); i++) {
16591                        ResolveInfo ri = newReceivers.get(i);
16592                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16593                            ComponentName cn = new ComponentName(
16594                                    ri.activityInfo.packageName, ri.activityInfo.name);
16595                            if (singleUserReceivers == null) {
16596                                singleUserReceivers = new HashSet<ComponentName>();
16597                            }
16598                            if (!singleUserReceivers.contains(cn)) {
16599                                singleUserReceivers.add(cn);
16600                                receivers.add(ri);
16601                            }
16602                        } else {
16603                            receivers.add(ri);
16604                        }
16605                    }
16606                }
16607            }
16608        } catch (RemoteException ex) {
16609            // pm is in same process, this will never happen.
16610        }
16611        return receivers;
16612    }
16613
16614    final int broadcastIntentLocked(ProcessRecord callerApp,
16615            String callerPackage, Intent intent, String resolvedType,
16616            IIntentReceiver resultTo, int resultCode, String resultData,
16617            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16618            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16619        intent = new Intent(intent);
16620
16621        // By default broadcasts do not go to stopped apps.
16622        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16623
16624        // If we have not finished booting, don't allow this to launch new processes.
16625        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16626            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16627        }
16628
16629        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16630                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16631                + " ordered=" + ordered + " userid=" + userId);
16632        if ((resultTo != null) && !ordered) {
16633            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16634        }
16635
16636        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16637                ALLOW_NON_FULL, "broadcast", callerPackage);
16638
16639        // Make sure that the user who is receiving this broadcast is running.
16640        // If not, we will just skip it. Make an exception for shutdown broadcasts
16641        // and upgrade steps.
16642
16643        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, false)) {
16644            if ((callingUid != Process.SYSTEM_UID
16645                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16646                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16647                Slog.w(TAG, "Skipping broadcast of " + intent
16648                        + ": user " + userId + " is stopped");
16649                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16650            }
16651        }
16652
16653        BroadcastOptions brOptions = null;
16654        if (bOptions != null) {
16655            brOptions = new BroadcastOptions(bOptions);
16656            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16657                // See if the caller is allowed to do this.  Note we are checking against
16658                // the actual real caller (not whoever provided the operation as say a
16659                // PendingIntent), because that who is actually supplied the arguments.
16660                if (checkComponentPermission(
16661                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16662                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16663                        != PackageManager.PERMISSION_GRANTED) {
16664                    String msg = "Permission Denial: " + intent.getAction()
16665                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16666                            + ", uid=" + callingUid + ")"
16667                            + " requires "
16668                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16669                    Slog.w(TAG, msg);
16670                    throw new SecurityException(msg);
16671                }
16672            }
16673        }
16674
16675        /*
16676         * Prevent non-system code (defined here to be non-persistent
16677         * processes) from sending protected broadcasts.
16678         */
16679        int callingAppId = UserHandle.getAppId(callingUid);
16680        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16681            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16682            || callingAppId == Process.NFC_UID || callingUid == 0) {
16683            // Always okay.
16684        } else if (callerApp == null || !callerApp.persistent) {
16685            try {
16686                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16687                        intent.getAction())) {
16688                    String msg = "Permission Denial: not allowed to send broadcast "
16689                            + intent.getAction() + " from pid="
16690                            + callingPid + ", uid=" + callingUid;
16691                    Slog.w(TAG, msg);
16692                    throw new SecurityException(msg);
16693                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16694                    // Special case for compatibility: we don't want apps to send this,
16695                    // but historically it has not been protected and apps may be using it
16696                    // to poke their own app widget.  So, instead of making it protected,
16697                    // just limit it to the caller.
16698                    if (callerApp == null) {
16699                        String msg = "Permission Denial: not allowed to send broadcast "
16700                                + intent.getAction() + " from unknown caller.";
16701                        Slog.w(TAG, msg);
16702                        throw new SecurityException(msg);
16703                    } else if (intent.getComponent() != null) {
16704                        // They are good enough to send to an explicit component...  verify
16705                        // it is being sent to the calling app.
16706                        if (!intent.getComponent().getPackageName().equals(
16707                                callerApp.info.packageName)) {
16708                            String msg = "Permission Denial: not allowed to send broadcast "
16709                                    + intent.getAction() + " to "
16710                                    + intent.getComponent().getPackageName() + " from "
16711                                    + callerApp.info.packageName;
16712                            Slog.w(TAG, msg);
16713                            throw new SecurityException(msg);
16714                        }
16715                    } else {
16716                        // Limit broadcast to their own package.
16717                        intent.setPackage(callerApp.info.packageName);
16718                    }
16719                }
16720            } catch (RemoteException e) {
16721                Slog.w(TAG, "Remote exception", e);
16722                return ActivityManager.BROADCAST_SUCCESS;
16723            }
16724        }
16725
16726        final String action = intent.getAction();
16727        if (action != null) {
16728            switch (action) {
16729                case Intent.ACTION_UID_REMOVED:
16730                case Intent.ACTION_PACKAGE_REMOVED:
16731                case Intent.ACTION_PACKAGE_CHANGED:
16732                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16733                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16734                    // Handle special intents: if this broadcast is from the package
16735                    // manager about a package being removed, we need to remove all of
16736                    // its activities from the history stack.
16737                    if (checkComponentPermission(
16738                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16739                            callingPid, callingUid, -1, true)
16740                            != PackageManager.PERMISSION_GRANTED) {
16741                        String msg = "Permission Denial: " + intent.getAction()
16742                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16743                                + ", uid=" + callingUid + ")"
16744                                + " requires "
16745                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16746                        Slog.w(TAG, msg);
16747                        throw new SecurityException(msg);
16748                    }
16749                    switch (action) {
16750                        case Intent.ACTION_UID_REMOVED:
16751                            final Bundle intentExtras = intent.getExtras();
16752                            final int uid = intentExtras != null
16753                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16754                            if (uid >= 0) {
16755                                mBatteryStatsService.removeUid(uid);
16756                                mAppOpsService.uidRemoved(uid);
16757                            }
16758                            break;
16759                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16760                            // If resources are unavailable just force stop all those packages
16761                            // and flush the attribute cache as well.
16762                            String list[] =
16763                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16764                            if (list != null && list.length > 0) {
16765                                for (int i = 0; i < list.length; i++) {
16766                                    forceStopPackageLocked(list[i], -1, false, true, true,
16767                                            false, false, userId, "storage unmount");
16768                                }
16769                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16770                                sendPackageBroadcastLocked(
16771                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16772                                        userId);
16773                            }
16774                            break;
16775                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16776                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16777                            break;
16778                        case Intent.ACTION_PACKAGE_REMOVED:
16779                        case Intent.ACTION_PACKAGE_CHANGED:
16780                            Uri data = intent.getData();
16781                            String ssp;
16782                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16783                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16784                                boolean fullUninstall = removed &&
16785                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16786                                final boolean killProcess =
16787                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16788                                if (killProcess) {
16789                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16790                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16791                                            false, true, true, false, fullUninstall, userId,
16792                                            removed ? "pkg removed" : "pkg changed");
16793                                }
16794                                if (removed) {
16795                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16796                                            new String[] {ssp}, userId);
16797                                    if (fullUninstall) {
16798                                        mAppOpsService.packageRemoved(
16799                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16800
16801                                        // Remove all permissions granted from/to this package
16802                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16803
16804                                        removeTasksByPackageNameLocked(ssp, userId);
16805                                        mBatteryStatsService.notePackageUninstalled(ssp);
16806                                    }
16807                                } else {
16808                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16809                                            intent.getStringArrayExtra(
16810                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16811                                }
16812                            }
16813                            break;
16814                    }
16815                    break;
16816                case Intent.ACTION_PACKAGE_ADDED:
16817                    // Special case for adding a package: by default turn on compatibility mode.
16818                    Uri data = intent.getData();
16819                    String ssp;
16820                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16821                        final boolean replacing =
16822                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16823                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16824
16825                        try {
16826                            ApplicationInfo ai = AppGlobals.getPackageManager().
16827                                    getApplicationInfo(ssp, 0, 0);
16828                            mBatteryStatsService.notePackageInstalled(ssp,
16829                                    ai != null ? ai.versionCode : 0);
16830                        } catch (RemoteException e) {
16831                        }
16832                    }
16833                    break;
16834                case Intent.ACTION_TIMEZONE_CHANGED:
16835                    // If this is the time zone changed action, queue up a message that will reset
16836                    // the timezone of all currently running processes. This message will get
16837                    // queued up before the broadcast happens.
16838                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16839                    break;
16840                case Intent.ACTION_TIME_CHANGED:
16841                    // If the user set the time, let all running processes know.
16842                    final int is24Hour =
16843                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16844                                    : 0;
16845                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16846                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16847                    synchronized (stats) {
16848                        stats.noteCurrentTimeChangedLocked();
16849                    }
16850                    break;
16851                case Intent.ACTION_CLEAR_DNS_CACHE:
16852                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16853                    break;
16854                case Proxy.PROXY_CHANGE_ACTION:
16855                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16856                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16857                    break;
16858            }
16859        }
16860
16861        // Add to the sticky list if requested.
16862        if (sticky) {
16863            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16864                    callingPid, callingUid)
16865                    != PackageManager.PERMISSION_GRANTED) {
16866                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16867                        + callingPid + ", uid=" + callingUid
16868                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16869                Slog.w(TAG, msg);
16870                throw new SecurityException(msg);
16871            }
16872            if (requiredPermissions != null && requiredPermissions.length > 0) {
16873                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16874                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16875                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16876            }
16877            if (intent.getComponent() != null) {
16878                throw new SecurityException(
16879                        "Sticky broadcasts can't target a specific component");
16880            }
16881            // We use userId directly here, since the "all" target is maintained
16882            // as a separate set of sticky broadcasts.
16883            if (userId != UserHandle.USER_ALL) {
16884                // But first, if this is not a broadcast to all users, then
16885                // make sure it doesn't conflict with an existing broadcast to
16886                // all users.
16887                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16888                        UserHandle.USER_ALL);
16889                if (stickies != null) {
16890                    ArrayList<Intent> list = stickies.get(intent.getAction());
16891                    if (list != null) {
16892                        int N = list.size();
16893                        int i;
16894                        for (i=0; i<N; i++) {
16895                            if (intent.filterEquals(list.get(i))) {
16896                                throw new IllegalArgumentException(
16897                                        "Sticky broadcast " + intent + " for user "
16898                                        + userId + " conflicts with existing global broadcast");
16899                            }
16900                        }
16901                    }
16902                }
16903            }
16904            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16905            if (stickies == null) {
16906                stickies = new ArrayMap<>();
16907                mStickyBroadcasts.put(userId, stickies);
16908            }
16909            ArrayList<Intent> list = stickies.get(intent.getAction());
16910            if (list == null) {
16911                list = new ArrayList<>();
16912                stickies.put(intent.getAction(), list);
16913            }
16914            final int stickiesCount = list.size();
16915            int i;
16916            for (i = 0; i < stickiesCount; i++) {
16917                if (intent.filterEquals(list.get(i))) {
16918                    // This sticky already exists, replace it.
16919                    list.set(i, new Intent(intent));
16920                    break;
16921                }
16922            }
16923            if (i >= stickiesCount) {
16924                list.add(new Intent(intent));
16925            }
16926        }
16927
16928        int[] users;
16929        if (userId == UserHandle.USER_ALL) {
16930            // Caller wants broadcast to go to all started users.
16931            users = mUserController.getStartedUserArrayLocked();
16932        } else {
16933            // Caller wants broadcast to go to one specific user.
16934            users = new int[] {userId};
16935        }
16936
16937        // Figure out who all will receive this broadcast.
16938        List receivers = null;
16939        List<BroadcastFilter> registeredReceivers = null;
16940        // Need to resolve the intent to interested receivers...
16941        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16942                 == 0) {
16943            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16944        }
16945        if (intent.getComponent() == null) {
16946            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16947                // Query one target user at a time, excluding shell-restricted users
16948                for (int i = 0; i < users.length; i++) {
16949                    if (mUserController.hasUserRestriction(
16950                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16951                        continue;
16952                    }
16953                    List<BroadcastFilter> registeredReceiversForUser =
16954                            mReceiverResolver.queryIntent(intent,
16955                                    resolvedType, false, users[i]);
16956                    if (registeredReceivers == null) {
16957                        registeredReceivers = registeredReceiversForUser;
16958                    } else if (registeredReceiversForUser != null) {
16959                        registeredReceivers.addAll(registeredReceiversForUser);
16960                    }
16961                }
16962            } else {
16963                registeredReceivers = mReceiverResolver.queryIntent(intent,
16964                        resolvedType, false, userId);
16965            }
16966        }
16967
16968        final boolean replacePending =
16969                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16970
16971        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16972                + " replacePending=" + replacePending);
16973
16974        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16975        if (!ordered && NR > 0) {
16976            // If we are not serializing this broadcast, then send the
16977            // registered receivers separately so they don't wait for the
16978            // components to be launched.
16979            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16980            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16981                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16982                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16983                    resultExtras, ordered, sticky, false, userId);
16984            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16985            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16986            if (!replaced) {
16987                queue.enqueueParallelBroadcastLocked(r);
16988                queue.scheduleBroadcastsLocked();
16989            }
16990            registeredReceivers = null;
16991            NR = 0;
16992        }
16993
16994        // Merge into one list.
16995        int ir = 0;
16996        if (receivers != null) {
16997            // A special case for PACKAGE_ADDED: do not allow the package
16998            // being added to see this broadcast.  This prevents them from
16999            // using this as a back door to get run as soon as they are
17000            // installed.  Maybe in the future we want to have a special install
17001            // broadcast or such for apps, but we'd like to deliberately make
17002            // this decision.
17003            String skipPackages[] = null;
17004            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17005                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17006                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17007                Uri data = intent.getData();
17008                if (data != null) {
17009                    String pkgName = data.getSchemeSpecificPart();
17010                    if (pkgName != null) {
17011                        skipPackages = new String[] { pkgName };
17012                    }
17013                }
17014            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17015                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17016            }
17017            if (skipPackages != null && (skipPackages.length > 0)) {
17018                for (String skipPackage : skipPackages) {
17019                    if (skipPackage != null) {
17020                        int NT = receivers.size();
17021                        for (int it=0; it<NT; it++) {
17022                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17023                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17024                                receivers.remove(it);
17025                                it--;
17026                                NT--;
17027                            }
17028                        }
17029                    }
17030                }
17031            }
17032
17033            int NT = receivers != null ? receivers.size() : 0;
17034            int it = 0;
17035            ResolveInfo curt = null;
17036            BroadcastFilter curr = null;
17037            while (it < NT && ir < NR) {
17038                if (curt == null) {
17039                    curt = (ResolveInfo)receivers.get(it);
17040                }
17041                if (curr == null) {
17042                    curr = registeredReceivers.get(ir);
17043                }
17044                if (curr.getPriority() >= curt.priority) {
17045                    // Insert this broadcast record into the final list.
17046                    receivers.add(it, curr);
17047                    ir++;
17048                    curr = null;
17049                    it++;
17050                    NT++;
17051                } else {
17052                    // Skip to the next ResolveInfo in the final list.
17053                    it++;
17054                    curt = null;
17055                }
17056            }
17057        }
17058        while (ir < NR) {
17059            if (receivers == null) {
17060                receivers = new ArrayList();
17061            }
17062            receivers.add(registeredReceivers.get(ir));
17063            ir++;
17064        }
17065
17066        if ((receivers != null && receivers.size() > 0)
17067                || resultTo != null) {
17068            BroadcastQueue queue = broadcastQueueForIntent(intent);
17069            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17070                    callerPackage, callingPid, callingUid, resolvedType,
17071                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17072                    resultData, resultExtras, ordered, sticky, false, userId);
17073
17074            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17075                    + ": prev had " + queue.mOrderedBroadcasts.size());
17076            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17077                    "Enqueueing broadcast " + r.intent.getAction());
17078
17079            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17080            if (!replaced) {
17081                queue.enqueueOrderedBroadcastLocked(r);
17082                queue.scheduleBroadcastsLocked();
17083            }
17084        }
17085
17086        return ActivityManager.BROADCAST_SUCCESS;
17087    }
17088
17089    final Intent verifyBroadcastLocked(Intent intent) {
17090        // Refuse possible leaked file descriptors
17091        if (intent != null && intent.hasFileDescriptors() == true) {
17092            throw new IllegalArgumentException("File descriptors passed in Intent");
17093        }
17094
17095        int flags = intent.getFlags();
17096
17097        if (!mProcessesReady) {
17098            // if the caller really truly claims to know what they're doing, go
17099            // ahead and allow the broadcast without launching any receivers
17100            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17101                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17102            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17103                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17104                        + " before boot completion");
17105                throw new IllegalStateException("Cannot broadcast before boot completed");
17106            }
17107        }
17108
17109        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17110            throw new IllegalArgumentException(
17111                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17112        }
17113
17114        return intent;
17115    }
17116
17117    public final int broadcastIntent(IApplicationThread caller,
17118            Intent intent, String resolvedType, IIntentReceiver resultTo,
17119            int resultCode, String resultData, Bundle resultExtras,
17120            String[] requiredPermissions, int appOp, Bundle bOptions,
17121            boolean serialized, boolean sticky, int userId) {
17122        enforceNotIsolatedCaller("broadcastIntent");
17123        synchronized(this) {
17124            intent = verifyBroadcastLocked(intent);
17125
17126            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17127            final int callingPid = Binder.getCallingPid();
17128            final int callingUid = Binder.getCallingUid();
17129            final long origId = Binder.clearCallingIdentity();
17130            int res = broadcastIntentLocked(callerApp,
17131                    callerApp != null ? callerApp.info.packageName : null,
17132                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17133                    requiredPermissions, appOp, null, serialized, sticky,
17134                    callingPid, callingUid, userId);
17135            Binder.restoreCallingIdentity(origId);
17136            return res;
17137        }
17138    }
17139
17140
17141    int broadcastIntentInPackage(String packageName, int uid,
17142            Intent intent, String resolvedType, IIntentReceiver resultTo,
17143            int resultCode, String resultData, Bundle resultExtras,
17144            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17145            int userId) {
17146        synchronized(this) {
17147            intent = verifyBroadcastLocked(intent);
17148
17149            final long origId = Binder.clearCallingIdentity();
17150            String[] requiredPermissions = requiredPermission == null ? null
17151                    : new String[] {requiredPermission};
17152            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17153                    resultTo, resultCode, resultData, resultExtras,
17154                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17155                    sticky, -1, uid, userId);
17156            Binder.restoreCallingIdentity(origId);
17157            return res;
17158        }
17159    }
17160
17161    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17162        // Refuse possible leaked file descriptors
17163        if (intent != null && intent.hasFileDescriptors() == true) {
17164            throw new IllegalArgumentException("File descriptors passed in Intent");
17165        }
17166
17167        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17168                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17169
17170        synchronized(this) {
17171            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17172                    != PackageManager.PERMISSION_GRANTED) {
17173                String msg = "Permission Denial: unbroadcastIntent() from pid="
17174                        + Binder.getCallingPid()
17175                        + ", uid=" + Binder.getCallingUid()
17176                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17177                Slog.w(TAG, msg);
17178                throw new SecurityException(msg);
17179            }
17180            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17181            if (stickies != null) {
17182                ArrayList<Intent> list = stickies.get(intent.getAction());
17183                if (list != null) {
17184                    int N = list.size();
17185                    int i;
17186                    for (i=0; i<N; i++) {
17187                        if (intent.filterEquals(list.get(i))) {
17188                            list.remove(i);
17189                            break;
17190                        }
17191                    }
17192                    if (list.size() <= 0) {
17193                        stickies.remove(intent.getAction());
17194                    }
17195                }
17196                if (stickies.size() <= 0) {
17197                    mStickyBroadcasts.remove(userId);
17198                }
17199            }
17200        }
17201    }
17202
17203    void backgroundServicesFinishedLocked(int userId) {
17204        for (BroadcastQueue queue : mBroadcastQueues) {
17205            queue.backgroundServicesFinishedLocked(userId);
17206        }
17207    }
17208
17209    public void finishReceiver(IBinder who, int resultCode, String resultData,
17210            Bundle resultExtras, boolean resultAbort, int flags) {
17211        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17212
17213        // Refuse possible leaked file descriptors
17214        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17215            throw new IllegalArgumentException("File descriptors passed in Bundle");
17216        }
17217
17218        final long origId = Binder.clearCallingIdentity();
17219        try {
17220            boolean doNext = false;
17221            BroadcastRecord r;
17222
17223            synchronized(this) {
17224                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17225                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17226                r = queue.getMatchingOrderedReceiver(who);
17227                if (r != null) {
17228                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17229                        resultData, resultExtras, resultAbort, true);
17230                }
17231            }
17232
17233            if (doNext) {
17234                r.queue.processNextBroadcast(false);
17235            }
17236            trimApplications();
17237        } finally {
17238            Binder.restoreCallingIdentity(origId);
17239        }
17240    }
17241
17242    // =========================================================
17243    // INSTRUMENTATION
17244    // =========================================================
17245
17246    public boolean startInstrumentation(ComponentName className,
17247            String profileFile, int flags, Bundle arguments,
17248            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17249            int userId, String abiOverride) {
17250        enforceNotIsolatedCaller("startInstrumentation");
17251        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17252                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17253        // Refuse possible leaked file descriptors
17254        if (arguments != null && arguments.hasFileDescriptors()) {
17255            throw new IllegalArgumentException("File descriptors passed in Bundle");
17256        }
17257
17258        synchronized(this) {
17259            InstrumentationInfo ii = null;
17260            ApplicationInfo ai = null;
17261            try {
17262                ii = mContext.getPackageManager().getInstrumentationInfo(
17263                    className, STOCK_PM_FLAGS);
17264                ai = AppGlobals.getPackageManager().getApplicationInfo(
17265                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17266            } catch (PackageManager.NameNotFoundException e) {
17267            } catch (RemoteException e) {
17268            }
17269            if (ii == null) {
17270                reportStartInstrumentationFailure(watcher, className,
17271                        "Unable to find instrumentation info for: " + className);
17272                return false;
17273            }
17274            if (ai == null) {
17275                reportStartInstrumentationFailure(watcher, className,
17276                        "Unable to find instrumentation target package: " + ii.targetPackage);
17277                return false;
17278            }
17279
17280            int match = mContext.getPackageManager().checkSignatures(
17281                    ii.targetPackage, ii.packageName);
17282            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17283                String msg = "Permission Denial: starting instrumentation "
17284                        + className + " from pid="
17285                        + Binder.getCallingPid()
17286                        + ", uid=" + Binder.getCallingPid()
17287                        + " not allowed because package " + ii.packageName
17288                        + " does not have a signature matching the target "
17289                        + ii.targetPackage;
17290                reportStartInstrumentationFailure(watcher, className, msg);
17291                throw new SecurityException(msg);
17292            }
17293
17294            final long origId = Binder.clearCallingIdentity();
17295            // Instrumentation can kill and relaunch even persistent processes
17296            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17297                    "start instr");
17298            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17299            app.instrumentationClass = className;
17300            app.instrumentationInfo = ai;
17301            app.instrumentationProfileFile = profileFile;
17302            app.instrumentationArguments = arguments;
17303            app.instrumentationWatcher = watcher;
17304            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17305            app.instrumentationResultClass = className;
17306            Binder.restoreCallingIdentity(origId);
17307        }
17308
17309        return true;
17310    }
17311
17312    /**
17313     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17314     * error to the logs, but if somebody is watching, send the report there too.  This enables
17315     * the "am" command to report errors with more information.
17316     *
17317     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17318     * @param cn The component name of the instrumentation.
17319     * @param report The error report.
17320     */
17321    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17322            ComponentName cn, String report) {
17323        Slog.w(TAG, report);
17324        try {
17325            if (watcher != null) {
17326                Bundle results = new Bundle();
17327                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17328                results.putString("Error", report);
17329                watcher.instrumentationStatus(cn, -1, results);
17330            }
17331        } catch (RemoteException e) {
17332            Slog.w(TAG, e);
17333        }
17334    }
17335
17336    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17337        if (app.instrumentationWatcher != null) {
17338            try {
17339                // NOTE:  IInstrumentationWatcher *must* be oneway here
17340                app.instrumentationWatcher.instrumentationFinished(
17341                    app.instrumentationClass,
17342                    resultCode,
17343                    results);
17344            } catch (RemoteException e) {
17345            }
17346        }
17347
17348        // Can't call out of the system process with a lock held, so post a message.
17349        if (app.instrumentationUiAutomationConnection != null) {
17350            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17351                    app.instrumentationUiAutomationConnection).sendToTarget();
17352        }
17353
17354        app.instrumentationWatcher = null;
17355        app.instrumentationUiAutomationConnection = null;
17356        app.instrumentationClass = null;
17357        app.instrumentationInfo = null;
17358        app.instrumentationProfileFile = null;
17359        app.instrumentationArguments = null;
17360
17361        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17362                "finished inst");
17363    }
17364
17365    public void finishInstrumentation(IApplicationThread target,
17366            int resultCode, Bundle results) {
17367        int userId = UserHandle.getCallingUserId();
17368        // Refuse possible leaked file descriptors
17369        if (results != null && results.hasFileDescriptors()) {
17370            throw new IllegalArgumentException("File descriptors passed in Intent");
17371        }
17372
17373        synchronized(this) {
17374            ProcessRecord app = getRecordForAppLocked(target);
17375            if (app == null) {
17376                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17377                return;
17378            }
17379            final long origId = Binder.clearCallingIdentity();
17380            finishInstrumentationLocked(app, resultCode, results);
17381            Binder.restoreCallingIdentity(origId);
17382        }
17383    }
17384
17385    // =========================================================
17386    // CONFIGURATION
17387    // =========================================================
17388
17389    public ConfigurationInfo getDeviceConfigurationInfo() {
17390        ConfigurationInfo config = new ConfigurationInfo();
17391        synchronized (this) {
17392            config.reqTouchScreen = mConfiguration.touchscreen;
17393            config.reqKeyboardType = mConfiguration.keyboard;
17394            config.reqNavigation = mConfiguration.navigation;
17395            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17396                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17397                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17398            }
17399            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17400                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17401                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17402            }
17403            config.reqGlEsVersion = GL_ES_VERSION;
17404        }
17405        return config;
17406    }
17407
17408    ActivityStack getFocusedStack() {
17409        return mStackSupervisor.getFocusedStack();
17410    }
17411
17412    @Override
17413    public int getFocusedStackId() throws RemoteException {
17414        ActivityStack focusedStack = getFocusedStack();
17415        if (focusedStack != null) {
17416            return focusedStack.getStackId();
17417        }
17418        return -1;
17419    }
17420
17421    public Configuration getConfiguration() {
17422        Configuration ci;
17423        synchronized(this) {
17424            ci = new Configuration(mConfiguration);
17425            ci.userSetLocale = false;
17426        }
17427        return ci;
17428    }
17429
17430    @Override
17431    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17432        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17433                "suppressResizeConfigChanges()");
17434        synchronized (this) {
17435            mSuppressResizeConfigChanges = suppress;
17436        }
17437    }
17438
17439    @Override
17440    public void removeStack(int stackId) {
17441        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17442                "detahStack()");
17443        if (stackId == HOME_STACK_ID) {
17444            throw new IllegalArgumentException("Removing home stack is not allowed.");
17445        }
17446        synchronized (this) {
17447            ActivityStack stack = mStackSupervisor.getStack(stackId);
17448            if (stack != null) {
17449                ArrayList<TaskRecord> tasks = stack.getAllTasks();
17450                for (int i = tasks.size() - 1; i >= 0; i--) {
17451                    removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
17452                            !REMOVE_FROM_RECENTS);
17453                }
17454            }
17455        }
17456    }
17457
17458    @Override
17459    public void updatePersistentConfiguration(Configuration values) {
17460        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17461                "updateConfiguration()");
17462        enforceWriteSettingsPermission("updateConfiguration()");
17463        if (values == null) {
17464            throw new NullPointerException("Configuration must not be null");
17465        }
17466
17467        int userId = UserHandle.getCallingUserId();
17468
17469        synchronized(this) {
17470            final long origId = Binder.clearCallingIdentity();
17471            updateConfigurationLocked(values, null, false, true, userId);
17472            Binder.restoreCallingIdentity(origId);
17473        }
17474    }
17475
17476    private void enforceWriteSettingsPermission(String func) {
17477        int uid = Binder.getCallingUid();
17478        if (uid == Process.ROOT_UID) {
17479            return;
17480        }
17481
17482        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17483                Settings.getPackageNameForUid(mContext, uid), false)) {
17484            return;
17485        }
17486
17487        String msg = "Permission Denial: " + func + " from pid="
17488                + Binder.getCallingPid()
17489                + ", uid=" + uid
17490                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17491        Slog.w(TAG, msg);
17492        throw new SecurityException(msg);
17493    }
17494
17495    public void updateConfiguration(Configuration values) {
17496        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17497                "updateConfiguration()");
17498
17499        synchronized(this) {
17500            if (values == null && mWindowManager != null) {
17501                // sentinel: fetch the current configuration from the window manager
17502                values = mWindowManager.computeNewConfiguration();
17503            }
17504
17505            if (mWindowManager != null) {
17506                mProcessList.applyDisplaySize(mWindowManager);
17507            }
17508
17509            final long origId = Binder.clearCallingIdentity();
17510            if (values != null) {
17511                Settings.System.clearConfiguration(values);
17512            }
17513            updateConfigurationLocked(values, null, false);
17514            Binder.restoreCallingIdentity(origId);
17515        }
17516    }
17517
17518    void updateUserConfigurationLocked() {
17519        Configuration configuration = new Configuration(mConfiguration);
17520        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17521                mUserController.getCurrentUserIdLocked());
17522        updateConfigurationLocked(configuration, null, false);
17523    }
17524
17525    boolean updateConfigurationLocked(Configuration values,
17526            ActivityRecord starting, boolean initLocale) {
17527        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17528        return updateConfigurationLocked(values, starting, initLocale, false,
17529                UserHandle.USER_NULL);
17530    }
17531
17532    /**
17533     * Do either or both things: (1) change the current configuration, and (2)
17534     * make sure the given activity is running with the (now) current
17535     * configuration.  Returns true if the activity has been left running, or
17536     * false if <var>starting</var> is being destroyed to match the new
17537     * configuration.
17538     *
17539     * @param userId is only used when persistent parameter is set to true to persist configuration
17540     *               for that particular user
17541     */
17542    boolean updateConfigurationLocked(Configuration values,
17543            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17544        int changes = 0;
17545
17546        if (values != null) {
17547            Configuration newConfig = new Configuration(mConfiguration);
17548            changes = newConfig.updateFrom(values);
17549            if (changes != 0) {
17550                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17551                        "Updating configuration to: " + values);
17552
17553                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17554
17555                if (!initLocale && values.locale != null && values.userSetLocale) {
17556                    final String languageTag = values.locale.toLanguageTag();
17557                    SystemProperties.set("persist.sys.locale", languageTag);
17558                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17559                            values.locale));
17560                }
17561
17562                mConfigurationSeq++;
17563                if (mConfigurationSeq <= 0) {
17564                    mConfigurationSeq = 1;
17565                }
17566                newConfig.seq = mConfigurationSeq;
17567                mConfiguration = newConfig;
17568                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17569                mUsageStatsService.reportConfigurationChange(newConfig,
17570                        mUserController.getCurrentUserIdLocked());
17571                //mUsageStatsService.noteStartConfig(newConfig);
17572
17573                final Configuration configCopy = new Configuration(mConfiguration);
17574
17575                // TODO: If our config changes, should we auto dismiss any currently
17576                // showing dialogs?
17577                mShowDialogs = shouldShowDialogs(newConfig);
17578
17579                AttributeCache ac = AttributeCache.instance();
17580                if (ac != null) {
17581                    ac.updateConfiguration(configCopy);
17582                }
17583
17584                // Make sure all resources in our process are updated
17585                // right now, so that anyone who is going to retrieve
17586                // resource values after we return will be sure to get
17587                // the new ones.  This is especially important during
17588                // boot, where the first config change needs to guarantee
17589                // all resources have that config before following boot
17590                // code is executed.
17591                mSystemThread.applyConfigurationToResources(configCopy);
17592
17593                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17594                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17595                    msg.obj = new Configuration(configCopy);
17596                    msg.arg1 = userId;
17597                    mHandler.sendMessage(msg);
17598                }
17599
17600                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17601                    ProcessRecord app = mLruProcesses.get(i);
17602                    try {
17603                        if (app.thread != null) {
17604                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17605                                    + app.processName + " new config " + mConfiguration);
17606                            app.thread.scheduleConfigurationChanged(configCopy);
17607                        }
17608                    } catch (Exception e) {
17609                    }
17610                }
17611                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17612                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17613                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17614                        | Intent.FLAG_RECEIVER_FOREGROUND);
17615                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17616                        null, AppOpsManager.OP_NONE, null, false, false,
17617                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17618                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17619                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17620                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17621                    if (!mProcessesReady) {
17622                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17623                    }
17624                    broadcastIntentLocked(null, null, intent,
17625                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17626                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17627                }
17628            }
17629        }
17630
17631        boolean kept = true;
17632        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17633        // mainStack is null during startup.
17634        if (mainStack != null) {
17635            if (changes != 0 && starting == null) {
17636                // If the configuration changed, and the caller is not already
17637                // in the process of starting an activity, then find the top
17638                // activity to check if its configuration needs to change.
17639                starting = mainStack.topRunningActivityLocked();
17640            }
17641
17642            if (starting != null) {
17643                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17644                // And we need to make sure at this point that all other activities
17645                // are made visible with the correct configuration.
17646                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17647                        !PRESERVE_WINDOWS);
17648            }
17649        }
17650
17651        if (values != null && mWindowManager != null) {
17652            mWindowManager.setNewConfiguration(mConfiguration);
17653        }
17654
17655        return kept;
17656    }
17657
17658    /**
17659     * Decide based on the configuration whether we should shouw the ANR,
17660     * crash, etc dialogs.  The idea is that if there is no affordnace to
17661     * press the on-screen buttons, we shouldn't show the dialog.
17662     *
17663     * A thought: SystemUI might also want to get told about this, the Power
17664     * dialog / global actions also might want different behaviors.
17665     */
17666    private static final boolean shouldShowDialogs(Configuration config) {
17667        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17668                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17669                && config.navigation == Configuration.NAVIGATION_NONAV);
17670    }
17671
17672    @Override
17673    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17674        synchronized (this) {
17675            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17676            if (srec != null) {
17677                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17678            }
17679        }
17680        return false;
17681    }
17682
17683    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17684            Intent resultData) {
17685
17686        synchronized (this) {
17687            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17688            if (r != null) {
17689                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17690            }
17691            return false;
17692        }
17693    }
17694
17695    public int getLaunchedFromUid(IBinder activityToken) {
17696        ActivityRecord srec;
17697        synchronized (this) {
17698            srec = ActivityRecord.forTokenLocked(activityToken);
17699        }
17700        if (srec == null) {
17701            return -1;
17702        }
17703        return srec.launchedFromUid;
17704    }
17705
17706    public String getLaunchedFromPackage(IBinder activityToken) {
17707        ActivityRecord srec;
17708        synchronized (this) {
17709            srec = ActivityRecord.forTokenLocked(activityToken);
17710        }
17711        if (srec == null) {
17712            return null;
17713        }
17714        return srec.launchedFromPackage;
17715    }
17716
17717    // =========================================================
17718    // LIFETIME MANAGEMENT
17719    // =========================================================
17720
17721    // Returns which broadcast queue the app is the current [or imminent] receiver
17722    // on, or 'null' if the app is not an active broadcast recipient.
17723    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17724        BroadcastRecord r = app.curReceiver;
17725        if (r != null) {
17726            return r.queue;
17727        }
17728
17729        // It's not the current receiver, but it might be starting up to become one
17730        synchronized (this) {
17731            for (BroadcastQueue queue : mBroadcastQueues) {
17732                r = queue.mPendingBroadcast;
17733                if (r != null && r.curApp == app) {
17734                    // found it; report which queue it's in
17735                    return queue;
17736                }
17737            }
17738        }
17739
17740        return null;
17741    }
17742
17743    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17744            ComponentName targetComponent, String targetProcess) {
17745        if (!mTrackingAssociations) {
17746            return null;
17747        }
17748        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17749                = mAssociations.get(targetUid);
17750        if (components == null) {
17751            components = new ArrayMap<>();
17752            mAssociations.put(targetUid, components);
17753        }
17754        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17755        if (sourceUids == null) {
17756            sourceUids = new SparseArray<>();
17757            components.put(targetComponent, sourceUids);
17758        }
17759        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17760        if (sourceProcesses == null) {
17761            sourceProcesses = new ArrayMap<>();
17762            sourceUids.put(sourceUid, sourceProcesses);
17763        }
17764        Association ass = sourceProcesses.get(sourceProcess);
17765        if (ass == null) {
17766            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17767                    targetProcess);
17768            sourceProcesses.put(sourceProcess, ass);
17769        }
17770        ass.mCount++;
17771        ass.mNesting++;
17772        if (ass.mNesting == 1) {
17773            ass.mStartTime = SystemClock.uptimeMillis();
17774        }
17775        return ass;
17776    }
17777
17778    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17779            ComponentName targetComponent) {
17780        if (!mTrackingAssociations) {
17781            return;
17782        }
17783        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17784                = mAssociations.get(targetUid);
17785        if (components == null) {
17786            return;
17787        }
17788        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17789        if (sourceUids == null) {
17790            return;
17791        }
17792        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17793        if (sourceProcesses == null) {
17794            return;
17795        }
17796        Association ass = sourceProcesses.get(sourceProcess);
17797        if (ass == null || ass.mNesting <= 0) {
17798            return;
17799        }
17800        ass.mNesting--;
17801        if (ass.mNesting == 0) {
17802            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17803        }
17804    }
17805
17806    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17807            boolean doingAll, long now) {
17808        if (mAdjSeq == app.adjSeq) {
17809            // This adjustment has already been computed.
17810            return app.curRawAdj;
17811        }
17812
17813        if (app.thread == null) {
17814            app.adjSeq = mAdjSeq;
17815            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17816            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17817            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17818        }
17819
17820        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17821        app.adjSource = null;
17822        app.adjTarget = null;
17823        app.empty = false;
17824        app.cached = false;
17825
17826        final int activitiesSize = app.activities.size();
17827
17828        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17829            // The max adjustment doesn't allow this app to be anything
17830            // below foreground, so it is not worth doing work for it.
17831            app.adjType = "fixed";
17832            app.adjSeq = mAdjSeq;
17833            app.curRawAdj = app.maxAdj;
17834            app.foregroundActivities = false;
17835            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17836            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17837            // System processes can do UI, and when they do we want to have
17838            // them trim their memory after the user leaves the UI.  To
17839            // facilitate this, here we need to determine whether or not it
17840            // is currently showing UI.
17841            app.systemNoUi = true;
17842            if (app == TOP_APP) {
17843                app.systemNoUi = false;
17844            } else if (activitiesSize > 0) {
17845                for (int j = 0; j < activitiesSize; j++) {
17846                    final ActivityRecord r = app.activities.get(j);
17847                    if (r.visible) {
17848                        app.systemNoUi = false;
17849                    }
17850                }
17851            }
17852            if (!app.systemNoUi) {
17853                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17854            }
17855            return (app.curAdj=app.maxAdj);
17856        }
17857
17858        app.systemNoUi = false;
17859
17860        final int PROCESS_STATE_TOP = mTopProcessState;
17861
17862        // Determine the importance of the process, starting with most
17863        // important to least, and assign an appropriate OOM adjustment.
17864        int adj;
17865        int schedGroup;
17866        int procState;
17867        boolean foregroundActivities = false;
17868        BroadcastQueue queue;
17869        if (app == TOP_APP) {
17870            // The last app on the list is the foreground app.
17871            adj = ProcessList.FOREGROUND_APP_ADJ;
17872            schedGroup = Process.THREAD_GROUP_DEFAULT;
17873            app.adjType = "top-activity";
17874            foregroundActivities = true;
17875            procState = PROCESS_STATE_TOP;
17876        } else if (app.instrumentationClass != null) {
17877            // Don't want to kill running instrumentation.
17878            adj = ProcessList.FOREGROUND_APP_ADJ;
17879            schedGroup = Process.THREAD_GROUP_DEFAULT;
17880            app.adjType = "instrumentation";
17881            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17882        } else if ((queue = isReceivingBroadcast(app)) != null) {
17883            // An app that is currently receiving a broadcast also
17884            // counts as being in the foreground for OOM killer purposes.
17885            // It's placed in a sched group based on the nature of the
17886            // broadcast as reflected by which queue it's active in.
17887            adj = ProcessList.FOREGROUND_APP_ADJ;
17888            schedGroup = (queue == mFgBroadcastQueue)
17889                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17890            app.adjType = "broadcast";
17891            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17892        } else if (app.executingServices.size() > 0) {
17893            // An app that is currently executing a service callback also
17894            // counts as being in the foreground.
17895            adj = ProcessList.FOREGROUND_APP_ADJ;
17896            schedGroup = app.execServicesFg ?
17897                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17898            app.adjType = "exec-service";
17899            procState = ActivityManager.PROCESS_STATE_SERVICE;
17900            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17901        } else {
17902            // As far as we know the process is empty.  We may change our mind later.
17903            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17904            // At this point we don't actually know the adjustment.  Use the cached adj
17905            // value that the caller wants us to.
17906            adj = cachedAdj;
17907            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17908            app.cached = true;
17909            app.empty = true;
17910            app.adjType = "cch-empty";
17911        }
17912
17913        // Examine all activities if not already foreground.
17914        if (!foregroundActivities && activitiesSize > 0) {
17915            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
17916            for (int j = 0; j < activitiesSize; j++) {
17917                final ActivityRecord r = app.activities.get(j);
17918                if (r.app != app) {
17919                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17920                            + app + "?!? Using " + r.app + " instead.");
17921                    continue;
17922                }
17923                if (r.visible) {
17924                    // App has a visible activity; only upgrade adjustment.
17925                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17926                        adj = ProcessList.VISIBLE_APP_ADJ;
17927                        app.adjType = "visible";
17928                    }
17929                    if (procState > PROCESS_STATE_TOP) {
17930                        procState = PROCESS_STATE_TOP;
17931                    }
17932                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17933                    app.cached = false;
17934                    app.empty = false;
17935                    foregroundActivities = true;
17936                    if (r.task != null && minLayer > 0) {
17937                        final int layer = r.task.mLayerRank;
17938                        if (layer >= 0 && minLayer > layer) {
17939                            minLayer = layer;
17940                        }
17941                    }
17942                    break;
17943                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17944                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17945                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17946                        app.adjType = "pausing";
17947                    }
17948                    if (procState > PROCESS_STATE_TOP) {
17949                        procState = PROCESS_STATE_TOP;
17950                    }
17951                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17952                    app.cached = false;
17953                    app.empty = false;
17954                    foregroundActivities = true;
17955                } else if (r.state == ActivityState.STOPPING) {
17956                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17957                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17958                        app.adjType = "stopping";
17959                    }
17960                    // For the process state, we will at this point consider the
17961                    // process to be cached.  It will be cached either as an activity
17962                    // or empty depending on whether the activity is finishing.  We do
17963                    // this so that we can treat the process as cached for purposes of
17964                    // memory trimming (determing current memory level, trim command to
17965                    // send to process) since there can be an arbitrary number of stopping
17966                    // processes and they should soon all go into the cached state.
17967                    if (!r.finishing) {
17968                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17969                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17970                        }
17971                    }
17972                    app.cached = false;
17973                    app.empty = false;
17974                    foregroundActivities = true;
17975                } else {
17976                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17977                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17978                        app.adjType = "cch-act";
17979                    }
17980                }
17981            }
17982            if (adj == ProcessList.VISIBLE_APP_ADJ) {
17983                adj += minLayer;
17984            }
17985        }
17986
17987        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17988            if (app.foregroundServices) {
17989                // The user is aware of this app, so make it visible.
17990                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17991                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17992                app.cached = false;
17993                app.adjType = "fg-service";
17994                schedGroup = Process.THREAD_GROUP_DEFAULT;
17995            } else if (app.forcingToForeground != null) {
17996                // The user is aware of this app, so make it visible.
17997                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17998                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17999                app.cached = false;
18000                app.adjType = "force-fg";
18001                app.adjSource = app.forcingToForeground;
18002                schedGroup = Process.THREAD_GROUP_DEFAULT;
18003            }
18004        }
18005
18006        if (app == mHeavyWeightProcess) {
18007            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18008                // We don't want to kill the current heavy-weight process.
18009                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18010                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18011                app.cached = false;
18012                app.adjType = "heavy";
18013            }
18014            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18015                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18016            }
18017        }
18018
18019        if (app == mHomeProcess) {
18020            if (adj > ProcessList.HOME_APP_ADJ) {
18021                // This process is hosting what we currently consider to be the
18022                // home app, so we don't want to let it go into the background.
18023                adj = ProcessList.HOME_APP_ADJ;
18024                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18025                app.cached = false;
18026                app.adjType = "home";
18027            }
18028            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18029                procState = ActivityManager.PROCESS_STATE_HOME;
18030            }
18031        }
18032
18033        if (app == mPreviousProcess && app.activities.size() > 0) {
18034            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18035                // This was the previous process that showed UI to the user.
18036                // We want to try to keep it around more aggressively, to give
18037                // a good experience around switching between two apps.
18038                adj = ProcessList.PREVIOUS_APP_ADJ;
18039                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18040                app.cached = false;
18041                app.adjType = "previous";
18042            }
18043            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18044                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18045            }
18046        }
18047
18048        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18049                + " reason=" + app.adjType);
18050
18051        // By default, we use the computed adjustment.  It may be changed if
18052        // there are applications dependent on our services or providers, but
18053        // this gives us a baseline and makes sure we don't get into an
18054        // infinite recursion.
18055        app.adjSeq = mAdjSeq;
18056        app.curRawAdj = adj;
18057        app.hasStartedServices = false;
18058
18059        if (mBackupTarget != null && app == mBackupTarget.app) {
18060            // If possible we want to avoid killing apps while they're being backed up
18061            if (adj > ProcessList.BACKUP_APP_ADJ) {
18062                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18063                adj = ProcessList.BACKUP_APP_ADJ;
18064                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18065                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18066                }
18067                app.adjType = "backup";
18068                app.cached = false;
18069            }
18070            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18071                procState = ActivityManager.PROCESS_STATE_BACKUP;
18072            }
18073        }
18074
18075        boolean mayBeTop = false;
18076
18077        for (int is = app.services.size()-1;
18078                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18079                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18080                        || procState > ActivityManager.PROCESS_STATE_TOP);
18081                is--) {
18082            ServiceRecord s = app.services.valueAt(is);
18083            if (s.startRequested) {
18084                app.hasStartedServices = true;
18085                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18086                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18087                }
18088                if (app.hasShownUi && app != mHomeProcess) {
18089                    // If this process has shown some UI, let it immediately
18090                    // go to the LRU list because it may be pretty heavy with
18091                    // UI stuff.  We'll tag it with a label just to help
18092                    // debug and understand what is going on.
18093                    if (adj > ProcessList.SERVICE_ADJ) {
18094                        app.adjType = "cch-started-ui-services";
18095                    }
18096                } else {
18097                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18098                        // This service has seen some activity within
18099                        // recent memory, so we will keep its process ahead
18100                        // of the background processes.
18101                        if (adj > ProcessList.SERVICE_ADJ) {
18102                            adj = ProcessList.SERVICE_ADJ;
18103                            app.adjType = "started-services";
18104                            app.cached = false;
18105                        }
18106                    }
18107                    // If we have let the service slide into the background
18108                    // state, still have some text describing what it is doing
18109                    // even though the service no longer has an impact.
18110                    if (adj > ProcessList.SERVICE_ADJ) {
18111                        app.adjType = "cch-started-services";
18112                    }
18113                }
18114            }
18115            for (int conni = s.connections.size()-1;
18116                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18117                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18118                            || procState > ActivityManager.PROCESS_STATE_TOP);
18119                    conni--) {
18120                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18121                for (int i = 0;
18122                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18123                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18124                                || procState > ActivityManager.PROCESS_STATE_TOP);
18125                        i++) {
18126                    // XXX should compute this based on the max of
18127                    // all connected clients.
18128                    ConnectionRecord cr = clist.get(i);
18129                    if (cr.binding.client == app) {
18130                        // Binding to ourself is not interesting.
18131                        continue;
18132                    }
18133                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18134                        ProcessRecord client = cr.binding.client;
18135                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18136                                TOP_APP, doingAll, now);
18137                        int clientProcState = client.curProcState;
18138                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18139                            // If the other app is cached for any reason, for purposes here
18140                            // we are going to consider it empty.  The specific cached state
18141                            // doesn't propagate except under certain conditions.
18142                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18143                        }
18144                        String adjType = null;
18145                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18146                            // Not doing bind OOM management, so treat
18147                            // this guy more like a started service.
18148                            if (app.hasShownUi && app != mHomeProcess) {
18149                                // If this process has shown some UI, let it immediately
18150                                // go to the LRU list because it may be pretty heavy with
18151                                // UI stuff.  We'll tag it with a label just to help
18152                                // debug and understand what is going on.
18153                                if (adj > clientAdj) {
18154                                    adjType = "cch-bound-ui-services";
18155                                }
18156                                app.cached = false;
18157                                clientAdj = adj;
18158                                clientProcState = procState;
18159                            } else {
18160                                if (now >= (s.lastActivity
18161                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18162                                    // This service has not seen activity within
18163                                    // recent memory, so allow it to drop to the
18164                                    // LRU list if there is no other reason to keep
18165                                    // it around.  We'll also tag it with a label just
18166                                    // to help debug and undertand what is going on.
18167                                    if (adj > clientAdj) {
18168                                        adjType = "cch-bound-services";
18169                                    }
18170                                    clientAdj = adj;
18171                                }
18172                            }
18173                        }
18174                        if (adj > clientAdj) {
18175                            // If this process has recently shown UI, and
18176                            // the process that is binding to it is less
18177                            // important than being visible, then we don't
18178                            // care about the binding as much as we care
18179                            // about letting this process get into the LRU
18180                            // list to be killed and restarted if needed for
18181                            // memory.
18182                            if (app.hasShownUi && app != mHomeProcess
18183                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18184                                adjType = "cch-bound-ui-services";
18185                            } else {
18186                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18187                                        |Context.BIND_IMPORTANT)) != 0) {
18188                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18189                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18190                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18191                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18192                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18193                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18194                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18195                                    adj = clientAdj;
18196                                } else {
18197                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18198                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18199                                    }
18200                                }
18201                                if (!client.cached) {
18202                                    app.cached = false;
18203                                }
18204                                adjType = "service";
18205                            }
18206                        }
18207                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18208                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18209                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18210                            }
18211                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18212                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18213                                    // Special handling of clients who are in the top state.
18214                                    // We *may* want to consider this process to be in the
18215                                    // top state as well, but only if there is not another
18216                                    // reason for it to be running.  Being on the top is a
18217                                    // special state, meaning you are specifically running
18218                                    // for the current top app.  If the process is already
18219                                    // running in the background for some other reason, it
18220                                    // is more important to continue considering it to be
18221                                    // in the background state.
18222                                    mayBeTop = true;
18223                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18224                                } else {
18225                                    // Special handling for above-top states (persistent
18226                                    // processes).  These should not bring the current process
18227                                    // into the top state, since they are not on top.  Instead
18228                                    // give them the best state after that.
18229                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18230                                        clientProcState =
18231                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18232                                    } else if (mWakefulness
18233                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18234                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18235                                                    != 0) {
18236                                        clientProcState =
18237                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18238                                    } else {
18239                                        clientProcState =
18240                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18241                                    }
18242                                }
18243                            }
18244                        } else {
18245                            if (clientProcState <
18246                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18247                                clientProcState =
18248                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18249                            }
18250                        }
18251                        if (procState > clientProcState) {
18252                            procState = clientProcState;
18253                        }
18254                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18255                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18256                            app.pendingUiClean = true;
18257                        }
18258                        if (adjType != null) {
18259                            app.adjType = adjType;
18260                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18261                                    .REASON_SERVICE_IN_USE;
18262                            app.adjSource = cr.binding.client;
18263                            app.adjSourceProcState = clientProcState;
18264                            app.adjTarget = s.name;
18265                        }
18266                    }
18267                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18268                        app.treatLikeActivity = true;
18269                    }
18270                    final ActivityRecord a = cr.activity;
18271                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18272                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18273                                (a.visible || a.state == ActivityState.RESUMED
18274                                 || a.state == ActivityState.PAUSING)) {
18275                            adj = ProcessList.FOREGROUND_APP_ADJ;
18276                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18277                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18278                            }
18279                            app.cached = false;
18280                            app.adjType = "service";
18281                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18282                                    .REASON_SERVICE_IN_USE;
18283                            app.adjSource = a;
18284                            app.adjSourceProcState = procState;
18285                            app.adjTarget = s.name;
18286                        }
18287                    }
18288                }
18289            }
18290        }
18291
18292        for (int provi = app.pubProviders.size()-1;
18293                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18294                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18295                        || procState > ActivityManager.PROCESS_STATE_TOP);
18296                provi--) {
18297            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18298            for (int i = cpr.connections.size()-1;
18299                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18300                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18301                            || procState > ActivityManager.PROCESS_STATE_TOP);
18302                    i--) {
18303                ContentProviderConnection conn = cpr.connections.get(i);
18304                ProcessRecord client = conn.client;
18305                if (client == app) {
18306                    // Being our own client is not interesting.
18307                    continue;
18308                }
18309                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18310                int clientProcState = client.curProcState;
18311                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18312                    // If the other app is cached for any reason, for purposes here
18313                    // we are going to consider it empty.
18314                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18315                }
18316                if (adj > clientAdj) {
18317                    if (app.hasShownUi && app != mHomeProcess
18318                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18319                        app.adjType = "cch-ui-provider";
18320                    } else {
18321                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18322                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18323                        app.adjType = "provider";
18324                    }
18325                    app.cached &= client.cached;
18326                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18327                            .REASON_PROVIDER_IN_USE;
18328                    app.adjSource = client;
18329                    app.adjSourceProcState = clientProcState;
18330                    app.adjTarget = cpr.name;
18331                }
18332                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18333                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18334                        // Special handling of clients who are in the top state.
18335                        // We *may* want to consider this process to be in the
18336                        // top state as well, but only if there is not another
18337                        // reason for it to be running.  Being on the top is a
18338                        // special state, meaning you are specifically running
18339                        // for the current top app.  If the process is already
18340                        // running in the background for some other reason, it
18341                        // is more important to continue considering it to be
18342                        // in the background state.
18343                        mayBeTop = true;
18344                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18345                    } else {
18346                        // Special handling for above-top states (persistent
18347                        // processes).  These should not bring the current process
18348                        // into the top state, since they are not on top.  Instead
18349                        // give them the best state after that.
18350                        clientProcState =
18351                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18352                    }
18353                }
18354                if (procState > clientProcState) {
18355                    procState = clientProcState;
18356                }
18357                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18358                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18359                }
18360            }
18361            // If the provider has external (non-framework) process
18362            // dependencies, ensure that its adjustment is at least
18363            // FOREGROUND_APP_ADJ.
18364            if (cpr.hasExternalProcessHandles()) {
18365                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18366                    adj = ProcessList.FOREGROUND_APP_ADJ;
18367                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18368                    app.cached = false;
18369                    app.adjType = "provider";
18370                    app.adjTarget = cpr.name;
18371                }
18372                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18373                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18374                }
18375            }
18376        }
18377
18378        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18379            // A client of one of our services or providers is in the top state.  We
18380            // *may* want to be in the top state, but not if we are already running in
18381            // the background for some other reason.  For the decision here, we are going
18382            // to pick out a few specific states that we want to remain in when a client
18383            // is top (states that tend to be longer-term) and otherwise allow it to go
18384            // to the top state.
18385            switch (procState) {
18386                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18387                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18388                case ActivityManager.PROCESS_STATE_SERVICE:
18389                    // These all are longer-term states, so pull them up to the top
18390                    // of the background states, but not all the way to the top state.
18391                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18392                    break;
18393                default:
18394                    // Otherwise, top is a better choice, so take it.
18395                    procState = ActivityManager.PROCESS_STATE_TOP;
18396                    break;
18397            }
18398        }
18399
18400        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18401            if (app.hasClientActivities) {
18402                // This is a cached process, but with client activities.  Mark it so.
18403                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18404                app.adjType = "cch-client-act";
18405            } else if (app.treatLikeActivity) {
18406                // This is a cached process, but somebody wants us to treat it like it has
18407                // an activity, okay!
18408                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18409                app.adjType = "cch-as-act";
18410            }
18411        }
18412
18413        if (adj == ProcessList.SERVICE_ADJ) {
18414            if (doingAll) {
18415                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18416                mNewNumServiceProcs++;
18417                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18418                if (!app.serviceb) {
18419                    // This service isn't far enough down on the LRU list to
18420                    // normally be a B service, but if we are low on RAM and it
18421                    // is large we want to force it down since we would prefer to
18422                    // keep launcher over it.
18423                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18424                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18425                        app.serviceHighRam = true;
18426                        app.serviceb = true;
18427                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18428                    } else {
18429                        mNewNumAServiceProcs++;
18430                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18431                    }
18432                } else {
18433                    app.serviceHighRam = false;
18434                }
18435            }
18436            if (app.serviceb) {
18437                adj = ProcessList.SERVICE_B_ADJ;
18438            }
18439        }
18440
18441        app.curRawAdj = adj;
18442
18443        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18444        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18445        if (adj > app.maxAdj) {
18446            adj = app.maxAdj;
18447            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18448                schedGroup = Process.THREAD_GROUP_DEFAULT;
18449            }
18450        }
18451
18452        // Do final modification to adj.  Everything we do between here and applying
18453        // the final setAdj must be done in this function, because we will also use
18454        // it when computing the final cached adj later.  Note that we don't need to
18455        // worry about this for max adj above, since max adj will always be used to
18456        // keep it out of the cached vaues.
18457        app.curAdj = app.modifyRawOomAdj(adj);
18458        app.curSchedGroup = schedGroup;
18459        app.curProcState = procState;
18460        app.foregroundActivities = foregroundActivities;
18461
18462        return app.curRawAdj;
18463    }
18464
18465    /**
18466     * Record new PSS sample for a process.
18467     */
18468    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18469        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18470        proc.lastPssTime = now;
18471        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18472        if (DEBUG_PSS) Slog.d(TAG_PSS,
18473                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18474                + " state=" + ProcessList.makeProcStateString(procState));
18475        if (proc.initialIdlePss == 0) {
18476            proc.initialIdlePss = pss;
18477        }
18478        proc.lastPss = pss;
18479        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18480            proc.lastCachedPss = pss;
18481        }
18482
18483        final SparseArray<Pair<Long, String>> watchUids
18484                = mMemWatchProcesses.getMap().get(proc.processName);
18485        Long check = null;
18486        if (watchUids != null) {
18487            Pair<Long, String> val = watchUids.get(proc.uid);
18488            if (val == null) {
18489                val = watchUids.get(0);
18490            }
18491            if (val != null) {
18492                check = val.first;
18493            }
18494        }
18495        if (check != null) {
18496            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18497                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18498                if (!isDebuggable) {
18499                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18500                        isDebuggable = true;
18501                    }
18502                }
18503                if (isDebuggable) {
18504                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18505                    final ProcessRecord myProc = proc;
18506                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18507                    mMemWatchDumpProcName = proc.processName;
18508                    mMemWatchDumpFile = heapdumpFile.toString();
18509                    mMemWatchDumpPid = proc.pid;
18510                    mMemWatchDumpUid = proc.uid;
18511                    BackgroundThread.getHandler().post(new Runnable() {
18512                        @Override
18513                        public void run() {
18514                            revokeUriPermission(ActivityThread.currentActivityThread()
18515                                            .getApplicationThread(),
18516                                    DumpHeapActivity.JAVA_URI,
18517                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18518                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18519                                    UserHandle.myUserId());
18520                            ParcelFileDescriptor fd = null;
18521                            try {
18522                                heapdumpFile.delete();
18523                                fd = ParcelFileDescriptor.open(heapdumpFile,
18524                                        ParcelFileDescriptor.MODE_CREATE |
18525                                                ParcelFileDescriptor.MODE_TRUNCATE |
18526                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18527                                                ParcelFileDescriptor.MODE_APPEND);
18528                                IApplicationThread thread = myProc.thread;
18529                                if (thread != null) {
18530                                    try {
18531                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18532                                                "Requesting dump heap from "
18533                                                + myProc + " to " + heapdumpFile);
18534                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18535                                    } catch (RemoteException e) {
18536                                    }
18537                                }
18538                            } catch (FileNotFoundException e) {
18539                                e.printStackTrace();
18540                            } finally {
18541                                if (fd != null) {
18542                                    try {
18543                                        fd.close();
18544                                    } catch (IOException e) {
18545                                    }
18546                                }
18547                            }
18548                        }
18549                    });
18550                } else {
18551                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18552                            + ", but debugging not enabled");
18553                }
18554            }
18555        }
18556    }
18557
18558    /**
18559     * Schedule PSS collection of a process.
18560     */
18561    void requestPssLocked(ProcessRecord proc, int procState) {
18562        if (mPendingPssProcesses.contains(proc)) {
18563            return;
18564        }
18565        if (mPendingPssProcesses.size() == 0) {
18566            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18567        }
18568        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18569        proc.pssProcState = procState;
18570        mPendingPssProcesses.add(proc);
18571    }
18572
18573    /**
18574     * Schedule PSS collection of all processes.
18575     */
18576    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18577        if (!always) {
18578            if (now < (mLastFullPssTime +
18579                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18580                return;
18581            }
18582        }
18583        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18584        mLastFullPssTime = now;
18585        mFullPssPending = true;
18586        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18587        mPendingPssProcesses.clear();
18588        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18589            ProcessRecord app = mLruProcesses.get(i);
18590            if (app.thread == null
18591                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18592                continue;
18593            }
18594            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18595                app.pssProcState = app.setProcState;
18596                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18597                        mTestPssMode, isSleeping(), now);
18598                mPendingPssProcesses.add(app);
18599            }
18600        }
18601        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18602    }
18603
18604    public void setTestPssMode(boolean enabled) {
18605        synchronized (this) {
18606            mTestPssMode = enabled;
18607            if (enabled) {
18608                // Whenever we enable the mode, we want to take a snapshot all of current
18609                // process mem use.
18610                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18611            }
18612        }
18613    }
18614
18615    /**
18616     * Ask a given process to GC right now.
18617     */
18618    final void performAppGcLocked(ProcessRecord app) {
18619        try {
18620            app.lastRequestedGc = SystemClock.uptimeMillis();
18621            if (app.thread != null) {
18622                if (app.reportLowMemory) {
18623                    app.reportLowMemory = false;
18624                    app.thread.scheduleLowMemory();
18625                } else {
18626                    app.thread.processInBackground();
18627                }
18628            }
18629        } catch (Exception e) {
18630            // whatever.
18631        }
18632    }
18633
18634    /**
18635     * Returns true if things are idle enough to perform GCs.
18636     */
18637    private final boolean canGcNowLocked() {
18638        boolean processingBroadcasts = false;
18639        for (BroadcastQueue q : mBroadcastQueues) {
18640            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18641                processingBroadcasts = true;
18642            }
18643        }
18644        return !processingBroadcasts
18645                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18646    }
18647
18648    /**
18649     * Perform GCs on all processes that are waiting for it, but only
18650     * if things are idle.
18651     */
18652    final void performAppGcsLocked() {
18653        final int N = mProcessesToGc.size();
18654        if (N <= 0) {
18655            return;
18656        }
18657        if (canGcNowLocked()) {
18658            while (mProcessesToGc.size() > 0) {
18659                ProcessRecord proc = mProcessesToGc.remove(0);
18660                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18661                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18662                            <= SystemClock.uptimeMillis()) {
18663                        // To avoid spamming the system, we will GC processes one
18664                        // at a time, waiting a few seconds between each.
18665                        performAppGcLocked(proc);
18666                        scheduleAppGcsLocked();
18667                        return;
18668                    } else {
18669                        // It hasn't been long enough since we last GCed this
18670                        // process...  put it in the list to wait for its time.
18671                        addProcessToGcListLocked(proc);
18672                        break;
18673                    }
18674                }
18675            }
18676
18677            scheduleAppGcsLocked();
18678        }
18679    }
18680
18681    /**
18682     * If all looks good, perform GCs on all processes waiting for them.
18683     */
18684    final void performAppGcsIfAppropriateLocked() {
18685        if (canGcNowLocked()) {
18686            performAppGcsLocked();
18687            return;
18688        }
18689        // Still not idle, wait some more.
18690        scheduleAppGcsLocked();
18691    }
18692
18693    /**
18694     * Schedule the execution of all pending app GCs.
18695     */
18696    final void scheduleAppGcsLocked() {
18697        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18698
18699        if (mProcessesToGc.size() > 0) {
18700            // Schedule a GC for the time to the next process.
18701            ProcessRecord proc = mProcessesToGc.get(0);
18702            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18703
18704            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18705            long now = SystemClock.uptimeMillis();
18706            if (when < (now+GC_TIMEOUT)) {
18707                when = now + GC_TIMEOUT;
18708            }
18709            mHandler.sendMessageAtTime(msg, when);
18710        }
18711    }
18712
18713    /**
18714     * Add a process to the array of processes waiting to be GCed.  Keeps the
18715     * list in sorted order by the last GC time.  The process can't already be
18716     * on the list.
18717     */
18718    final void addProcessToGcListLocked(ProcessRecord proc) {
18719        boolean added = false;
18720        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18721            if (mProcessesToGc.get(i).lastRequestedGc <
18722                    proc.lastRequestedGc) {
18723                added = true;
18724                mProcessesToGc.add(i+1, proc);
18725                break;
18726            }
18727        }
18728        if (!added) {
18729            mProcessesToGc.add(0, proc);
18730        }
18731    }
18732
18733    /**
18734     * Set up to ask a process to GC itself.  This will either do it
18735     * immediately, or put it on the list of processes to gc the next
18736     * time things are idle.
18737     */
18738    final void scheduleAppGcLocked(ProcessRecord app) {
18739        long now = SystemClock.uptimeMillis();
18740        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18741            return;
18742        }
18743        if (!mProcessesToGc.contains(app)) {
18744            addProcessToGcListLocked(app);
18745            scheduleAppGcsLocked();
18746        }
18747    }
18748
18749    final void checkExcessivePowerUsageLocked(boolean doKills) {
18750        updateCpuStatsNow();
18751
18752        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18753        boolean doWakeKills = doKills;
18754        boolean doCpuKills = doKills;
18755        if (mLastPowerCheckRealtime == 0) {
18756            doWakeKills = false;
18757        }
18758        if (mLastPowerCheckUptime == 0) {
18759            doCpuKills = false;
18760        }
18761        if (stats.isScreenOn()) {
18762            doWakeKills = false;
18763        }
18764        final long curRealtime = SystemClock.elapsedRealtime();
18765        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18766        final long curUptime = SystemClock.uptimeMillis();
18767        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18768        mLastPowerCheckRealtime = curRealtime;
18769        mLastPowerCheckUptime = curUptime;
18770        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18771            doWakeKills = false;
18772        }
18773        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18774            doCpuKills = false;
18775        }
18776        int i = mLruProcesses.size();
18777        while (i > 0) {
18778            i--;
18779            ProcessRecord app = mLruProcesses.get(i);
18780            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18781                long wtime;
18782                synchronized (stats) {
18783                    wtime = stats.getProcessWakeTime(app.info.uid,
18784                            app.pid, curRealtime);
18785                }
18786                long wtimeUsed = wtime - app.lastWakeTime;
18787                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18788                if (DEBUG_POWER) {
18789                    StringBuilder sb = new StringBuilder(128);
18790                    sb.append("Wake for ");
18791                    app.toShortString(sb);
18792                    sb.append(": over ");
18793                    TimeUtils.formatDuration(realtimeSince, sb);
18794                    sb.append(" used ");
18795                    TimeUtils.formatDuration(wtimeUsed, sb);
18796                    sb.append(" (");
18797                    sb.append((wtimeUsed*100)/realtimeSince);
18798                    sb.append("%)");
18799                    Slog.i(TAG_POWER, sb.toString());
18800                    sb.setLength(0);
18801                    sb.append("CPU for ");
18802                    app.toShortString(sb);
18803                    sb.append(": over ");
18804                    TimeUtils.formatDuration(uptimeSince, sb);
18805                    sb.append(" used ");
18806                    TimeUtils.formatDuration(cputimeUsed, sb);
18807                    sb.append(" (");
18808                    sb.append((cputimeUsed*100)/uptimeSince);
18809                    sb.append("%)");
18810                    Slog.i(TAG_POWER, sb.toString());
18811                }
18812                // If a process has held a wake lock for more
18813                // than 50% of the time during this period,
18814                // that sounds bad.  Kill!
18815                if (doWakeKills && realtimeSince > 0
18816                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18817                    synchronized (stats) {
18818                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18819                                realtimeSince, wtimeUsed);
18820                    }
18821                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18822                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18823                } else if (doCpuKills && uptimeSince > 0
18824                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18825                    synchronized (stats) {
18826                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18827                                uptimeSince, cputimeUsed);
18828                    }
18829                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18830                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18831                } else {
18832                    app.lastWakeTime = wtime;
18833                    app.lastCpuTime = app.curCpuTime;
18834                }
18835            }
18836        }
18837    }
18838
18839    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18840            long nowElapsed) {
18841        boolean success = true;
18842
18843        if (app.curRawAdj != app.setRawAdj) {
18844            app.setRawAdj = app.curRawAdj;
18845        }
18846
18847        int changes = 0;
18848
18849        if (app.curAdj != app.setAdj) {
18850            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18851            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18852                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18853                    + app.adjType);
18854            app.setAdj = app.curAdj;
18855        }
18856
18857        if (app.setSchedGroup != app.curSchedGroup) {
18858            app.setSchedGroup = app.curSchedGroup;
18859            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18860                    "Setting process group of " + app.processName
18861                    + " to " + app.curSchedGroup);
18862            if (app.waitingToKill != null && app.curReceiver == null
18863                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18864                app.kill(app.waitingToKill, true);
18865                success = false;
18866            } else {
18867                if (true) {
18868                    long oldId = Binder.clearCallingIdentity();
18869                    try {
18870                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18871                    } catch (Exception e) {
18872                        Slog.w(TAG, "Failed setting process group of " + app.pid
18873                                + " to " + app.curSchedGroup);
18874                        e.printStackTrace();
18875                    } finally {
18876                        Binder.restoreCallingIdentity(oldId);
18877                    }
18878                } else {
18879                    if (app.thread != null) {
18880                        try {
18881                            app.thread.setSchedulingGroup(app.curSchedGroup);
18882                        } catch (RemoteException e) {
18883                        }
18884                    }
18885                }
18886                Process.setSwappiness(app.pid,
18887                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18888            }
18889        }
18890        if (app.repForegroundActivities != app.foregroundActivities) {
18891            app.repForegroundActivities = app.foregroundActivities;
18892            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18893        }
18894        if (app.repProcState != app.curProcState) {
18895            app.repProcState = app.curProcState;
18896            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18897            if (app.thread != null) {
18898                try {
18899                    if (false) {
18900                        //RuntimeException h = new RuntimeException("here");
18901                        Slog.i(TAG, "Sending new process state " + app.repProcState
18902                                + " to " + app /*, h*/);
18903                    }
18904                    app.thread.setProcessState(app.repProcState);
18905                } catch (RemoteException e) {
18906                }
18907            }
18908        }
18909        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18910                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18911            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18912                // Experimental code to more aggressively collect pss while
18913                // running test...  the problem is that this tends to collect
18914                // the data right when a process is transitioning between process
18915                // states, which well tend to give noisy data.
18916                long start = SystemClock.uptimeMillis();
18917                long pss = Debug.getPss(app.pid, mTmpLong, null);
18918                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18919                mPendingPssProcesses.remove(app);
18920                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18921                        + " to " + app.curProcState + ": "
18922                        + (SystemClock.uptimeMillis()-start) + "ms");
18923            }
18924            app.lastStateTime = now;
18925            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18926                    mTestPssMode, isSleeping(), now);
18927            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18928                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18929                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18930                    + (app.nextPssTime-now) + ": " + app);
18931        } else {
18932            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18933                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18934                    mTestPssMode)))) {
18935                requestPssLocked(app, app.setProcState);
18936                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18937                        mTestPssMode, isSleeping(), now);
18938            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18939                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18940        }
18941        if (app.setProcState != app.curProcState) {
18942            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18943                    "Proc state change of " + app.processName
18944                            + " to " + app.curProcState);
18945            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18946            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18947            if (setImportant && !curImportant) {
18948                // This app is no longer something we consider important enough to allow to
18949                // use arbitrary amounts of battery power.  Note
18950                // its current wake lock time to later know to kill it if
18951                // it is not behaving well.
18952                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18953                synchronized (stats) {
18954                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18955                            app.pid, nowElapsed);
18956                }
18957                app.lastCpuTime = app.curCpuTime;
18958
18959            }
18960            // Inform UsageStats of important process state change
18961            // Must be called before updating setProcState
18962            maybeUpdateUsageStatsLocked(app, nowElapsed);
18963
18964            app.setProcState = app.curProcState;
18965            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18966                app.notCachedSinceIdle = false;
18967            }
18968            if (!doingAll) {
18969                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18970            } else {
18971                app.procStateChanged = true;
18972            }
18973        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
18974                > USAGE_STATS_INTERACTION_INTERVAL) {
18975            // For apps that sit around for a long time in the interactive state, we need
18976            // to report this at least once a day so they don't go idle.
18977            maybeUpdateUsageStatsLocked(app, nowElapsed);
18978        }
18979
18980        if (changes != 0) {
18981            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18982                    "Changes in " + app + ": " + changes);
18983            int i = mPendingProcessChanges.size()-1;
18984            ProcessChangeItem item = null;
18985            while (i >= 0) {
18986                item = mPendingProcessChanges.get(i);
18987                if (item.pid == app.pid) {
18988                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18989                            "Re-using existing item: " + item);
18990                    break;
18991                }
18992                i--;
18993            }
18994            if (i < 0) {
18995                // No existing item in pending changes; need a new one.
18996                final int NA = mAvailProcessChanges.size();
18997                if (NA > 0) {
18998                    item = mAvailProcessChanges.remove(NA-1);
18999                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19000                            "Retrieving available item: " + item);
19001                } else {
19002                    item = new ProcessChangeItem();
19003                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19004                            "Allocating new item: " + item);
19005                }
19006                item.changes = 0;
19007                item.pid = app.pid;
19008                item.uid = app.info.uid;
19009                if (mPendingProcessChanges.size() == 0) {
19010                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19011                            "*** Enqueueing dispatch processes changed!");
19012                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
19013                }
19014                mPendingProcessChanges.add(item);
19015            }
19016            item.changes |= changes;
19017            item.processState = app.repProcState;
19018            item.foregroundActivities = app.repForegroundActivities;
19019            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19020                    "Item " + Integer.toHexString(System.identityHashCode(item))
19021                    + " " + app.toShortString() + ": changes=" + item.changes
19022                    + " procState=" + item.processState
19023                    + " foreground=" + item.foregroundActivities
19024                    + " type=" + app.adjType + " source=" + app.adjSource
19025                    + " target=" + app.adjTarget);
19026        }
19027
19028        return success;
19029    }
19030
19031    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
19032        if (uidRec.pendingChange == null) {
19033            if (mPendingUidChanges.size() == 0) {
19034                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19035                        "*** Enqueueing dispatch uid changed!");
19036                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
19037            }
19038            final int NA = mAvailUidChanges.size();
19039            if (NA > 0) {
19040                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
19041                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19042                        "Retrieving available item: " + uidRec.pendingChange);
19043            } else {
19044                uidRec.pendingChange = new UidRecord.ChangeItem();
19045                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19046                        "Allocating new item: " + uidRec.pendingChange);
19047            }
19048            uidRec.pendingChange.uidRecord = uidRec;
19049            uidRec.pendingChange.uid = uidRec.uid;
19050            mPendingUidChanges.add(uidRec.pendingChange);
19051        }
19052        uidRec.pendingChange.gone = gone;
19053        uidRec.pendingChange.processState = uidRec.setProcState;
19054    }
19055
19056    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19057            String authority) {
19058        if (app == null) return;
19059        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19060            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19061            if (userState == null) return;
19062            final long now = SystemClock.elapsedRealtime();
19063            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19064            if (lastReported == null || lastReported < now - 60 * 1000L) {
19065                mUsageStatsService.reportContentProviderUsage(
19066                        authority, providerPkgName, app.userId);
19067                userState.mProviderLastReportedFg.put(authority, now);
19068            }
19069        }
19070    }
19071
19072    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19073        if (DEBUG_USAGE_STATS) {
19074            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19075                    + "] state changes: old = " + app.setProcState + ", new = "
19076                    + app.curProcState);
19077        }
19078        if (mUsageStatsService == null) {
19079            return;
19080        }
19081        boolean isInteraction;
19082        // To avoid some abuse patterns, we are going to be careful about what we consider
19083        // to be an app interaction.  Being the top activity doesn't count while the display
19084        // is sleeping, nor do short foreground services.
19085        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19086            isInteraction = true;
19087            app.fgInteractionTime = 0;
19088        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19089            if (app.fgInteractionTime == 0) {
19090                app.fgInteractionTime = nowElapsed;
19091                isInteraction = false;
19092            } else {
19093                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19094            }
19095        } else {
19096            isInteraction = app.curProcState
19097                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19098            app.fgInteractionTime = 0;
19099        }
19100        if (isInteraction && (!app.reportedInteraction
19101                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19102            app.interactionEventTime = nowElapsed;
19103            String[] packages = app.getPackageList();
19104            if (packages != null) {
19105                for (int i = 0; i < packages.length; i++) {
19106                    mUsageStatsService.reportEvent(packages[i], app.userId,
19107                            UsageEvents.Event.SYSTEM_INTERACTION);
19108                }
19109            }
19110        }
19111        app.reportedInteraction = isInteraction;
19112        if (!isInteraction) {
19113            app.interactionEventTime = 0;
19114        }
19115    }
19116
19117    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19118        if (proc.thread != null) {
19119            if (proc.baseProcessTracker != null) {
19120                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19121            }
19122            if (proc.repProcState >= 0) {
19123                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19124                        proc.repProcState);
19125            }
19126        }
19127    }
19128
19129    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19130            ProcessRecord TOP_APP, boolean doingAll, long now) {
19131        if (app.thread == null) {
19132            return false;
19133        }
19134
19135        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19136
19137        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19138    }
19139
19140    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19141            boolean oomAdj) {
19142        if (isForeground != proc.foregroundServices) {
19143            proc.foregroundServices = isForeground;
19144            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19145                    proc.info.uid);
19146            if (isForeground) {
19147                if (curProcs == null) {
19148                    curProcs = new ArrayList<ProcessRecord>();
19149                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19150                }
19151                if (!curProcs.contains(proc)) {
19152                    curProcs.add(proc);
19153                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19154                            proc.info.packageName, proc.info.uid);
19155                }
19156            } else {
19157                if (curProcs != null) {
19158                    if (curProcs.remove(proc)) {
19159                        mBatteryStatsService.noteEvent(
19160                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19161                                proc.info.packageName, proc.info.uid);
19162                        if (curProcs.size() <= 0) {
19163                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19164                        }
19165                    }
19166                }
19167            }
19168            if (oomAdj) {
19169                updateOomAdjLocked();
19170            }
19171        }
19172    }
19173
19174    private final ActivityRecord resumedAppLocked() {
19175        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19176        String pkg;
19177        int uid;
19178        if (act != null) {
19179            pkg = act.packageName;
19180            uid = act.info.applicationInfo.uid;
19181        } else {
19182            pkg = null;
19183            uid = -1;
19184        }
19185        // Has the UID or resumed package name changed?
19186        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19187                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19188            if (mCurResumedPackage != null) {
19189                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19190                        mCurResumedPackage, mCurResumedUid);
19191            }
19192            mCurResumedPackage = pkg;
19193            mCurResumedUid = uid;
19194            if (mCurResumedPackage != null) {
19195                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19196                        mCurResumedPackage, mCurResumedUid);
19197            }
19198        }
19199        return act;
19200    }
19201
19202    final boolean updateOomAdjLocked(ProcessRecord app) {
19203        final ActivityRecord TOP_ACT = resumedAppLocked();
19204        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19205        final boolean wasCached = app.cached;
19206
19207        mAdjSeq++;
19208
19209        // This is the desired cached adjusment we want to tell it to use.
19210        // If our app is currently cached, we know it, and that is it.  Otherwise,
19211        // we don't know it yet, and it needs to now be cached we will then
19212        // need to do a complete oom adj.
19213        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19214                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19215        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19216                SystemClock.uptimeMillis());
19217        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19218            // Changed to/from cached state, so apps after it in the LRU
19219            // list may also be changed.
19220            updateOomAdjLocked();
19221        }
19222        return success;
19223    }
19224
19225    final void updateOomAdjLocked() {
19226        final ActivityRecord TOP_ACT = resumedAppLocked();
19227        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19228        final long now = SystemClock.uptimeMillis();
19229        final long nowElapsed = SystemClock.elapsedRealtime();
19230        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19231        final int N = mLruProcesses.size();
19232
19233        if (false) {
19234            RuntimeException e = new RuntimeException();
19235            e.fillInStackTrace();
19236            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19237        }
19238
19239        // Reset state in all uid records.
19240        for (int i=mActiveUids.size()-1; i>=0; i--) {
19241            final UidRecord uidRec = mActiveUids.valueAt(i);
19242            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19243                    "Starting update of " + uidRec);
19244            uidRec.reset();
19245        }
19246
19247        mStackSupervisor.rankTaskLayersIfNeeded();
19248
19249        mAdjSeq++;
19250        mNewNumServiceProcs = 0;
19251        mNewNumAServiceProcs = 0;
19252
19253        final int emptyProcessLimit;
19254        final int cachedProcessLimit;
19255        if (mProcessLimit <= 0) {
19256            emptyProcessLimit = cachedProcessLimit = 0;
19257        } else if (mProcessLimit == 1) {
19258            emptyProcessLimit = 1;
19259            cachedProcessLimit = 0;
19260        } else {
19261            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19262            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19263        }
19264
19265        // Let's determine how many processes we have running vs.
19266        // how many slots we have for background processes; we may want
19267        // to put multiple processes in a slot of there are enough of
19268        // them.
19269        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19270                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19271        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19272        if (numEmptyProcs > cachedProcessLimit) {
19273            // If there are more empty processes than our limit on cached
19274            // processes, then use the cached process limit for the factor.
19275            // This ensures that the really old empty processes get pushed
19276            // down to the bottom, so if we are running low on memory we will
19277            // have a better chance at keeping around more cached processes
19278            // instead of a gazillion empty processes.
19279            numEmptyProcs = cachedProcessLimit;
19280        }
19281        int emptyFactor = numEmptyProcs/numSlots;
19282        if (emptyFactor < 1) emptyFactor = 1;
19283        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19284        if (cachedFactor < 1) cachedFactor = 1;
19285        int stepCached = 0;
19286        int stepEmpty = 0;
19287        int numCached = 0;
19288        int numEmpty = 0;
19289        int numTrimming = 0;
19290
19291        mNumNonCachedProcs = 0;
19292        mNumCachedHiddenProcs = 0;
19293
19294        // First update the OOM adjustment for each of the
19295        // application processes based on their current state.
19296        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19297        int nextCachedAdj = curCachedAdj+1;
19298        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19299        int nextEmptyAdj = curEmptyAdj+2;
19300        for (int i=N-1; i>=0; i--) {
19301            ProcessRecord app = mLruProcesses.get(i);
19302            if (!app.killedByAm && app.thread != null) {
19303                app.procStateChanged = false;
19304                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19305
19306                // If we haven't yet assigned the final cached adj
19307                // to the process, do that now.
19308                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19309                    switch (app.curProcState) {
19310                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19311                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19312                            // This process is a cached process holding activities...
19313                            // assign it the next cached value for that type, and then
19314                            // step that cached level.
19315                            app.curRawAdj = curCachedAdj;
19316                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19317                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19318                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19319                                    + ")");
19320                            if (curCachedAdj != nextCachedAdj) {
19321                                stepCached++;
19322                                if (stepCached >= cachedFactor) {
19323                                    stepCached = 0;
19324                                    curCachedAdj = nextCachedAdj;
19325                                    nextCachedAdj += 2;
19326                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19327                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19328                                    }
19329                                }
19330                            }
19331                            break;
19332                        default:
19333                            // For everything else, assign next empty cached process
19334                            // level and bump that up.  Note that this means that
19335                            // long-running services that have dropped down to the
19336                            // cached level will be treated as empty (since their process
19337                            // state is still as a service), which is what we want.
19338                            app.curRawAdj = curEmptyAdj;
19339                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19340                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19341                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19342                                    + ")");
19343                            if (curEmptyAdj != nextEmptyAdj) {
19344                                stepEmpty++;
19345                                if (stepEmpty >= emptyFactor) {
19346                                    stepEmpty = 0;
19347                                    curEmptyAdj = nextEmptyAdj;
19348                                    nextEmptyAdj += 2;
19349                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19350                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19351                                    }
19352                                }
19353                            }
19354                            break;
19355                    }
19356                }
19357
19358                applyOomAdjLocked(app, true, now, nowElapsed);
19359
19360                // Count the number of process types.
19361                switch (app.curProcState) {
19362                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19363                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19364                        mNumCachedHiddenProcs++;
19365                        numCached++;
19366                        if (numCached > cachedProcessLimit) {
19367                            app.kill("cached #" + numCached, true);
19368                        }
19369                        break;
19370                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19371                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19372                                && app.lastActivityTime < oldTime) {
19373                            app.kill("empty for "
19374                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19375                                    / 1000) + "s", true);
19376                        } else {
19377                            numEmpty++;
19378                            if (numEmpty > emptyProcessLimit) {
19379                                app.kill("empty #" + numEmpty, true);
19380                            }
19381                        }
19382                        break;
19383                    default:
19384                        mNumNonCachedProcs++;
19385                        break;
19386                }
19387
19388                if (app.isolated && app.services.size() <= 0) {
19389                    // If this is an isolated process, and there are no
19390                    // services running in it, then the process is no longer
19391                    // needed.  We agressively kill these because we can by
19392                    // definition not re-use the same process again, and it is
19393                    // good to avoid having whatever code was running in them
19394                    // left sitting around after no longer needed.
19395                    app.kill("isolated not needed", true);
19396                } else {
19397                    // Keeping this process, update its uid.
19398                    final UidRecord uidRec = app.uidRecord;
19399                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19400                        uidRec.curProcState = app.curProcState;
19401                    }
19402                }
19403
19404                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19405                        && !app.killedByAm) {
19406                    numTrimming++;
19407                }
19408            }
19409        }
19410
19411        mNumServiceProcs = mNewNumServiceProcs;
19412
19413        // Now determine the memory trimming level of background processes.
19414        // Unfortunately we need to start at the back of the list to do this
19415        // properly.  We only do this if the number of background apps we
19416        // are managing to keep around is less than half the maximum we desire;
19417        // if we are keeping a good number around, we'll let them use whatever
19418        // memory they want.
19419        final int numCachedAndEmpty = numCached + numEmpty;
19420        int memFactor;
19421        if (numCached <= ProcessList.TRIM_CACHED_APPS
19422                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19423            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19424                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19425            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19426                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19427            } else {
19428                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19429            }
19430        } else {
19431            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19432        }
19433        // We always allow the memory level to go up (better).  We only allow it to go
19434        // down if we are in a state where that is allowed, *and* the total number of processes
19435        // has gone down since last time.
19436        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19437                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19438                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19439        if (memFactor > mLastMemoryLevel) {
19440            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19441                memFactor = mLastMemoryLevel;
19442                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19443            }
19444        }
19445        mLastMemoryLevel = memFactor;
19446        mLastNumProcesses = mLruProcesses.size();
19447        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19448        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19449        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19450            if (mLowRamStartTime == 0) {
19451                mLowRamStartTime = now;
19452            }
19453            int step = 0;
19454            int fgTrimLevel;
19455            switch (memFactor) {
19456                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19457                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19458                    break;
19459                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19460                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19461                    break;
19462                default:
19463                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19464                    break;
19465            }
19466            int factor = numTrimming/3;
19467            int minFactor = 2;
19468            if (mHomeProcess != null) minFactor++;
19469            if (mPreviousProcess != null) minFactor++;
19470            if (factor < minFactor) factor = minFactor;
19471            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19472            for (int i=N-1; i>=0; i--) {
19473                ProcessRecord app = mLruProcesses.get(i);
19474                if (allChanged || app.procStateChanged) {
19475                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19476                    app.procStateChanged = false;
19477                }
19478                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19479                        && !app.killedByAm) {
19480                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19481                        try {
19482                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19483                                    "Trimming memory of " + app.processName + " to " + curLevel);
19484                            app.thread.scheduleTrimMemory(curLevel);
19485                        } catch (RemoteException e) {
19486                        }
19487                        if (false) {
19488                            // For now we won't do this; our memory trimming seems
19489                            // to be good enough at this point that destroying
19490                            // activities causes more harm than good.
19491                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19492                                    && app != mHomeProcess && app != mPreviousProcess) {
19493                                // Need to do this on its own message because the stack may not
19494                                // be in a consistent state at this point.
19495                                // For these apps we will also finish their activities
19496                                // to help them free memory.
19497                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19498                            }
19499                        }
19500                    }
19501                    app.trimMemoryLevel = curLevel;
19502                    step++;
19503                    if (step >= factor) {
19504                        step = 0;
19505                        switch (curLevel) {
19506                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19507                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19508                                break;
19509                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19510                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19511                                break;
19512                        }
19513                    }
19514                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19515                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19516                            && app.thread != null) {
19517                        try {
19518                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19519                                    "Trimming memory of heavy-weight " + app.processName
19520                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19521                            app.thread.scheduleTrimMemory(
19522                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19523                        } catch (RemoteException e) {
19524                        }
19525                    }
19526                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19527                } else {
19528                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19529                            || app.systemNoUi) && app.pendingUiClean) {
19530                        // If this application is now in the background and it
19531                        // had done UI, then give it the special trim level to
19532                        // have it free UI resources.
19533                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19534                        if (app.trimMemoryLevel < level && app.thread != null) {
19535                            try {
19536                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19537                                        "Trimming memory of bg-ui " + app.processName
19538                                        + " to " + level);
19539                                app.thread.scheduleTrimMemory(level);
19540                            } catch (RemoteException e) {
19541                            }
19542                        }
19543                        app.pendingUiClean = false;
19544                    }
19545                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19546                        try {
19547                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19548                                    "Trimming memory of fg " + app.processName
19549                                    + " to " + fgTrimLevel);
19550                            app.thread.scheduleTrimMemory(fgTrimLevel);
19551                        } catch (RemoteException e) {
19552                        }
19553                    }
19554                    app.trimMemoryLevel = fgTrimLevel;
19555                }
19556            }
19557        } else {
19558            if (mLowRamStartTime != 0) {
19559                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19560                mLowRamStartTime = 0;
19561            }
19562            for (int i=N-1; i>=0; i--) {
19563                ProcessRecord app = mLruProcesses.get(i);
19564                if (allChanged || app.procStateChanged) {
19565                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19566                    app.procStateChanged = false;
19567                }
19568                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19569                        || app.systemNoUi) && app.pendingUiClean) {
19570                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19571                            && app.thread != null) {
19572                        try {
19573                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19574                                    "Trimming memory of ui hidden " + app.processName
19575                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19576                            app.thread.scheduleTrimMemory(
19577                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19578                        } catch (RemoteException e) {
19579                        }
19580                    }
19581                    app.pendingUiClean = false;
19582                }
19583                app.trimMemoryLevel = 0;
19584            }
19585        }
19586
19587        if (mAlwaysFinishActivities) {
19588            // Need to do this on its own message because the stack may not
19589            // be in a consistent state at this point.
19590            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19591        }
19592
19593        if (allChanged) {
19594            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19595        }
19596
19597        // Update from any uid changes.
19598        for (int i=mActiveUids.size()-1; i>=0; i--) {
19599            final UidRecord uidRec = mActiveUids.valueAt(i);
19600            if (uidRec.setProcState != uidRec.curProcState) {
19601                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19602                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19603                        + " to " + uidRec.curProcState);
19604                uidRec.setProcState = uidRec.curProcState;
19605                enqueueUidChangeLocked(uidRec, false);
19606            }
19607        }
19608
19609        if (mProcessStats.shouldWriteNowLocked(now)) {
19610            mHandler.post(new Runnable() {
19611                @Override public void run() {
19612                    synchronized (ActivityManagerService.this) {
19613                        mProcessStats.writeStateAsyncLocked();
19614                    }
19615                }
19616            });
19617        }
19618
19619        if (DEBUG_OOM_ADJ) {
19620            final long duration = SystemClock.uptimeMillis() - now;
19621            if (false) {
19622                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19623                        new RuntimeException("here").fillInStackTrace());
19624            } else {
19625                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19626            }
19627        }
19628    }
19629
19630    final void trimApplications() {
19631        synchronized (this) {
19632            int i;
19633
19634            // First remove any unused application processes whose package
19635            // has been removed.
19636            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19637                final ProcessRecord app = mRemovedProcesses.get(i);
19638                if (app.activities.size() == 0
19639                        && app.curReceiver == null && app.services.size() == 0) {
19640                    Slog.i(
19641                        TAG, "Exiting empty application process "
19642                        + app.processName + " ("
19643                        + (app.thread != null ? app.thread.asBinder() : null)
19644                        + ")\n");
19645                    if (app.pid > 0 && app.pid != MY_PID) {
19646                        app.kill("empty", false);
19647                    } else {
19648                        try {
19649                            app.thread.scheduleExit();
19650                        } catch (Exception e) {
19651                            // Ignore exceptions.
19652                        }
19653                    }
19654                    cleanUpApplicationRecordLocked(app, false, true, -1);
19655                    mRemovedProcesses.remove(i);
19656
19657                    if (app.persistent) {
19658                        addAppLocked(app.info, false, null /* ABI override */);
19659                    }
19660                }
19661            }
19662
19663            // Now update the oom adj for all processes.
19664            updateOomAdjLocked();
19665        }
19666    }
19667
19668    /** This method sends the specified signal to each of the persistent apps */
19669    public void signalPersistentProcesses(int sig) throws RemoteException {
19670        if (sig != Process.SIGNAL_USR1) {
19671            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19672        }
19673
19674        synchronized (this) {
19675            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19676                    != PackageManager.PERMISSION_GRANTED) {
19677                throw new SecurityException("Requires permission "
19678                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19679            }
19680
19681            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19682                ProcessRecord r = mLruProcesses.get(i);
19683                if (r.thread != null && r.persistent) {
19684                    Process.sendSignal(r.pid, sig);
19685                }
19686            }
19687        }
19688    }
19689
19690    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19691        if (proc == null || proc == mProfileProc) {
19692            proc = mProfileProc;
19693            profileType = mProfileType;
19694            clearProfilerLocked();
19695        }
19696        if (proc == null) {
19697            return;
19698        }
19699        try {
19700            proc.thread.profilerControl(false, null, profileType);
19701        } catch (RemoteException e) {
19702            throw new IllegalStateException("Process disappeared");
19703        }
19704    }
19705
19706    private void clearProfilerLocked() {
19707        if (mProfileFd != null) {
19708            try {
19709                mProfileFd.close();
19710            } catch (IOException e) {
19711            }
19712        }
19713        mProfileApp = null;
19714        mProfileProc = null;
19715        mProfileFile = null;
19716        mProfileType = 0;
19717        mAutoStopProfiler = false;
19718        mSamplingInterval = 0;
19719    }
19720
19721    public boolean profileControl(String process, int userId, boolean start,
19722            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19723
19724        try {
19725            synchronized (this) {
19726                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19727                // its own permission.
19728                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19729                        != PackageManager.PERMISSION_GRANTED) {
19730                    throw new SecurityException("Requires permission "
19731                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19732                }
19733
19734                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19735                    throw new IllegalArgumentException("null profile info or fd");
19736                }
19737
19738                ProcessRecord proc = null;
19739                if (process != null) {
19740                    proc = findProcessLocked(process, userId, "profileControl");
19741                }
19742
19743                if (start && (proc == null || proc.thread == null)) {
19744                    throw new IllegalArgumentException("Unknown process: " + process);
19745                }
19746
19747                if (start) {
19748                    stopProfilerLocked(null, 0);
19749                    setProfileApp(proc.info, proc.processName, profilerInfo);
19750                    mProfileProc = proc;
19751                    mProfileType = profileType;
19752                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19753                    try {
19754                        fd = fd.dup();
19755                    } catch (IOException e) {
19756                        fd = null;
19757                    }
19758                    profilerInfo.profileFd = fd;
19759                    proc.thread.profilerControl(start, profilerInfo, profileType);
19760                    fd = null;
19761                    mProfileFd = null;
19762                } else {
19763                    stopProfilerLocked(proc, profileType);
19764                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19765                        try {
19766                            profilerInfo.profileFd.close();
19767                        } catch (IOException e) {
19768                        }
19769                    }
19770                }
19771
19772                return true;
19773            }
19774        } catch (RemoteException e) {
19775            throw new IllegalStateException("Process disappeared");
19776        } finally {
19777            if (profilerInfo != null && profilerInfo.profileFd != null) {
19778                try {
19779                    profilerInfo.profileFd.close();
19780                } catch (IOException e) {
19781                }
19782            }
19783        }
19784    }
19785
19786    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19787        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19788                userId, true, ALLOW_FULL_ONLY, callName, null);
19789        ProcessRecord proc = null;
19790        try {
19791            int pid = Integer.parseInt(process);
19792            synchronized (mPidsSelfLocked) {
19793                proc = mPidsSelfLocked.get(pid);
19794            }
19795        } catch (NumberFormatException e) {
19796        }
19797
19798        if (proc == null) {
19799            ArrayMap<String, SparseArray<ProcessRecord>> all
19800                    = mProcessNames.getMap();
19801            SparseArray<ProcessRecord> procs = all.get(process);
19802            if (procs != null && procs.size() > 0) {
19803                proc = procs.valueAt(0);
19804                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19805                    for (int i=1; i<procs.size(); i++) {
19806                        ProcessRecord thisProc = procs.valueAt(i);
19807                        if (thisProc.userId == userId) {
19808                            proc = thisProc;
19809                            break;
19810                        }
19811                    }
19812                }
19813            }
19814        }
19815
19816        return proc;
19817    }
19818
19819    public boolean dumpHeap(String process, int userId, boolean managed,
19820            String path, ParcelFileDescriptor fd) throws RemoteException {
19821
19822        try {
19823            synchronized (this) {
19824                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19825                // its own permission (same as profileControl).
19826                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19827                        != PackageManager.PERMISSION_GRANTED) {
19828                    throw new SecurityException("Requires permission "
19829                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19830                }
19831
19832                if (fd == null) {
19833                    throw new IllegalArgumentException("null fd");
19834                }
19835
19836                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19837                if (proc == null || proc.thread == null) {
19838                    throw new IllegalArgumentException("Unknown process: " + process);
19839                }
19840
19841                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19842                if (!isDebuggable) {
19843                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19844                        throw new SecurityException("Process not debuggable: " + proc);
19845                    }
19846                }
19847
19848                proc.thread.dumpHeap(managed, path, fd);
19849                fd = null;
19850                return true;
19851            }
19852        } catch (RemoteException e) {
19853            throw new IllegalStateException("Process disappeared");
19854        } finally {
19855            if (fd != null) {
19856                try {
19857                    fd.close();
19858                } catch (IOException e) {
19859                }
19860            }
19861        }
19862    }
19863
19864    @Override
19865    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19866            String reportPackage) {
19867        if (processName != null) {
19868            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19869                    "setDumpHeapDebugLimit()");
19870        } else {
19871            synchronized (mPidsSelfLocked) {
19872                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19873                if (proc == null) {
19874                    throw new SecurityException("No process found for calling pid "
19875                            + Binder.getCallingPid());
19876                }
19877                if (!Build.IS_DEBUGGABLE
19878                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19879                    throw new SecurityException("Not running a debuggable build");
19880                }
19881                processName = proc.processName;
19882                uid = proc.uid;
19883                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19884                    throw new SecurityException("Package " + reportPackage + " is not running in "
19885                            + proc);
19886                }
19887            }
19888        }
19889        synchronized (this) {
19890            if (maxMemSize > 0) {
19891                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19892            } else {
19893                if (uid != 0) {
19894                    mMemWatchProcesses.remove(processName, uid);
19895                } else {
19896                    mMemWatchProcesses.getMap().remove(processName);
19897                }
19898            }
19899        }
19900    }
19901
19902    @Override
19903    public void dumpHeapFinished(String path) {
19904        synchronized (this) {
19905            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19906                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19907                        + " does not match last pid " + mMemWatchDumpPid);
19908                return;
19909            }
19910            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19911                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19912                        + " does not match last path " + mMemWatchDumpFile);
19913                return;
19914            }
19915            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19916            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19917        }
19918    }
19919
19920    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19921    public void monitor() {
19922        synchronized (this) { }
19923    }
19924
19925    void onCoreSettingsChange(Bundle settings) {
19926        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19927            ProcessRecord processRecord = mLruProcesses.get(i);
19928            try {
19929                if (processRecord.thread != null) {
19930                    processRecord.thread.setCoreSettings(settings);
19931                }
19932            } catch (RemoteException re) {
19933                /* ignore */
19934            }
19935        }
19936    }
19937
19938    // Multi-user methods
19939
19940    /**
19941     * Start user, if its not already running, but don't bring it to foreground.
19942     */
19943    @Override
19944    public boolean startUserInBackground(final int userId) {
19945        return mUserController.startUser(userId, /* foreground */ false);
19946    }
19947
19948    @Override
19949    public boolean switchUser(final int userId) {
19950        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19951        String userName;
19952        synchronized (this) {
19953            UserInfo userInfo = mUserController.getUserInfo(userId);
19954            if (userInfo == null) {
19955                Slog.w(TAG, "No user info for user #" + userId);
19956                return false;
19957            }
19958            if (userInfo.isManagedProfile()) {
19959                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19960                return false;
19961            }
19962            userName = userInfo.name;
19963            mUserController.setTargetUserIdLocked(userId);
19964        }
19965        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19966        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19967        return true;
19968    }
19969
19970    void scheduleStartProfilesLocked() {
19971        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19972            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19973                    DateUtils.SECOND_IN_MILLIS);
19974        }
19975    }
19976
19977    @Override
19978    public int stopUser(final int userId, final IStopUserCallback callback) {
19979        return mUserController.stopUser(userId, callback);
19980    }
19981
19982    void onUserRemovedLocked(int userId) {
19983        mRecentTasks.removeTasksForUserLocked(userId);
19984    }
19985
19986    @Override
19987    public UserInfo getCurrentUser() {
19988        return mUserController.getCurrentUser();
19989    }
19990
19991    @Override
19992    public boolean isUserRunning(int userId, boolean orStopped) {
19993        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19994                != PackageManager.PERMISSION_GRANTED) {
19995            String msg = "Permission Denial: isUserRunning() from pid="
19996                    + Binder.getCallingPid()
19997                    + ", uid=" + Binder.getCallingUid()
19998                    + " requires " + INTERACT_ACROSS_USERS;
19999            Slog.w(TAG, msg);
20000            throw new SecurityException(msg);
20001        }
20002        synchronized (this) {
20003            return mUserController.isUserRunningLocked(userId, orStopped);
20004        }
20005    }
20006
20007    @Override
20008    public int[] getRunningUserIds() {
20009        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20010                != PackageManager.PERMISSION_GRANTED) {
20011            String msg = "Permission Denial: isUserRunning() from pid="
20012                    + Binder.getCallingPid()
20013                    + ", uid=" + Binder.getCallingUid()
20014                    + " requires " + INTERACT_ACROSS_USERS;
20015            Slog.w(TAG, msg);
20016            throw new SecurityException(msg);
20017        }
20018        synchronized (this) {
20019            return mUserController.getStartedUserArrayLocked();
20020        }
20021    }
20022
20023    @Override
20024    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20025        mUserController.registerUserSwitchObserver(observer);
20026    }
20027
20028    @Override
20029    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20030        mUserController.unregisterUserSwitchObserver(observer);
20031    }
20032
20033    private int applyUserId(int uid, int userId) {
20034        return UserHandle.getUid(userId, uid);
20035    }
20036
20037    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20038        if (info == null) return null;
20039        ApplicationInfo newInfo = new ApplicationInfo(info);
20040        newInfo.uid = applyUserId(info.uid, userId);
20041        newInfo.dataDir = Environment
20042                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20043                .getAbsolutePath();
20044        return newInfo;
20045    }
20046
20047    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20048        if (aInfo == null
20049                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20050            return aInfo;
20051        }
20052
20053        ActivityInfo info = new ActivityInfo(aInfo);
20054        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20055        return info;
20056    }
20057
20058    private boolean processSanityChecksLocked(ProcessRecord process) {
20059        if (process == null || process.thread == null) {
20060            return false;
20061        }
20062
20063        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20064        if (!isDebuggable) {
20065            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20066                return false;
20067            }
20068        }
20069
20070        return true;
20071    }
20072
20073    public boolean startBinderTracking() throws RemoteException {
20074        synchronized (this) {
20075            mBinderTransactionTrackingEnabled = true;
20076            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20077            // permission (same as profileControl).
20078            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20079                    != PackageManager.PERMISSION_GRANTED) {
20080                throw new SecurityException("Requires permission "
20081                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20082            }
20083
20084            for (int i = 0; i < mLruProcesses.size(); i++) {
20085                ProcessRecord process = mLruProcesses.get(i);
20086                if (!processSanityChecksLocked(process)) {
20087                    continue;
20088                }
20089                try {
20090                    process.thread.startBinderTracking();
20091                } catch (RemoteException e) {
20092                    Log.v(TAG, "Process disappared");
20093                }
20094            }
20095            return true;
20096        }
20097    }
20098
20099    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20100        try {
20101            synchronized (this) {
20102                mBinderTransactionTrackingEnabled = false;
20103                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20104                // permission (same as profileControl).
20105                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20106                        != PackageManager.PERMISSION_GRANTED) {
20107                    throw new SecurityException("Requires permission "
20108                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20109                }
20110
20111                if (fd == null) {
20112                    throw new IllegalArgumentException("null fd");
20113                }
20114
20115                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20116                pw.println("Binder transaction traces for all processes.\n");
20117                for (ProcessRecord process : mLruProcesses) {
20118                    if (!processSanityChecksLocked(process)) {
20119                        continue;
20120                    }
20121
20122                    pw.println("Traces for process: " + process.processName);
20123                    pw.flush();
20124                    try {
20125                        TransferPipe tp = new TransferPipe();
20126                        try {
20127                            process.thread.stopBinderTrackingAndDump(
20128                                    tp.getWriteFd().getFileDescriptor());
20129                            tp.go(fd.getFileDescriptor());
20130                        } finally {
20131                            tp.kill();
20132                        }
20133                    } catch (IOException e) {
20134                        pw.println("Failure while dumping IPC traces from " + process +
20135                                ".  Exception: " + e);
20136                        pw.flush();
20137                    } catch (RemoteException e) {
20138                        pw.println("Got a RemoteException while dumping IPC traces from " +
20139                                process + ".  Exception: " + e);
20140                        pw.flush();
20141                    }
20142                }
20143                fd = null;
20144                return true;
20145            }
20146        } finally {
20147            if (fd != null) {
20148                try {
20149                    fd.close();
20150                } catch (IOException e) {
20151                }
20152            }
20153        }
20154    }
20155
20156    void stopReportingCrashesLocked(ProcessRecord proc) {
20157        if (mAppsNotReportingCrashes == null) {
20158            mAppsNotReportingCrashes = new ArraySet<>();
20159        }
20160        mAppsNotReportingCrashes.add(proc.info.packageName);
20161    }
20162
20163    private final class LocalService extends ActivityManagerInternal {
20164        @Override
20165        public void onWakefulnessChanged(int wakefulness) {
20166            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20167        }
20168
20169        @Override
20170        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20171                String processName, String abiOverride, int uid, Runnable crashHandler) {
20172            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20173                    processName, abiOverride, uid, crashHandler);
20174        }
20175
20176        @Override
20177        public SleepToken acquireSleepToken(String tag) {
20178            Preconditions.checkNotNull(tag);
20179
20180            synchronized (ActivityManagerService.this) {
20181                SleepTokenImpl token = new SleepTokenImpl(tag);
20182                mSleepTokens.add(token);
20183                updateSleepIfNeededLocked();
20184                return token;
20185            }
20186        }
20187
20188        @Override
20189        public ComponentName getHomeActivityForUser(int userId) {
20190            synchronized (ActivityManagerService.this) {
20191                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20192                return homeActivity == null ? null : homeActivity.realActivity;
20193            }
20194        }
20195
20196        @Override
20197        public void onUserRemoved(int userId) {
20198            synchronized (ActivityManagerService.this) {
20199                ActivityManagerService.this.onUserRemovedLocked(userId);
20200            }
20201        }
20202    }
20203
20204    private final class SleepTokenImpl extends SleepToken {
20205        private final String mTag;
20206        private final long mAcquireTime;
20207
20208        public SleepTokenImpl(String tag) {
20209            mTag = tag;
20210            mAcquireTime = SystemClock.uptimeMillis();
20211        }
20212
20213        @Override
20214        public void release() {
20215            synchronized (ActivityManagerService.this) {
20216                if (mSleepTokens.remove(this)) {
20217                    updateSleepIfNeededLocked();
20218                }
20219            }
20220        }
20221
20222        @Override
20223        public String toString() {
20224            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20225        }
20226    }
20227
20228    /**
20229     * An implementation of IAppTask, that allows an app to manage its own tasks via
20230     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20231     * only the process that calls getAppTasks() can call the AppTask methods.
20232     */
20233    class AppTaskImpl extends IAppTask.Stub {
20234        private int mTaskId;
20235        private int mCallingUid;
20236
20237        public AppTaskImpl(int taskId, int callingUid) {
20238            mTaskId = taskId;
20239            mCallingUid = callingUid;
20240        }
20241
20242        private void checkCaller() {
20243            if (mCallingUid != Binder.getCallingUid()) {
20244                throw new SecurityException("Caller " + mCallingUid
20245                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20246            }
20247        }
20248
20249        @Override
20250        public void finishAndRemoveTask() {
20251            checkCaller();
20252
20253            synchronized (ActivityManagerService.this) {
20254                long origId = Binder.clearCallingIdentity();
20255                try {
20256                    // We remove the task from recents to preserve backwards
20257                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20258                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20259                    }
20260                } finally {
20261                    Binder.restoreCallingIdentity(origId);
20262                }
20263            }
20264        }
20265
20266        @Override
20267        public ActivityManager.RecentTaskInfo getTaskInfo() {
20268            checkCaller();
20269
20270            synchronized (ActivityManagerService.this) {
20271                long origId = Binder.clearCallingIdentity();
20272                try {
20273                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20274                    if (tr == null) {
20275                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20276                    }
20277                    return createRecentTaskInfoFromTaskRecord(tr);
20278                } finally {
20279                    Binder.restoreCallingIdentity(origId);
20280                }
20281            }
20282        }
20283
20284        @Override
20285        public void moveToFront() {
20286            checkCaller();
20287            // Will bring task to front if it already has a root activity.
20288            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20289        }
20290
20291        @Override
20292        public int startActivity(IBinder whoThread, String callingPackage,
20293                Intent intent, String resolvedType, Bundle bOptions) {
20294            checkCaller();
20295
20296            int callingUser = UserHandle.getCallingUserId();
20297            TaskRecord tr;
20298            IApplicationThread appThread;
20299            synchronized (ActivityManagerService.this) {
20300                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20301                if (tr == null) {
20302                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20303                }
20304                appThread = ApplicationThreadNative.asInterface(whoThread);
20305                if (appThread == null) {
20306                    throw new IllegalArgumentException("Bad app thread " + appThread);
20307                }
20308            }
20309            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20310                    resolvedType, null, null, null, null, 0, 0, null, null,
20311                    null, bOptions, false, callingUser, null, tr);
20312        }
20313
20314        @Override
20315        public void setExcludeFromRecents(boolean exclude) {
20316            checkCaller();
20317
20318            synchronized (ActivityManagerService.this) {
20319                long origId = Binder.clearCallingIdentity();
20320                try {
20321                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20322                    if (tr == null) {
20323                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20324                    }
20325                    Intent intent = tr.getBaseIntent();
20326                    if (exclude) {
20327                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20328                    } else {
20329                        intent.setFlags(intent.getFlags()
20330                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20331                    }
20332                } finally {
20333                    Binder.restoreCallingIdentity(origId);
20334                }
20335            }
20336        }
20337    }
20338}
20339