ActivityManagerService.java revision 27c073796978106746e4a51f2100b29068ab37f6
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 notifyPackageUse(String packageName) {
3064        IPackageManager pm = AppGlobals.getPackageManager();
3065        try {
3066            pm.notifyPackageUse(packageName);
3067        } catch (RemoteException e) {
3068        }
3069    }
3070
3071    boolean isNextTransitionForward() {
3072        int transit = mWindowManager.getPendingAppTransition();
3073        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3074                || transit == AppTransition.TRANSIT_TASK_OPEN
3075                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3076    }
3077
3078    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3079            String processName, String abiOverride, int uid, Runnable crashHandler) {
3080        synchronized(this) {
3081            ApplicationInfo info = new ApplicationInfo();
3082            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3083            // For isolated processes, the former contains the parent's uid and the latter the
3084            // actual uid of the isolated process.
3085            // In the special case introduced by this method (which is, starting an isolated
3086            // process directly from the SystemServer without an actual parent app process) the
3087            // closest thing to a parent's uid is SYSTEM_UID.
3088            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3089            // the |isolated| logic in the ProcessRecord constructor.
3090            info.uid = Process.SYSTEM_UID;
3091            info.processName = processName;
3092            info.className = entryPoint;
3093            info.packageName = "android";
3094            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3095                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3096                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3097                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3098                    crashHandler);
3099            return proc != null ? proc.pid : 0;
3100        }
3101    }
3102
3103    final ProcessRecord startProcessLocked(String processName,
3104            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3105            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3106            boolean isolated, boolean keepIfLarge) {
3107        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3108                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3109                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3110                null /* crashHandler */);
3111    }
3112
3113    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3114            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3115            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3116            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3117        long startTime = SystemClock.elapsedRealtime();
3118        ProcessRecord app;
3119        if (!isolated) {
3120            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3121            checkTime(startTime, "startProcess: after getProcessRecord");
3122
3123            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3124                // If we are in the background, then check to see if this process
3125                // is bad.  If so, we will just silently fail.
3126                if (mBadProcesses.get(info.processName, info.uid) != null) {
3127                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3128                            + "/" + info.processName);
3129                    return null;
3130                }
3131            } else {
3132                // When the user is explicitly starting a process, then clear its
3133                // crash count so that we won't make it bad until they see at
3134                // least one crash dialog again, and make the process good again
3135                // if it had been bad.
3136                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3137                        + "/" + info.processName);
3138                mProcessCrashTimes.remove(info.processName, info.uid);
3139                if (mBadProcesses.get(info.processName, info.uid) != null) {
3140                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3141                            UserHandle.getUserId(info.uid), info.uid,
3142                            info.processName);
3143                    mBadProcesses.remove(info.processName, info.uid);
3144                    if (app != null) {
3145                        app.bad = false;
3146                    }
3147                }
3148            }
3149        } else {
3150            // If this is an isolated process, it can't re-use an existing process.
3151            app = null;
3152        }
3153
3154        // app launch boost for big.little configurations
3155        // use cpusets to migrate freshly launched tasks to big cores
3156        synchronized(ActivityManagerService.this) {
3157            nativeMigrateToBoost();
3158            mIsBoosted = true;
3159            mBoostStartTime = SystemClock.uptimeMillis();
3160            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3161            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3162        }
3163
3164        // We don't have to do anything more if:
3165        // (1) There is an existing application record; and
3166        // (2) The caller doesn't think it is dead, OR there is no thread
3167        //     object attached to it so we know it couldn't have crashed; and
3168        // (3) There is a pid assigned to it, so it is either starting or
3169        //     already running.
3170        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3171                + " app=" + app + " knownToBeDead=" + knownToBeDead
3172                + " thread=" + (app != null ? app.thread : null)
3173                + " pid=" + (app != null ? app.pid : -1));
3174        if (app != null && app.pid > 0) {
3175            if (!knownToBeDead || app.thread == null) {
3176                // We already have the app running, or are waiting for it to
3177                // come up (we have a pid but not yet its thread), so keep it.
3178                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3179                // If this is a new package in the process, add the package to the list
3180                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3181                checkTime(startTime, "startProcess: done, added package to proc");
3182                return app;
3183            }
3184
3185            // An application record is attached to a previous process,
3186            // clean it up now.
3187            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3188            checkTime(startTime, "startProcess: bad proc running, killing");
3189            killProcessGroup(app.info.uid, app.pid);
3190            handleAppDiedLocked(app, true, true);
3191            checkTime(startTime, "startProcess: done killing old proc");
3192        }
3193
3194        String hostingNameStr = hostingName != null
3195                ? hostingName.flattenToShortString() : null;
3196
3197        if (app == null) {
3198            checkTime(startTime, "startProcess: creating new process record");
3199            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3200            if (app == null) {
3201                Slog.w(TAG, "Failed making new process record for "
3202                        + processName + "/" + info.uid + " isolated=" + isolated);
3203                return null;
3204            }
3205            app.crashHandler = crashHandler;
3206            checkTime(startTime, "startProcess: done creating new process record");
3207        } else {
3208            // If this is a new package in the process, add the package to the list
3209            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3210            checkTime(startTime, "startProcess: added package to existing proc");
3211        }
3212
3213        // If the system is not ready yet, then hold off on starting this
3214        // process until it is.
3215        if (!mProcessesReady
3216                && !isAllowedWhileBooting(info)
3217                && !allowWhileBooting) {
3218            if (!mProcessesOnHold.contains(app)) {
3219                mProcessesOnHold.add(app);
3220            }
3221            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3222                    "System not ready, putting on hold: " + app);
3223            checkTime(startTime, "startProcess: returning with proc on hold");
3224            return app;
3225        }
3226
3227        checkTime(startTime, "startProcess: stepping in to startProcess");
3228        startProcessLocked(
3229                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3230        checkTime(startTime, "startProcess: done starting proc!");
3231        return (app.pid != 0) ? app : null;
3232    }
3233
3234    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3235        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3236    }
3237
3238    private final void startProcessLocked(ProcessRecord app,
3239            String hostingType, String hostingNameStr) {
3240        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3241                null /* entryPoint */, null /* entryPointArgs */);
3242    }
3243
3244    private final void startProcessLocked(ProcessRecord app, String hostingType,
3245            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3246        long startTime = SystemClock.elapsedRealtime();
3247        if (app.pid > 0 && app.pid != MY_PID) {
3248            checkTime(startTime, "startProcess: removing from pids map");
3249            synchronized (mPidsSelfLocked) {
3250                mPidsSelfLocked.remove(app.pid);
3251                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3252            }
3253            checkTime(startTime, "startProcess: done removing from pids map");
3254            app.setPid(0);
3255        }
3256
3257        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3258                "startProcessLocked removing on hold: " + app);
3259        mProcessesOnHold.remove(app);
3260
3261        checkTime(startTime, "startProcess: starting to update cpu stats");
3262        updateCpuStats();
3263        checkTime(startTime, "startProcess: done updating cpu stats");
3264
3265        try {
3266            try {
3267                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3268                    // This is caught below as if we had failed to fork zygote
3269                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3270                }
3271            } catch (RemoteException e) {
3272                throw e.rethrowAsRuntimeException();
3273            }
3274
3275            int uid = app.uid;
3276            int[] gids = null;
3277            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3278            if (!app.isolated) {
3279                int[] permGids = null;
3280                try {
3281                    checkTime(startTime, "startProcess: getting gids from package manager");
3282                    final IPackageManager pm = AppGlobals.getPackageManager();
3283                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3284                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3285                            MountServiceInternal.class);
3286                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3287                            app.info.packageName);
3288                } catch (RemoteException e) {
3289                    throw e.rethrowAsRuntimeException();
3290                }
3291
3292                /*
3293                 * Add shared application and profile GIDs so applications can share some
3294                 * resources like shared libraries and access user-wide resources
3295                 */
3296                if (ArrayUtils.isEmpty(permGids)) {
3297                    gids = new int[2];
3298                } else {
3299                    gids = new int[permGids.length + 2];
3300                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3301                }
3302                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3303                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3304            }
3305            checkTime(startTime, "startProcess: building args");
3306            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3307                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3308                        && mTopComponent != null
3309                        && app.processName.equals(mTopComponent.getPackageName())) {
3310                    uid = 0;
3311                }
3312                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3313                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3314                    uid = 0;
3315                }
3316            }
3317            int debugFlags = 0;
3318            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3319                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3320                // Also turn on CheckJNI for debuggable apps. It's quite
3321                // awkward to turn on otherwise.
3322                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3323            }
3324            // Run the app in safe mode if its manifest requests so or the
3325            // system is booted in safe mode.
3326            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3327                mSafeMode == true) {
3328                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3329            }
3330            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3331                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3332            }
3333            String jitDebugProperty = SystemProperties.get("debug.usejit");
3334            if ("true".equals(jitDebugProperty)) {
3335                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3336            } else if (!"false".equals(jitDebugProperty)) {
3337                // If we didn't force disable by setting false, defer to the dalvik vm options.
3338                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3339                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3340                }
3341            }
3342            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3343            if ("true".equals(genDebugInfoProperty)) {
3344                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3345            }
3346            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3347                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3348            }
3349            if ("1".equals(SystemProperties.get("debug.assert"))) {
3350                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3351            }
3352
3353            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3354            if (requiredAbi == null) {
3355                requiredAbi = Build.SUPPORTED_ABIS[0];
3356            }
3357
3358            String instructionSet = null;
3359            if (app.info.primaryCpuAbi != null) {
3360                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3361            }
3362
3363            app.gids = gids;
3364            app.requiredAbi = requiredAbi;
3365            app.instructionSet = instructionSet;
3366
3367            // Start the process.  It will either succeed and return a result containing
3368            // the PID of the new process, or else throw a RuntimeException.
3369            boolean isActivityProcess = (entryPoint == null);
3370            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3371            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3372                    app.processName);
3373            checkTime(startTime, "startProcess: asking zygote to start proc");
3374            Process.ProcessStartResult startResult = Process.start(entryPoint,
3375                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3376                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3377                    app.info.dataDir, entryPointArgs);
3378            checkTime(startTime, "startProcess: returned from zygote!");
3379            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3380
3381            if (app.isolated) {
3382                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3383            }
3384            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3385            checkTime(startTime, "startProcess: done updating battery stats");
3386
3387            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3388                    UserHandle.getUserId(uid), startResult.pid, uid,
3389                    app.processName, hostingType,
3390                    hostingNameStr != null ? hostingNameStr : "");
3391
3392            if (app.persistent) {
3393                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3394            }
3395
3396            checkTime(startTime, "startProcess: building log message");
3397            StringBuilder buf = mStringBuilder;
3398            buf.setLength(0);
3399            buf.append("Start proc ");
3400            buf.append(startResult.pid);
3401            buf.append(':');
3402            buf.append(app.processName);
3403            buf.append('/');
3404            UserHandle.formatUid(buf, uid);
3405            if (!isActivityProcess) {
3406                buf.append(" [");
3407                buf.append(entryPoint);
3408                buf.append("]");
3409            }
3410            buf.append(" for ");
3411            buf.append(hostingType);
3412            if (hostingNameStr != null) {
3413                buf.append(" ");
3414                buf.append(hostingNameStr);
3415            }
3416            Slog.i(TAG, buf.toString());
3417            app.setPid(startResult.pid);
3418            app.usingWrapper = startResult.usingWrapper;
3419            app.removed = false;
3420            app.killed = false;
3421            app.killedByAm = false;
3422            checkTime(startTime, "startProcess: starting to update pids map");
3423            synchronized (mPidsSelfLocked) {
3424                this.mPidsSelfLocked.put(startResult.pid, app);
3425                if (isActivityProcess) {
3426                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3427                    msg.obj = app;
3428                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3429                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3430                }
3431            }
3432            checkTime(startTime, "startProcess: done updating pids map");
3433        } catch (RuntimeException e) {
3434            // XXX do better error recovery.
3435            app.setPid(0);
3436            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3437            if (app.isolated) {
3438                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3439            }
3440            Slog.e(TAG, "Failure starting process " + app.processName, e);
3441        }
3442    }
3443
3444    void updateUsageStats(ActivityRecord component, boolean resumed) {
3445        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3446                "updateUsageStats: comp=" + component + "res=" + resumed);
3447        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3448        if (resumed) {
3449            if (mUsageStatsService != null) {
3450                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3451                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3452            }
3453            synchronized (stats) {
3454                stats.noteActivityResumedLocked(component.app.uid);
3455            }
3456        } else {
3457            if (mUsageStatsService != null) {
3458                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3459                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3460            }
3461            synchronized (stats) {
3462                stats.noteActivityPausedLocked(component.app.uid);
3463            }
3464        }
3465    }
3466
3467    Intent getHomeIntent() {
3468        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3469        intent.setComponent(mTopComponent);
3470        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3471            intent.addCategory(Intent.CATEGORY_HOME);
3472        }
3473        return intent;
3474    }
3475
3476    boolean startHomeActivityLocked(int userId, String reason) {
3477        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3478                && mTopAction == null) {
3479            // We are running in factory test mode, but unable to find
3480            // the factory test app, so just sit around displaying the
3481            // error message and don't try to start anything.
3482            return false;
3483        }
3484        Intent intent = getHomeIntent();
3485        ActivityInfo aInfo =
3486            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3487        if (aInfo != null) {
3488            intent.setComponent(new ComponentName(
3489                    aInfo.applicationInfo.packageName, aInfo.name));
3490            // Don't do this if the home app is currently being
3491            // instrumented.
3492            aInfo = new ActivityInfo(aInfo);
3493            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3494            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3495                    aInfo.applicationInfo.uid, true);
3496            if (app == null || app.instrumentationClass == null) {
3497                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3498                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3499            }
3500        }
3501
3502        return true;
3503    }
3504
3505    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3506        ActivityInfo ai = null;
3507        ComponentName comp = intent.getComponent();
3508        try {
3509            if (comp != null) {
3510                // Factory test.
3511                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3512            } else {
3513                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3514                        intent,
3515                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3516                        flags, userId);
3517
3518                if (info != null) {
3519                    ai = info.activityInfo;
3520                }
3521            }
3522        } catch (RemoteException e) {
3523            // ignore
3524        }
3525
3526        return ai;
3527    }
3528
3529    /**
3530     * Starts the "new version setup screen" if appropriate.
3531     */
3532    void startSetupActivityLocked() {
3533        // Only do this once per boot.
3534        if (mCheckedForSetup) {
3535            return;
3536        }
3537
3538        // We will show this screen if the current one is a different
3539        // version than the last one shown, and we are not running in
3540        // low-level factory test mode.
3541        final ContentResolver resolver = mContext.getContentResolver();
3542        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3543                Settings.Global.getInt(resolver,
3544                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3545            mCheckedForSetup = true;
3546
3547            // See if we should be showing the platform update setup UI.
3548            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3549            List<ResolveInfo> ris = mContext.getPackageManager()
3550                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3551
3552            // We don't allow third party apps to replace this.
3553            ResolveInfo ri = null;
3554            for (int i=0; ris != null && i<ris.size(); i++) {
3555                if ((ris.get(i).activityInfo.applicationInfo.flags
3556                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3557                    ri = ris.get(i);
3558                    break;
3559                }
3560            }
3561
3562            if (ri != null) {
3563                String vers = ri.activityInfo.metaData != null
3564                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3565                        : null;
3566                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3567                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3568                            Intent.METADATA_SETUP_VERSION);
3569                }
3570                String lastVers = Settings.Secure.getString(
3571                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3572                if (vers != null && !vers.equals(lastVers)) {
3573                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3574                    intent.setComponent(new ComponentName(
3575                            ri.activityInfo.packageName, ri.activityInfo.name));
3576                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3577                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3578                            null, null, null);
3579                }
3580            }
3581        }
3582    }
3583
3584    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3585        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3586    }
3587
3588    void enforceNotIsolatedCaller(String caller) {
3589        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3590            throw new SecurityException("Isolated process not allowed to call " + caller);
3591        }
3592    }
3593
3594    void enforceShellRestriction(String restriction, int userHandle) {
3595        if (Binder.getCallingUid() == Process.SHELL_UID) {
3596            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3597                throw new SecurityException("Shell does not have permission to access user "
3598                        + userHandle);
3599            }
3600        }
3601    }
3602
3603    @Override
3604    public int getFrontActivityScreenCompatMode() {
3605        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3606        synchronized (this) {
3607            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3608        }
3609    }
3610
3611    @Override
3612    public void setFrontActivityScreenCompatMode(int mode) {
3613        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3614                "setFrontActivityScreenCompatMode");
3615        synchronized (this) {
3616            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3617        }
3618    }
3619
3620    @Override
3621    public int getPackageScreenCompatMode(String packageName) {
3622        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3623        synchronized (this) {
3624            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3625        }
3626    }
3627
3628    @Override
3629    public void setPackageScreenCompatMode(String packageName, int mode) {
3630        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3631                "setPackageScreenCompatMode");
3632        synchronized (this) {
3633            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3634        }
3635    }
3636
3637    @Override
3638    public boolean getPackageAskScreenCompat(String packageName) {
3639        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3640        synchronized (this) {
3641            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3642        }
3643    }
3644
3645    @Override
3646    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3647        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3648                "setPackageAskScreenCompat");
3649        synchronized (this) {
3650            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3651        }
3652    }
3653
3654    private boolean hasUsageStatsPermission(String callingPackage) {
3655        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3656                Binder.getCallingUid(), callingPackage);
3657        if (mode == AppOpsManager.MODE_DEFAULT) {
3658            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3659                    == PackageManager.PERMISSION_GRANTED;
3660        }
3661        return mode == AppOpsManager.MODE_ALLOWED;
3662    }
3663
3664    @Override
3665    public int getPackageProcessState(String packageName, String callingPackage) {
3666        if (!hasUsageStatsPermission(callingPackage)) {
3667            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3668                    "getPackageProcessState");
3669        }
3670
3671        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3672        synchronized (this) {
3673            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674                final ProcessRecord proc = mLruProcesses.get(i);
3675                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3676                        || procState > proc.setProcState) {
3677                    boolean found = false;
3678                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3679                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3680                            procState = proc.setProcState;
3681                            found = true;
3682                        }
3683                    }
3684                    if (proc.pkgDeps != null && !found) {
3685                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3686                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3687                                procState = proc.setProcState;
3688                                break;
3689                            }
3690                        }
3691                    }
3692                }
3693            }
3694        }
3695        return procState;
3696    }
3697
3698    @Override
3699    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3700        synchronized (this) {
3701            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3702            if (app == null) {
3703                return false;
3704            }
3705            if (app.trimMemoryLevel < level && app.thread != null &&
3706                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3707                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3708                try {
3709                    app.thread.scheduleTrimMemory(level);
3710                    app.trimMemoryLevel = level;
3711                    return true;
3712                } catch (RemoteException e) {
3713                    // Fallthrough to failure case.
3714                }
3715            }
3716        }
3717        return false;
3718    }
3719
3720    private void dispatchProcessesChanged() {
3721        int N;
3722        synchronized (this) {
3723            N = mPendingProcessChanges.size();
3724            if (mActiveProcessChanges.length < N) {
3725                mActiveProcessChanges = new ProcessChangeItem[N];
3726            }
3727            mPendingProcessChanges.toArray(mActiveProcessChanges);
3728            mPendingProcessChanges.clear();
3729            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3730                    "*** Delivering " + N + " process changes");
3731        }
3732
3733        int i = mProcessObservers.beginBroadcast();
3734        while (i > 0) {
3735            i--;
3736            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3737            if (observer != null) {
3738                try {
3739                    for (int j=0; j<N; j++) {
3740                        ProcessChangeItem item = mActiveProcessChanges[j];
3741                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3742                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3743                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3744                                    + item.uid + ": " + item.foregroundActivities);
3745                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3746                                    item.foregroundActivities);
3747                        }
3748                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3749                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3750                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3751                                    + ": " + item.processState);
3752                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3753                        }
3754                    }
3755                } catch (RemoteException e) {
3756                }
3757            }
3758        }
3759        mProcessObservers.finishBroadcast();
3760
3761        synchronized (this) {
3762            for (int j=0; j<N; j++) {
3763                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3764            }
3765        }
3766    }
3767
3768    private void dispatchProcessDied(int pid, int uid) {
3769        int i = mProcessObservers.beginBroadcast();
3770        while (i > 0) {
3771            i--;
3772            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3773            if (observer != null) {
3774                try {
3775                    observer.onProcessDied(pid, uid);
3776                } catch (RemoteException e) {
3777                }
3778            }
3779        }
3780        mProcessObservers.finishBroadcast();
3781    }
3782
3783    private void dispatchUidsChanged() {
3784        int N;
3785        synchronized (this) {
3786            N = mPendingUidChanges.size();
3787            if (mActiveUidChanges.length < N) {
3788                mActiveUidChanges = new UidRecord.ChangeItem[N];
3789            }
3790            for (int i=0; i<N; i++) {
3791                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3792                mActiveUidChanges[i] = change;
3793                change.uidRecord.pendingChange = null;
3794                change.uidRecord = null;
3795            }
3796            mPendingUidChanges.clear();
3797            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3798                    "*** Delivering " + N + " uid changes");
3799        }
3800
3801        if (mLocalPowerManager != null) {
3802            for (int j=0; j<N; j++) {
3803                UidRecord.ChangeItem item = mActiveUidChanges[j];
3804                if (item.gone) {
3805                    mLocalPowerManager.uidGone(item.uid);
3806                } else {
3807                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3808                }
3809            }
3810        }
3811
3812        int i = mUidObservers.beginBroadcast();
3813        while (i > 0) {
3814            i--;
3815            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3816            if (observer != null) {
3817                try {
3818                    for (int j=0; j<N; j++) {
3819                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3820                        if (item.gone) {
3821                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3822                                    "UID gone uid=" + item.uid);
3823                            observer.onUidGone(item.uid);
3824                        } else {
3825                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3826                                    "UID CHANGED uid=" + item.uid
3827                                    + ": " + item.processState);
3828                            observer.onUidStateChanged(item.uid, item.processState);
3829                        }
3830                    }
3831                } catch (RemoteException e) {
3832                }
3833            }
3834        }
3835        mUidObservers.finishBroadcast();
3836
3837        synchronized (this) {
3838            for (int j=0; j<N; j++) {
3839                mAvailUidChanges.add(mActiveUidChanges[j]);
3840            }
3841        }
3842    }
3843
3844    @Override
3845    public final int startActivity(IApplicationThread caller, String callingPackage,
3846            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3847            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
3848        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3849                resultWho, requestCode, startFlags, profilerInfo, bOptions,
3850                UserHandle.getCallingUserId());
3851    }
3852
3853    @Override
3854    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3855            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3856            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3857        enforceNotIsolatedCaller("startActivity");
3858        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3859                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
3860        // TODO: Switch to user app stacks here.
3861        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3862                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3863                profilerInfo, null, null, bOptions, false, userId, null, null);
3864    }
3865
3866    @Override
3867    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3868            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3869            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
3870            int userId) {
3871
3872        // This is very dangerous -- it allows you to perform a start activity (including
3873        // permission grants) as any app that may launch one of your own activities.  So
3874        // we will only allow this to be done from activities that are part of the core framework,
3875        // and then only when they are running as the system.
3876        final ActivityRecord sourceRecord;
3877        final int targetUid;
3878        final String targetPackage;
3879        synchronized (this) {
3880            if (resultTo == null) {
3881                throw new SecurityException("Must be called from an activity");
3882            }
3883            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3884            if (sourceRecord == null) {
3885                throw new SecurityException("Called with bad activity token: " + resultTo);
3886            }
3887            if (!sourceRecord.info.packageName.equals("android")) {
3888                throw new SecurityException(
3889                        "Must be called from an activity that is declared in the android package");
3890            }
3891            if (sourceRecord.app == null) {
3892                throw new SecurityException("Called without a process attached to activity");
3893            }
3894            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3895                // This is still okay, as long as this activity is running under the
3896                // uid of the original calling activity.
3897                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3898                    throw new SecurityException(
3899                            "Calling activity in uid " + sourceRecord.app.uid
3900                                    + " must be system uid or original calling uid "
3901                                    + sourceRecord.launchedFromUid);
3902                }
3903            }
3904            if (ignoreTargetSecurity) {
3905                if (intent.getComponent() == null) {
3906                    throw new SecurityException(
3907                            "Component must be specified with ignoreTargetSecurity");
3908                }
3909                if (intent.getSelector() != null) {
3910                    throw new SecurityException(
3911                            "Selector not allowed with ignoreTargetSecurity");
3912                }
3913            }
3914            targetUid = sourceRecord.launchedFromUid;
3915            targetPackage = sourceRecord.launchedFromPackage;
3916        }
3917
3918        if (userId == UserHandle.USER_NULL) {
3919            userId = UserHandle.getUserId(sourceRecord.app.uid);
3920        }
3921
3922        // TODO: Switch to user app stacks here.
3923        try {
3924            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3925                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3926                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
3927            return ret;
3928        } catch (SecurityException e) {
3929            // XXX need to figure out how to propagate to original app.
3930            // A SecurityException here is generally actually a fault of the original
3931            // calling activity (such as a fairly granting permissions), so propagate it
3932            // back to them.
3933            /*
3934            StringBuilder msg = new StringBuilder();
3935            msg.append("While launching");
3936            msg.append(intent.toString());
3937            msg.append(": ");
3938            msg.append(e.getMessage());
3939            */
3940            throw e;
3941        }
3942    }
3943
3944    @Override
3945    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3946            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3947            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3948        enforceNotIsolatedCaller("startActivityAndWait");
3949        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3950                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3951        WaitResult res = new WaitResult();
3952        // TODO: Switch to user app stacks here.
3953        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3954                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3955                bOptions, false, userId, null, null);
3956        return res;
3957    }
3958
3959    @Override
3960    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3961            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3962            int startFlags, Configuration config, Bundle bOptions, int userId) {
3963        enforceNotIsolatedCaller("startActivityWithConfig");
3964        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3965                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3966        // TODO: Switch to user app stacks here.
3967        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3968                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3969                null, null, config, bOptions, false, userId, null, null);
3970        return ret;
3971    }
3972
3973    @Override
3974    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3975            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3976            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
3977            throws TransactionTooLargeException {
3978        enforceNotIsolatedCaller("startActivityIntentSender");
3979        // Refuse possible leaked file descriptors
3980        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3981            throw new IllegalArgumentException("File descriptors passed in Intent");
3982        }
3983
3984        IIntentSender sender = intent.getTarget();
3985        if (!(sender instanceof PendingIntentRecord)) {
3986            throw new IllegalArgumentException("Bad PendingIntent object");
3987        }
3988
3989        PendingIntentRecord pir = (PendingIntentRecord)sender;
3990
3991        synchronized (this) {
3992            // If this is coming from the currently resumed activity, it is
3993            // effectively saying that app switches are allowed at this point.
3994            final ActivityStack stack = getFocusedStack();
3995            if (stack.mResumedActivity != null &&
3996                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3997                mAppSwitchesAllowedTime = 0;
3998            }
3999        }
4000        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4001                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4002        return ret;
4003    }
4004
4005    @Override
4006    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4007            Intent intent, String resolvedType, IVoiceInteractionSession session,
4008            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4009            Bundle bOptions, int userId) {
4010        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4011                != PackageManager.PERMISSION_GRANTED) {
4012            String msg = "Permission Denial: startVoiceActivity() from pid="
4013                    + Binder.getCallingPid()
4014                    + ", uid=" + Binder.getCallingUid()
4015                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4016            Slog.w(TAG, msg);
4017            throw new SecurityException(msg);
4018        }
4019        if (session == null || interactor == null) {
4020            throw new NullPointerException("null session or interactor");
4021        }
4022        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4023                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4024        // TODO: Switch to user app stacks here.
4025        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4026                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4027                null, bOptions, false, userId, null, null);
4028    }
4029
4030    @Override
4031    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4032        synchronized (this) {
4033            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4034                if (keepAwake) {
4035                    mVoiceWakeLock.acquire();
4036                } else {
4037                    mVoiceWakeLock.release();
4038                }
4039            }
4040        }
4041    }
4042
4043    @Override
4044    public boolean startNextMatchingActivity(IBinder callingActivity,
4045            Intent intent, Bundle bOptions) {
4046        // Refuse possible leaked file descriptors
4047        if (intent != null && intent.hasFileDescriptors() == true) {
4048            throw new IllegalArgumentException("File descriptors passed in Intent");
4049        }
4050        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4051
4052        synchronized (this) {
4053            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4054            if (r == null) {
4055                ActivityOptions.abort(options);
4056                return false;
4057            }
4058            if (r.app == null || r.app.thread == null) {
4059                // The caller is not running...  d'oh!
4060                ActivityOptions.abort(options);
4061                return false;
4062            }
4063            intent = new Intent(intent);
4064            // The caller is not allowed to change the data.
4065            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4066            // And we are resetting to find the next component...
4067            intent.setComponent(null);
4068
4069            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4070
4071            ActivityInfo aInfo = null;
4072            try {
4073                List<ResolveInfo> resolves =
4074                    AppGlobals.getPackageManager().queryIntentActivities(
4075                            intent, r.resolvedType,
4076                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4077                            UserHandle.getCallingUserId());
4078
4079                // Look for the original activity in the list...
4080                final int N = resolves != null ? resolves.size() : 0;
4081                for (int i=0; i<N; i++) {
4082                    ResolveInfo rInfo = resolves.get(i);
4083                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4084                            && rInfo.activityInfo.name.equals(r.info.name)) {
4085                        // We found the current one...  the next matching is
4086                        // after it.
4087                        i++;
4088                        if (i<N) {
4089                            aInfo = resolves.get(i).activityInfo;
4090                        }
4091                        if (debug) {
4092                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4093                                    + "/" + r.info.name);
4094                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4095                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4096                        }
4097                        break;
4098                    }
4099                }
4100            } catch (RemoteException e) {
4101            }
4102
4103            if (aInfo == null) {
4104                // Nobody who is next!
4105                ActivityOptions.abort(options);
4106                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4107                return false;
4108            }
4109
4110            intent.setComponent(new ComponentName(
4111                    aInfo.applicationInfo.packageName, aInfo.name));
4112            intent.setFlags(intent.getFlags()&~(
4113                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4114                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4115                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4116                    Intent.FLAG_ACTIVITY_NEW_TASK));
4117
4118            // Okay now we need to start the new activity, replacing the
4119            // currently running activity.  This is a little tricky because
4120            // we want to start the new one as if the current one is finished,
4121            // but not finish the current one first so that there is no flicker.
4122            // And thus...
4123            final boolean wasFinishing = r.finishing;
4124            r.finishing = true;
4125
4126            // Propagate reply information over to the new activity.
4127            final ActivityRecord resultTo = r.resultTo;
4128            final String resultWho = r.resultWho;
4129            final int requestCode = r.requestCode;
4130            r.resultTo = null;
4131            if (resultTo != null) {
4132                resultTo.removeResultsLocked(r, resultWho, requestCode);
4133            }
4134
4135            final long origId = Binder.clearCallingIdentity();
4136            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4137                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4138                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4139                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4140            Binder.restoreCallingIdentity(origId);
4141
4142            r.finishing = wasFinishing;
4143            if (res != ActivityManager.START_SUCCESS) {
4144                return false;
4145            }
4146            return true;
4147        }
4148    }
4149
4150    @Override
4151    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4152        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4153            String msg = "Permission Denial: startActivityFromRecents called without " +
4154                    START_TASKS_FROM_RECENTS;
4155            Slog.w(TAG, msg);
4156            throw new SecurityException(msg);
4157        }
4158        final long origId = Binder.clearCallingIdentity();
4159        try {
4160            return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4161        } finally {
4162            Binder.restoreCallingIdentity(origId);
4163        }
4164    }
4165
4166    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4167        final TaskRecord task;
4168        final int callingUid;
4169        final String callingPackage;
4170        final Intent intent;
4171        final int userId;
4172        synchronized (this) {
4173            if (launchStackId == HOME_STACK_ID) {
4174                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4175                        + taskId + " can't be launch in the home stack.");
4176            }
4177
4178            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4179            if (task == null) {
4180                throw new IllegalArgumentException(
4181                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4182            }
4183
4184            if (launchStackId != INVALID_STACK_ID && task.stack.mStackId != launchStackId) {
4185                if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4186                    ActivityOptions activityOptions = new ActivityOptions(bOptions);
4187                    mWindowManager.setDockedStackCreateMode(activityOptions.getDockCreateMode());
4188                }
4189                mStackSupervisor.moveTaskToStackLocked(
4190                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents");
4191            }
4192
4193            if (task.getRootActivity() != null) {
4194                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4195                return ActivityManager.START_TASK_TO_FRONT;
4196            }
4197            callingUid = task.mCallingUid;
4198            callingPackage = task.mCallingPackage;
4199            intent = task.intent;
4200            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4201            userId = task.userId;
4202        }
4203        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4204                bOptions, userId, null, task);
4205    }
4206
4207    final int startActivityInPackage(int uid, String callingPackage,
4208            Intent intent, String resolvedType, IBinder resultTo,
4209            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4210            IActivityContainer container, TaskRecord inTask) {
4211
4212        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4213                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4214
4215        // TODO: Switch to user app stacks here.
4216        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4217                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4218                null, null, null, bOptions, false, userId, container, inTask);
4219        return ret;
4220    }
4221
4222    @Override
4223    public final int startActivities(IApplicationThread caller, String callingPackage,
4224            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4225            int userId) {
4226        enforceNotIsolatedCaller("startActivities");
4227        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4228                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4229        // TODO: Switch to user app stacks here.
4230        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4231                resolvedTypes, resultTo, bOptions, userId);
4232        return ret;
4233    }
4234
4235    final int startActivitiesInPackage(int uid, String callingPackage,
4236            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4237            Bundle bOptions, int userId) {
4238
4239        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4240                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4241        // TODO: Switch to user app stacks here.
4242        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4243                resultTo, bOptions, userId);
4244        return ret;
4245    }
4246
4247    @Override
4248    public void reportActivityFullyDrawn(IBinder token) {
4249        synchronized (this) {
4250            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4251            if (r == null) {
4252                return;
4253            }
4254            r.reportFullyDrawnLocked();
4255        }
4256    }
4257
4258    @Override
4259    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4260        synchronized (this) {
4261            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4262            if (r == null) {
4263                return;
4264            }
4265            if (r.task != null && r.task.mResizeable) {
4266                // Fixed screen orientation isn't supported with resizeable activities.
4267                return;
4268            }
4269            final long origId = Binder.clearCallingIdentity();
4270            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4271            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4272                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4273            if (config != null) {
4274                r.frozenBeforeDestroy = true;
4275                if (!updateConfigurationLocked(config, r, false)) {
4276                    mStackSupervisor.resumeTopActivitiesLocked();
4277                }
4278            }
4279            Binder.restoreCallingIdentity(origId);
4280        }
4281    }
4282
4283    @Override
4284    public int getRequestedOrientation(IBinder token) {
4285        synchronized (this) {
4286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4287            if (r == null) {
4288                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4289            }
4290            return mWindowManager.getAppOrientation(r.appToken);
4291        }
4292    }
4293
4294    /**
4295     * This is the internal entry point for handling Activity.finish().
4296     *
4297     * @param token The Binder token referencing the Activity we want to finish.
4298     * @param resultCode Result code, if any, from this Activity.
4299     * @param resultData Result data (Intent), if any, from this Activity.
4300     * @param finishTask Whether to finish the task associated with this Activity.
4301     *
4302     * @return Returns true if the activity successfully finished, or false if it is still running.
4303     */
4304    @Override
4305    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4306            int finishTask) {
4307        // Refuse possible leaked file descriptors
4308        if (resultData != null && resultData.hasFileDescriptors() == true) {
4309            throw new IllegalArgumentException("File descriptors passed in Intent");
4310        }
4311
4312        synchronized(this) {
4313            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4314            if (r == null) {
4315                return true;
4316            }
4317            // Keep track of the root activity of the task before we finish it
4318            TaskRecord tr = r.task;
4319            ActivityRecord rootR = tr.getRootActivity();
4320            if (rootR == null) {
4321                Slog.w(TAG, "Finishing task with all activities already finished");
4322            }
4323            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4324            // finish.
4325            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4326                    mStackSupervisor.isLastLockedTask(tr)) {
4327                Slog.i(TAG, "Not finishing task in lock task mode");
4328                mStackSupervisor.showLockTaskToast();
4329                return false;
4330            }
4331            if (mController != null) {
4332                // Find the first activity that is not finishing.
4333                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4334                if (next != null) {
4335                    // ask watcher if this is allowed
4336                    boolean resumeOK = true;
4337                    try {
4338                        resumeOK = mController.activityResuming(next.packageName);
4339                    } catch (RemoteException e) {
4340                        mController = null;
4341                        Watchdog.getInstance().setActivityController(null);
4342                    }
4343
4344                    if (!resumeOK) {
4345                        Slog.i(TAG, "Not finishing activity because controller resumed");
4346                        return false;
4347                    }
4348                }
4349            }
4350            final long origId = Binder.clearCallingIdentity();
4351            try {
4352                boolean res;
4353                final boolean finishWithRootActivity =
4354                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4355                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4356                        || (finishWithRootActivity && r == rootR)) {
4357                    // If requested, remove the task that is associated to this activity only if it
4358                    // was the root activity in the task. The result code and data is ignored
4359                    // because we don't support returning them across task boundaries. Also, to
4360                    // keep backwards compatibility we remove the task from recents when finishing
4361                    // task with root activity.
4362                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4363                    if (!res) {
4364                        Slog.i(TAG, "Removing task failed to finish activity");
4365                    }
4366                } else {
4367                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4368                            resultData, "app-request", true);
4369                    if (!res) {
4370                        Slog.i(TAG, "Failed to finish by app-request");
4371                    }
4372                }
4373                return res;
4374            } finally {
4375                Binder.restoreCallingIdentity(origId);
4376            }
4377        }
4378    }
4379
4380    @Override
4381    public final void finishHeavyWeightApp() {
4382        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4383                != PackageManager.PERMISSION_GRANTED) {
4384            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4385                    + Binder.getCallingPid()
4386                    + ", uid=" + Binder.getCallingUid()
4387                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4388            Slog.w(TAG, msg);
4389            throw new SecurityException(msg);
4390        }
4391
4392        synchronized(this) {
4393            if (mHeavyWeightProcess == null) {
4394                return;
4395            }
4396
4397            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4398            for (int i = 0; i < activities.size(); i++) {
4399                ActivityRecord r = activities.get(i);
4400                if (!r.finishing && r.isInStackLocked()) {
4401                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4402                            null, "finish-heavy", true);
4403                }
4404            }
4405
4406            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4407                    mHeavyWeightProcess.userId, 0));
4408            mHeavyWeightProcess = null;
4409        }
4410    }
4411
4412    @Override
4413    public void crashApplication(int uid, int initialPid, String packageName,
4414            String message) {
4415        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4416                != PackageManager.PERMISSION_GRANTED) {
4417            String msg = "Permission Denial: crashApplication() from pid="
4418                    + Binder.getCallingPid()
4419                    + ", uid=" + Binder.getCallingUid()
4420                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4421            Slog.w(TAG, msg);
4422            throw new SecurityException(msg);
4423        }
4424
4425        synchronized(this) {
4426            ProcessRecord proc = null;
4427
4428            // Figure out which process to kill.  We don't trust that initialPid
4429            // still has any relation to current pids, so must scan through the
4430            // list.
4431            synchronized (mPidsSelfLocked) {
4432                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4433                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4434                    if (p.uid != uid) {
4435                        continue;
4436                    }
4437                    if (p.pid == initialPid) {
4438                        proc = p;
4439                        break;
4440                    }
4441                    if (p.pkgList.containsKey(packageName)) {
4442                        proc = p;
4443                    }
4444                }
4445            }
4446
4447            if (proc == null) {
4448                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4449                        + " initialPid=" + initialPid
4450                        + " packageName=" + packageName);
4451                return;
4452            }
4453
4454            if (proc.thread != null) {
4455                if (proc.pid == Process.myPid()) {
4456                    Log.w(TAG, "crashApplication: trying to crash self!");
4457                    return;
4458                }
4459                long ident = Binder.clearCallingIdentity();
4460                try {
4461                    proc.thread.scheduleCrash(message);
4462                } catch (RemoteException e) {
4463                }
4464                Binder.restoreCallingIdentity(ident);
4465            }
4466        }
4467    }
4468
4469    @Override
4470    public final void finishSubActivity(IBinder token, String resultWho,
4471            int requestCode) {
4472        synchronized(this) {
4473            final long origId = Binder.clearCallingIdentity();
4474            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4475            if (r != null) {
4476                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4477            }
4478            Binder.restoreCallingIdentity(origId);
4479        }
4480    }
4481
4482    @Override
4483    public boolean finishActivityAffinity(IBinder token) {
4484        synchronized(this) {
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4488                if (r == null) {
4489                    return false;
4490                }
4491
4492                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4493                // can finish.
4494                final TaskRecord task = r.task;
4495                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4496                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4497                    mStackSupervisor.showLockTaskToast();
4498                    return false;
4499                }
4500                return task.stack.finishActivityAffinityLocked(r);
4501            } finally {
4502                Binder.restoreCallingIdentity(origId);
4503            }
4504        }
4505    }
4506
4507    @Override
4508    public void finishVoiceTask(IVoiceInteractionSession session) {
4509        synchronized(this) {
4510            final long origId = Binder.clearCallingIdentity();
4511            try {
4512                mStackSupervisor.finishVoiceTask(session);
4513            } finally {
4514                Binder.restoreCallingIdentity(origId);
4515            }
4516        }
4517
4518    }
4519
4520    @Override
4521    public boolean releaseActivityInstance(IBinder token) {
4522        synchronized(this) {
4523            final long origId = Binder.clearCallingIdentity();
4524            try {
4525                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4526                if (r == null) {
4527                    return false;
4528                }
4529                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4530            } finally {
4531                Binder.restoreCallingIdentity(origId);
4532            }
4533        }
4534    }
4535
4536    @Override
4537    public void releaseSomeActivities(IApplicationThread appInt) {
4538        synchronized(this) {
4539            final long origId = Binder.clearCallingIdentity();
4540            try {
4541                ProcessRecord app = getRecordForAppLocked(appInt);
4542                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4543            } finally {
4544                Binder.restoreCallingIdentity(origId);
4545            }
4546        }
4547    }
4548
4549    @Override
4550    public boolean willActivityBeVisible(IBinder token) {
4551        synchronized(this) {
4552            ActivityStack stack = ActivityRecord.getStackLocked(token);
4553            if (stack != null) {
4554                return stack.willActivityBeVisibleLocked(token);
4555            }
4556            return false;
4557        }
4558    }
4559
4560    @Override
4561    public void overridePendingTransition(IBinder token, String packageName,
4562            int enterAnim, int exitAnim) {
4563        synchronized(this) {
4564            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4565            if (self == null) {
4566                return;
4567            }
4568
4569            final long origId = Binder.clearCallingIdentity();
4570
4571            if (self.state == ActivityState.RESUMED
4572                    || self.state == ActivityState.PAUSING) {
4573                mWindowManager.overridePendingAppTransition(packageName,
4574                        enterAnim, exitAnim, null);
4575            }
4576
4577            Binder.restoreCallingIdentity(origId);
4578        }
4579    }
4580
4581    /**
4582     * Main function for removing an existing process from the activity manager
4583     * as a result of that process going away.  Clears out all connections
4584     * to the process.
4585     */
4586    private final void handleAppDiedLocked(ProcessRecord app,
4587            boolean restarting, boolean allowRestart) {
4588        int pid = app.pid;
4589        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4590        if (!kept && !restarting) {
4591            removeLruProcessLocked(app);
4592            if (pid > 0) {
4593                ProcessList.remove(pid);
4594            }
4595        }
4596
4597        if (mProfileProc == app) {
4598            clearProfilerLocked();
4599        }
4600
4601        // Remove this application's activities from active lists.
4602        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4603
4604        app.activities.clear();
4605
4606        if (app.instrumentationClass != null) {
4607            Slog.w(TAG, "Crash of app " + app.processName
4608                  + " running instrumentation " + app.instrumentationClass);
4609            Bundle info = new Bundle();
4610            info.putString("shortMsg", "Process crashed.");
4611            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4612        }
4613
4614        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4615            // If there was nothing to resume, and we are not already
4616            // restarting this process, but there is a visible activity that
4617            // is hosted by the process...  then make sure all visible
4618            // activities are running, taking care of restarting this
4619            // process.
4620            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4621        }
4622    }
4623
4624    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4625        IBinder threadBinder = thread.asBinder();
4626        // Find the application record.
4627        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4628            ProcessRecord rec = mLruProcesses.get(i);
4629            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4630                return i;
4631            }
4632        }
4633        return -1;
4634    }
4635
4636    final ProcessRecord getRecordForAppLocked(
4637            IApplicationThread thread) {
4638        if (thread == null) {
4639            return null;
4640        }
4641
4642        int appIndex = getLRURecordIndexForAppLocked(thread);
4643        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4644    }
4645
4646    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4647        // If there are no longer any background processes running,
4648        // and the app that died was not running instrumentation,
4649        // then tell everyone we are now low on memory.
4650        boolean haveBg = false;
4651        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4652            ProcessRecord rec = mLruProcesses.get(i);
4653            if (rec.thread != null
4654                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4655                haveBg = true;
4656                break;
4657            }
4658        }
4659
4660        if (!haveBg) {
4661            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4662            if (doReport) {
4663                long now = SystemClock.uptimeMillis();
4664                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4665                    doReport = false;
4666                } else {
4667                    mLastMemUsageReportTime = now;
4668                }
4669            }
4670            final ArrayList<ProcessMemInfo> memInfos
4671                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4672            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4673            long now = SystemClock.uptimeMillis();
4674            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4675                ProcessRecord rec = mLruProcesses.get(i);
4676                if (rec == dyingProc || rec.thread == null) {
4677                    continue;
4678                }
4679                if (doReport) {
4680                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4681                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4682                }
4683                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4684                    // The low memory report is overriding any current
4685                    // state for a GC request.  Make sure to do
4686                    // heavy/important/visible/foreground processes first.
4687                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4688                        rec.lastRequestedGc = 0;
4689                    } else {
4690                        rec.lastRequestedGc = rec.lastLowMemory;
4691                    }
4692                    rec.reportLowMemory = true;
4693                    rec.lastLowMemory = now;
4694                    mProcessesToGc.remove(rec);
4695                    addProcessToGcListLocked(rec);
4696                }
4697            }
4698            if (doReport) {
4699                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4700                mHandler.sendMessage(msg);
4701            }
4702            scheduleAppGcsLocked();
4703        }
4704    }
4705
4706    final void appDiedLocked(ProcessRecord app) {
4707       appDiedLocked(app, app.pid, app.thread, false);
4708    }
4709
4710    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4711            boolean fromBinderDied) {
4712        // First check if this ProcessRecord is actually active for the pid.
4713        synchronized (mPidsSelfLocked) {
4714            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4715            if (curProc != app) {
4716                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4717                return;
4718            }
4719        }
4720
4721        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4722        synchronized (stats) {
4723            stats.noteProcessDiedLocked(app.info.uid, pid);
4724        }
4725
4726        if (!app.killed) {
4727            if (!fromBinderDied) {
4728                Process.killProcessQuiet(pid);
4729            }
4730            killProcessGroup(app.info.uid, pid);
4731            app.killed = true;
4732        }
4733
4734        // Clean up already done if the process has been re-started.
4735        if (app.pid == pid && app.thread != null &&
4736                app.thread.asBinder() == thread.asBinder()) {
4737            boolean doLowMem = app.instrumentationClass == null;
4738            boolean doOomAdj = doLowMem;
4739            if (!app.killedByAm) {
4740                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4741                        + ") has died");
4742                mAllowLowerMemLevel = true;
4743            } else {
4744                // Note that we always want to do oom adj to update our state with the
4745                // new number of procs.
4746                mAllowLowerMemLevel = false;
4747                doLowMem = false;
4748            }
4749            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4750            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4751                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4752            handleAppDiedLocked(app, false, true);
4753
4754            if (doOomAdj) {
4755                updateOomAdjLocked();
4756            }
4757            if (doLowMem) {
4758                doLowMemReportIfNeededLocked(app);
4759            }
4760        } else if (app.pid != pid) {
4761            // A new process has already been started.
4762            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4763                    + ") has died and restarted (pid " + app.pid + ").");
4764            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4765        } else if (DEBUG_PROCESSES) {
4766            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4767                    + thread.asBinder());
4768        }
4769    }
4770
4771    /**
4772     * If a stack trace dump file is configured, dump process stack traces.
4773     * @param clearTraces causes the dump file to be erased prior to the new
4774     *    traces being written, if true; when false, the new traces will be
4775     *    appended to any existing file content.
4776     * @param firstPids of dalvik VM processes to dump stack traces for first
4777     * @param lastPids of dalvik VM processes to dump stack traces for last
4778     * @param nativeProcs optional list of native process names to dump stack crawls
4779     * @return file containing stack traces, or null if no dump file is configured
4780     */
4781    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4782            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4783        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4784        if (tracesPath == null || tracesPath.length() == 0) {
4785            return null;
4786        }
4787
4788        File tracesFile = new File(tracesPath);
4789        try {
4790            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4791            tracesFile.createNewFile();
4792            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4793        } catch (IOException e) {
4794            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4795            return null;
4796        }
4797
4798        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4799        return tracesFile;
4800    }
4801
4802    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4803            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4804        // Use a FileObserver to detect when traces finish writing.
4805        // The order of traces is considered important to maintain for legibility.
4806        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4807            @Override
4808            public synchronized void onEvent(int event, String path) { notify(); }
4809        };
4810
4811        try {
4812            observer.startWatching();
4813
4814            // First collect all of the stacks of the most important pids.
4815            if (firstPids != null) {
4816                try {
4817                    int num = firstPids.size();
4818                    for (int i = 0; i < num; i++) {
4819                        synchronized (observer) {
4820                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4821                            observer.wait(200);  // Wait for write-close, give up after 200msec
4822                        }
4823                    }
4824                } catch (InterruptedException e) {
4825                    Slog.wtf(TAG, e);
4826                }
4827            }
4828
4829            // Next collect the stacks of the native pids
4830            if (nativeProcs != null) {
4831                int[] pids = Process.getPidsForCommands(nativeProcs);
4832                if (pids != null) {
4833                    for (int pid : pids) {
4834                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4835                    }
4836                }
4837            }
4838
4839            // Lastly, measure CPU usage.
4840            if (processCpuTracker != null) {
4841                processCpuTracker.init();
4842                System.gc();
4843                processCpuTracker.update();
4844                try {
4845                    synchronized (processCpuTracker) {
4846                        processCpuTracker.wait(500); // measure over 1/2 second.
4847                    }
4848                } catch (InterruptedException e) {
4849                }
4850                processCpuTracker.update();
4851
4852                // We'll take the stack crawls of just the top apps using CPU.
4853                final int N = processCpuTracker.countWorkingStats();
4854                int numProcs = 0;
4855                for (int i=0; i<N && numProcs<5; i++) {
4856                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4857                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4858                        numProcs++;
4859                        try {
4860                            synchronized (observer) {
4861                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4862                                observer.wait(200);  // Wait for write-close, give up after 200msec
4863                            }
4864                        } catch (InterruptedException e) {
4865                            Slog.wtf(TAG, e);
4866                        }
4867
4868                    }
4869                }
4870            }
4871        } finally {
4872            observer.stopWatching();
4873        }
4874    }
4875
4876    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4877        if (true || IS_USER_BUILD) {
4878            return;
4879        }
4880        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4881        if (tracesPath == null || tracesPath.length() == 0) {
4882            return;
4883        }
4884
4885        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4886        StrictMode.allowThreadDiskWrites();
4887        try {
4888            final File tracesFile = new File(tracesPath);
4889            final File tracesDir = tracesFile.getParentFile();
4890            final File tracesTmp = new File(tracesDir, "__tmp__");
4891            try {
4892                if (tracesFile.exists()) {
4893                    tracesTmp.delete();
4894                    tracesFile.renameTo(tracesTmp);
4895                }
4896                StringBuilder sb = new StringBuilder();
4897                Time tobj = new Time();
4898                tobj.set(System.currentTimeMillis());
4899                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4900                sb.append(": ");
4901                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4902                sb.append(" since ");
4903                sb.append(msg);
4904                FileOutputStream fos = new FileOutputStream(tracesFile);
4905                fos.write(sb.toString().getBytes());
4906                if (app == null) {
4907                    fos.write("\n*** No application process!".getBytes());
4908                }
4909                fos.close();
4910                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4911            } catch (IOException e) {
4912                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4913                return;
4914            }
4915
4916            if (app != null) {
4917                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4918                firstPids.add(app.pid);
4919                dumpStackTraces(tracesPath, firstPids, null, null, null);
4920            }
4921
4922            File lastTracesFile = null;
4923            File curTracesFile = null;
4924            for (int i=9; i>=0; i--) {
4925                String name = String.format(Locale.US, "slow%02d.txt", i);
4926                curTracesFile = new File(tracesDir, name);
4927                if (curTracesFile.exists()) {
4928                    if (lastTracesFile != null) {
4929                        curTracesFile.renameTo(lastTracesFile);
4930                    } else {
4931                        curTracesFile.delete();
4932                    }
4933                }
4934                lastTracesFile = curTracesFile;
4935            }
4936            tracesFile.renameTo(curTracesFile);
4937            if (tracesTmp.exists()) {
4938                tracesTmp.renameTo(tracesFile);
4939            }
4940        } finally {
4941            StrictMode.setThreadPolicy(oldPolicy);
4942        }
4943    }
4944
4945    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4946            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4947        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4948        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4949
4950        if (mController != null) {
4951            try {
4952                // 0 == continue, -1 = kill process immediately
4953                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4954                if (res < 0 && app.pid != MY_PID) {
4955                    app.kill("anr", true);
4956                }
4957            } catch (RemoteException e) {
4958                mController = null;
4959                Watchdog.getInstance().setActivityController(null);
4960            }
4961        }
4962
4963        long anrTime = SystemClock.uptimeMillis();
4964        if (MONITOR_CPU_USAGE) {
4965            updateCpuStatsNow();
4966        }
4967
4968        synchronized (this) {
4969            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4970            if (mShuttingDown) {
4971                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4972                return;
4973            } else if (app.notResponding) {
4974                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4975                return;
4976            } else if (app.crashing) {
4977                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4978                return;
4979            }
4980
4981            // In case we come through here for the same app before completing
4982            // this one, mark as anring now so we will bail out.
4983            app.notResponding = true;
4984
4985            // Log the ANR to the event log.
4986            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4987                    app.processName, app.info.flags, annotation);
4988
4989            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4990            firstPids.add(app.pid);
4991
4992            int parentPid = app.pid;
4993            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4994            if (parentPid != app.pid) firstPids.add(parentPid);
4995
4996            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4997
4998            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4999                ProcessRecord r = mLruProcesses.get(i);
5000                if (r != null && r.thread != null) {
5001                    int pid = r.pid;
5002                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5003                        if (r.persistent) {
5004                            firstPids.add(pid);
5005                        } else {
5006                            lastPids.put(pid, Boolean.TRUE);
5007                        }
5008                    }
5009                }
5010            }
5011        }
5012
5013        // Log the ANR to the main log.
5014        StringBuilder info = new StringBuilder();
5015        info.setLength(0);
5016        info.append("ANR in ").append(app.processName);
5017        if (activity != null && activity.shortComponentName != null) {
5018            info.append(" (").append(activity.shortComponentName).append(")");
5019        }
5020        info.append("\n");
5021        info.append("PID: ").append(app.pid).append("\n");
5022        if (annotation != null) {
5023            info.append("Reason: ").append(annotation).append("\n");
5024        }
5025        if (parent != null && parent != activity) {
5026            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5027        }
5028
5029        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5030
5031        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5032                NATIVE_STACKS_OF_INTEREST);
5033
5034        String cpuInfo = null;
5035        if (MONITOR_CPU_USAGE) {
5036            updateCpuStatsNow();
5037            synchronized (mProcessCpuTracker) {
5038                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5039            }
5040            info.append(processCpuTracker.printCurrentLoad());
5041            info.append(cpuInfo);
5042        }
5043
5044        info.append(processCpuTracker.printCurrentState(anrTime));
5045
5046        Slog.e(TAG, info.toString());
5047        if (tracesFile == null) {
5048            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5049            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5050        }
5051
5052        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5053                cpuInfo, tracesFile, null);
5054
5055        if (mController != null) {
5056            try {
5057                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5058                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5059                if (res != 0) {
5060                    if (res < 0 && app.pid != MY_PID) {
5061                        app.kill("anr", true);
5062                    } else {
5063                        synchronized (this) {
5064                            mServices.scheduleServiceTimeoutLocked(app);
5065                        }
5066                    }
5067                    return;
5068                }
5069            } catch (RemoteException e) {
5070                mController = null;
5071                Watchdog.getInstance().setActivityController(null);
5072            }
5073        }
5074
5075        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5076        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5077                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5078
5079        synchronized (this) {
5080            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5081
5082            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5083                app.kill("bg anr", true);
5084                return;
5085            }
5086
5087            // Set the app's notResponding state, and look up the errorReportReceiver
5088            makeAppNotRespondingLocked(app,
5089                    activity != null ? activity.shortComponentName : null,
5090                    annotation != null ? "ANR " + annotation : "ANR",
5091                    info.toString());
5092
5093            // Bring up the infamous App Not Responding dialog
5094            Message msg = Message.obtain();
5095            HashMap<String, Object> map = new HashMap<String, Object>();
5096            msg.what = SHOW_NOT_RESPONDING_MSG;
5097            msg.obj = map;
5098            msg.arg1 = aboveSystem ? 1 : 0;
5099            map.put("app", app);
5100            if (activity != null) {
5101                map.put("activity", activity);
5102            }
5103
5104            mUiHandler.sendMessage(msg);
5105        }
5106    }
5107
5108    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5109        if (!mLaunchWarningShown) {
5110            mLaunchWarningShown = true;
5111            mUiHandler.post(new Runnable() {
5112                @Override
5113                public void run() {
5114                    synchronized (ActivityManagerService.this) {
5115                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5116                        d.show();
5117                        mUiHandler.postDelayed(new Runnable() {
5118                            @Override
5119                            public void run() {
5120                                synchronized (ActivityManagerService.this) {
5121                                    d.dismiss();
5122                                    mLaunchWarningShown = false;
5123                                }
5124                            }
5125                        }, 4000);
5126                    }
5127                }
5128            });
5129        }
5130    }
5131
5132    @Override
5133    public boolean clearApplicationUserData(final String packageName,
5134            final IPackageDataObserver observer, int userId) {
5135        enforceNotIsolatedCaller("clearApplicationUserData");
5136        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5137            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5138        }
5139        int uid = Binder.getCallingUid();
5140        int pid = Binder.getCallingPid();
5141        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5142                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5143        long callingId = Binder.clearCallingIdentity();
5144        try {
5145            IPackageManager pm = AppGlobals.getPackageManager();
5146            int pkgUid = -1;
5147            synchronized(this) {
5148                try {
5149                    pkgUid = pm.getPackageUid(packageName, userId);
5150                } catch (RemoteException e) {
5151                }
5152                if (pkgUid == -1) {
5153                    Slog.w(TAG, "Invalid packageName: " + packageName);
5154                    if (observer != null) {
5155                        try {
5156                            observer.onRemoveCompleted(packageName, false);
5157                        } catch (RemoteException e) {
5158                            Slog.i(TAG, "Observer no longer exists.");
5159                        }
5160                    }
5161                    return false;
5162                }
5163                if (uid == pkgUid || checkComponentPermission(
5164                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5165                        pid, uid, -1, true)
5166                        == PackageManager.PERMISSION_GRANTED) {
5167                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5168                } else {
5169                    throw new SecurityException("PID " + pid + " does not have permission "
5170                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5171                                    + " of package " + packageName);
5172                }
5173
5174                // Remove all tasks match the cleared application package and user
5175                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5176                    final TaskRecord tr = mRecentTasks.get(i);
5177                    final String taskPackageName =
5178                            tr.getBaseIntent().getComponent().getPackageName();
5179                    if (tr.userId != userId) continue;
5180                    if (!taskPackageName.equals(packageName)) continue;
5181                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5182                }
5183            }
5184
5185            try {
5186                // Clear application user data
5187                pm.clearApplicationUserData(packageName, observer, userId);
5188
5189                synchronized(this) {
5190                    // Remove all permissions granted from/to this package
5191                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5192                }
5193
5194                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5195                        Uri.fromParts("package", packageName, null));
5196                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5197                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5198                        null, null, 0, null, null, null, null, false, false, userId);
5199            } catch (RemoteException e) {
5200            }
5201        } finally {
5202            Binder.restoreCallingIdentity(callingId);
5203        }
5204        return true;
5205    }
5206
5207    @Override
5208    public void killBackgroundProcesses(final String packageName, int userId) {
5209        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5210                != PackageManager.PERMISSION_GRANTED &&
5211                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5212                        != PackageManager.PERMISSION_GRANTED) {
5213            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5214                    + Binder.getCallingPid()
5215                    + ", uid=" + Binder.getCallingUid()
5216                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5217            Slog.w(TAG, msg);
5218            throw new SecurityException(msg);
5219        }
5220
5221        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5222                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5223        long callingId = Binder.clearCallingIdentity();
5224        try {
5225            IPackageManager pm = AppGlobals.getPackageManager();
5226            synchronized(this) {
5227                int appId = -1;
5228                try {
5229                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5230                } catch (RemoteException e) {
5231                }
5232                if (appId == -1) {
5233                    Slog.w(TAG, "Invalid packageName: " + packageName);
5234                    return;
5235                }
5236                killPackageProcessesLocked(packageName, appId, userId,
5237                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5238            }
5239        } finally {
5240            Binder.restoreCallingIdentity(callingId);
5241        }
5242    }
5243
5244    @Override
5245    public void killAllBackgroundProcesses() {
5246        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5247                != PackageManager.PERMISSION_GRANTED) {
5248            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5249                    + Binder.getCallingPid()
5250                    + ", uid=" + Binder.getCallingUid()
5251                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5252            Slog.w(TAG, msg);
5253            throw new SecurityException(msg);
5254        }
5255
5256        long callingId = Binder.clearCallingIdentity();
5257        try {
5258            synchronized(this) {
5259                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5260                final int NP = mProcessNames.getMap().size();
5261                for (int ip=0; ip<NP; ip++) {
5262                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5263                    final int NA = apps.size();
5264                    for (int ia=0; ia<NA; ia++) {
5265                        ProcessRecord app = apps.valueAt(ia);
5266                        if (app.persistent) {
5267                            // we don't kill persistent processes
5268                            continue;
5269                        }
5270                        if (app.removed) {
5271                            procs.add(app);
5272                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5273                            app.removed = true;
5274                            procs.add(app);
5275                        }
5276                    }
5277                }
5278
5279                int N = procs.size();
5280                for (int i=0; i<N; i++) {
5281                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5282                }
5283                mAllowLowerMemLevel = true;
5284                updateOomAdjLocked();
5285                doLowMemReportIfNeededLocked(null);
5286            }
5287        } finally {
5288            Binder.restoreCallingIdentity(callingId);
5289        }
5290    }
5291
5292    @Override
5293    public void forceStopPackage(final String packageName, int userId) {
5294        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5295                != PackageManager.PERMISSION_GRANTED) {
5296            String msg = "Permission Denial: forceStopPackage() from pid="
5297                    + Binder.getCallingPid()
5298                    + ", uid=" + Binder.getCallingUid()
5299                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5300            Slog.w(TAG, msg);
5301            throw new SecurityException(msg);
5302        }
5303        final int callingPid = Binder.getCallingPid();
5304        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5305                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5306        long callingId = Binder.clearCallingIdentity();
5307        try {
5308            IPackageManager pm = AppGlobals.getPackageManager();
5309            synchronized(this) {
5310                int[] users = userId == UserHandle.USER_ALL
5311                        ? mUserController.getUsers() : new int[] { userId };
5312                for (int user : users) {
5313                    int pkgUid = -1;
5314                    try {
5315                        pkgUid = pm.getPackageUid(packageName, user);
5316                    } catch (RemoteException e) {
5317                    }
5318                    if (pkgUid == -1) {
5319                        Slog.w(TAG, "Invalid packageName: " + packageName);
5320                        continue;
5321                    }
5322                    try {
5323                        pm.setPackageStoppedState(packageName, true, user);
5324                    } catch (RemoteException e) {
5325                    } catch (IllegalArgumentException e) {
5326                        Slog.w(TAG, "Failed trying to unstop package "
5327                                + packageName + ": " + e);
5328                    }
5329                    if (mUserController.isUserRunningLocked(user, false)) {
5330                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5331                    }
5332                }
5333            }
5334        } finally {
5335            Binder.restoreCallingIdentity(callingId);
5336        }
5337    }
5338
5339    @Override
5340    public void addPackageDependency(String packageName) {
5341        synchronized (this) {
5342            int callingPid = Binder.getCallingPid();
5343            if (callingPid == Process.myPid()) {
5344                //  Yeah, um, no.
5345                return;
5346            }
5347            ProcessRecord proc;
5348            synchronized (mPidsSelfLocked) {
5349                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5350            }
5351            if (proc != null) {
5352                if (proc.pkgDeps == null) {
5353                    proc.pkgDeps = new ArraySet<String>(1);
5354                }
5355                proc.pkgDeps.add(packageName);
5356            }
5357        }
5358    }
5359
5360    /*
5361     * The pkg name and app id have to be specified.
5362     */
5363    @Override
5364    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5365        if (pkg == null) {
5366            return;
5367        }
5368        // Make sure the uid is valid.
5369        if (appid < 0) {
5370            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5371            return;
5372        }
5373        int callerUid = Binder.getCallingUid();
5374        // Only the system server can kill an application
5375        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5376            // Post an aysnc message to kill the application
5377            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5378            msg.arg1 = appid;
5379            msg.arg2 = 0;
5380            Bundle bundle = new Bundle();
5381            bundle.putString("pkg", pkg);
5382            bundle.putString("reason", reason);
5383            msg.obj = bundle;
5384            mHandler.sendMessage(msg);
5385        } else {
5386            throw new SecurityException(callerUid + " cannot kill pkg: " +
5387                    pkg);
5388        }
5389    }
5390
5391    @Override
5392    public void closeSystemDialogs(String reason) {
5393        enforceNotIsolatedCaller("closeSystemDialogs");
5394
5395        final int pid = Binder.getCallingPid();
5396        final int uid = Binder.getCallingUid();
5397        final long origId = Binder.clearCallingIdentity();
5398        try {
5399            synchronized (this) {
5400                // Only allow this from foreground processes, so that background
5401                // applications can't abuse it to prevent system UI from being shown.
5402                if (uid >= Process.FIRST_APPLICATION_UID) {
5403                    ProcessRecord proc;
5404                    synchronized (mPidsSelfLocked) {
5405                        proc = mPidsSelfLocked.get(pid);
5406                    }
5407                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5408                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5409                                + " from background process " + proc);
5410                        return;
5411                    }
5412                }
5413                closeSystemDialogsLocked(reason);
5414            }
5415        } finally {
5416            Binder.restoreCallingIdentity(origId);
5417        }
5418    }
5419
5420    void closeSystemDialogsLocked(String reason) {
5421        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5422        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5423                | Intent.FLAG_RECEIVER_FOREGROUND);
5424        if (reason != null) {
5425            intent.putExtra("reason", reason);
5426        }
5427        mWindowManager.closeSystemDialogs(reason);
5428
5429        mStackSupervisor.closeSystemDialogsLocked();
5430
5431        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5432                AppOpsManager.OP_NONE, null, false, false,
5433                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5434    }
5435
5436    @Override
5437    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5438        enforceNotIsolatedCaller("getProcessMemoryInfo");
5439        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5440        for (int i=pids.length-1; i>=0; i--) {
5441            ProcessRecord proc;
5442            int oomAdj;
5443            synchronized (this) {
5444                synchronized (mPidsSelfLocked) {
5445                    proc = mPidsSelfLocked.get(pids[i]);
5446                    oomAdj = proc != null ? proc.setAdj : 0;
5447                }
5448            }
5449            infos[i] = new Debug.MemoryInfo();
5450            Debug.getMemoryInfo(pids[i], infos[i]);
5451            if (proc != null) {
5452                synchronized (this) {
5453                    if (proc.thread != null && proc.setAdj == oomAdj) {
5454                        // Record this for posterity if the process has been stable.
5455                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5456                                infos[i].getTotalUss(), false, proc.pkgList);
5457                    }
5458                }
5459            }
5460        }
5461        return infos;
5462    }
5463
5464    @Override
5465    public long[] getProcessPss(int[] pids) {
5466        enforceNotIsolatedCaller("getProcessPss");
5467        long[] pss = new long[pids.length];
5468        for (int i=pids.length-1; i>=0; i--) {
5469            ProcessRecord proc;
5470            int oomAdj;
5471            synchronized (this) {
5472                synchronized (mPidsSelfLocked) {
5473                    proc = mPidsSelfLocked.get(pids[i]);
5474                    oomAdj = proc != null ? proc.setAdj : 0;
5475                }
5476            }
5477            long[] tmpUss = new long[1];
5478            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5479            if (proc != null) {
5480                synchronized (this) {
5481                    if (proc.thread != null && proc.setAdj == oomAdj) {
5482                        // Record this for posterity if the process has been stable.
5483                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5484                    }
5485                }
5486            }
5487        }
5488        return pss;
5489    }
5490
5491    @Override
5492    public void killApplicationProcess(String processName, int uid) {
5493        if (processName == null) {
5494            return;
5495        }
5496
5497        int callerUid = Binder.getCallingUid();
5498        // Only the system server can kill an application
5499        if (callerUid == Process.SYSTEM_UID) {
5500            synchronized (this) {
5501                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5502                if (app != null && app.thread != null) {
5503                    try {
5504                        app.thread.scheduleSuicide();
5505                    } catch (RemoteException e) {
5506                        // If the other end already died, then our work here is done.
5507                    }
5508                } else {
5509                    Slog.w(TAG, "Process/uid not found attempting kill of "
5510                            + processName + " / " + uid);
5511                }
5512            }
5513        } else {
5514            throw new SecurityException(callerUid + " cannot kill app process: " +
5515                    processName);
5516        }
5517    }
5518
5519    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5520        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5521                false, true, false, false, UserHandle.getUserId(uid), reason);
5522        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5523                Uri.fromParts("package", packageName, null));
5524        if (!mProcessesReady) {
5525            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5526                    | Intent.FLAG_RECEIVER_FOREGROUND);
5527        }
5528        intent.putExtra(Intent.EXTRA_UID, uid);
5529        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5530        broadcastIntentLocked(null, null, intent,
5531                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5532                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5533    }
5534
5535
5536    private final boolean killPackageProcessesLocked(String packageName, int appId,
5537            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5538            boolean doit, boolean evenPersistent, String reason) {
5539        ArrayList<ProcessRecord> procs = new ArrayList<>();
5540
5541        // Remove all processes this package may have touched: all with the
5542        // same UID (except for the system or root user), and all whose name
5543        // matches the package name.
5544        final int NP = mProcessNames.getMap().size();
5545        for (int ip=0; ip<NP; ip++) {
5546            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5547            final int NA = apps.size();
5548            for (int ia=0; ia<NA; ia++) {
5549                ProcessRecord app = apps.valueAt(ia);
5550                if (app.persistent && !evenPersistent) {
5551                    // we don't kill persistent processes
5552                    continue;
5553                }
5554                if (app.removed) {
5555                    if (doit) {
5556                        procs.add(app);
5557                    }
5558                    continue;
5559                }
5560
5561                // Skip process if it doesn't meet our oom adj requirement.
5562                if (app.setAdj < minOomAdj) {
5563                    continue;
5564                }
5565
5566                // If no package is specified, we call all processes under the
5567                // give user id.
5568                if (packageName == null) {
5569                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5570                        continue;
5571                    }
5572                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5573                        continue;
5574                    }
5575                // Package has been specified, we want to hit all processes
5576                // that match it.  We need to qualify this by the processes
5577                // that are running under the specified app and user ID.
5578                } else {
5579                    final boolean isDep = app.pkgDeps != null
5580                            && app.pkgDeps.contains(packageName);
5581                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5582                        continue;
5583                    }
5584                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5585                        continue;
5586                    }
5587                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5588                        continue;
5589                    }
5590                }
5591
5592                // Process has passed all conditions, kill it!
5593                if (!doit) {
5594                    return true;
5595                }
5596                app.removed = true;
5597                procs.add(app);
5598            }
5599        }
5600
5601        int N = procs.size();
5602        for (int i=0; i<N; i++) {
5603            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5604        }
5605        updateOomAdjLocked();
5606        return N > 0;
5607    }
5608
5609    private void cleanupDisabledPackageComponentsLocked(
5610            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5611
5612        Set<String> disabledClasses = null;
5613        boolean packageDisabled = false;
5614        IPackageManager pm = AppGlobals.getPackageManager();
5615
5616        if (changedClasses == null) {
5617            // Nothing changed...
5618            return;
5619        }
5620
5621        // Determine enable/disable state of the package and its components.
5622        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5623        for (int i = changedClasses.length - 1; i >= 0; i--) {
5624            final String changedClass = changedClasses[i];
5625
5626            if (changedClass.equals(packageName)) {
5627                try {
5628                    // Entire package setting changed
5629                    enabled = pm.getApplicationEnabledSetting(packageName,
5630                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5631                } catch (Exception e) {
5632                    // No such package/component; probably racing with uninstall.  In any
5633                    // event it means we have nothing further to do here.
5634                    return;
5635                }
5636                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5637                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5638                if (packageDisabled) {
5639                    // Entire package is disabled.
5640                    // No need to continue to check component states.
5641                    disabledClasses = null;
5642                    break;
5643                }
5644            } else {
5645                try {
5646                    enabled = pm.getComponentEnabledSetting(
5647                            new ComponentName(packageName, changedClass),
5648                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5649                } catch (Exception e) {
5650                    // As above, probably racing with uninstall.
5651                    return;
5652                }
5653                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5654                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5655                    if (disabledClasses == null) {
5656                        disabledClasses = new ArraySet<>(changedClasses.length);
5657                    }
5658                    disabledClasses.add(changedClass);
5659                }
5660            }
5661        }
5662
5663        if (!packageDisabled && disabledClasses == null) {
5664            // Nothing to do here...
5665            return;
5666        }
5667
5668        // Clean-up disabled activities.
5669        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5670                packageName, disabledClasses, true, false, userId) && mBooted) {
5671            mStackSupervisor.resumeTopActivitiesLocked();
5672            mStackSupervisor.scheduleIdleLocked();
5673        }
5674
5675        // Clean-up disabled tasks
5676        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5677
5678        // Clean-up disabled services.
5679        mServices.bringDownDisabledPackageServicesLocked(
5680                packageName, disabledClasses, userId, false, killProcess, true);
5681
5682        // Clean-up disabled providers.
5683        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5684        mProviderMap.collectPackageProvidersLocked(
5685                packageName, disabledClasses, true, false, userId, providers);
5686        for (int i = providers.size() - 1; i >= 0; i--) {
5687            removeDyingProviderLocked(null, providers.get(i), true);
5688        }
5689
5690        // Clean-up disabled broadcast receivers.
5691        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5692            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5693                    packageName, disabledClasses, userId, true);
5694        }
5695
5696    }
5697
5698    final boolean forceStopPackageLocked(String packageName, int appId,
5699            boolean callerWillRestart, boolean purgeCache, boolean doit,
5700            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5701        int i;
5702
5703        if (userId == UserHandle.USER_ALL && packageName == null) {
5704            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5705        }
5706
5707        if (appId < 0 && packageName != null) {
5708            try {
5709                appId = UserHandle.getAppId(
5710                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5711            } catch (RemoteException e) {
5712            }
5713        }
5714
5715        if (doit) {
5716            if (packageName != null) {
5717                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5718                        + " user=" + userId + ": " + reason);
5719            } else {
5720                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5721            }
5722
5723            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5724            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5725                SparseArray<Long> ba = pmap.valueAt(ip);
5726                for (i = ba.size() - 1; i >= 0; i--) {
5727                    boolean remove = false;
5728                    final int entUid = ba.keyAt(i);
5729                    if (packageName != null) {
5730                        if (userId == UserHandle.USER_ALL) {
5731                            if (UserHandle.getAppId(entUid) == appId) {
5732                                remove = true;
5733                            }
5734                        } else {
5735                            if (entUid == UserHandle.getUid(userId, appId)) {
5736                                remove = true;
5737                            }
5738                        }
5739                    } else if (UserHandle.getUserId(entUid) == userId) {
5740                        remove = true;
5741                    }
5742                    if (remove) {
5743                        ba.removeAt(i);
5744                    }
5745                }
5746                if (ba.size() == 0) {
5747                    pmap.removeAt(ip);
5748                }
5749            }
5750        }
5751
5752        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5753                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5754                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5755
5756        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5757                packageName, null, doit, evenPersistent, userId)) {
5758            if (!doit) {
5759                return true;
5760            }
5761            didSomething = true;
5762        }
5763
5764        if (mServices.bringDownDisabledPackageServicesLocked(
5765                packageName, null, userId, evenPersistent, true, doit)) {
5766            if (!doit) {
5767                return true;
5768            }
5769            didSomething = true;
5770        }
5771
5772        if (packageName == null) {
5773            // Remove all sticky broadcasts from this user.
5774            mStickyBroadcasts.remove(userId);
5775        }
5776
5777        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5778        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5779                userId, providers)) {
5780            if (!doit) {
5781                return true;
5782            }
5783            didSomething = true;
5784        }
5785        for (i = providers.size() - 1; i >= 0; i--) {
5786            removeDyingProviderLocked(null, providers.get(i), true);
5787        }
5788
5789        // Remove transient permissions granted from/to this package/user
5790        removeUriPermissionsForPackageLocked(packageName, userId, false);
5791
5792        if (doit) {
5793            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5794                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5795                        packageName, null, userId, doit);
5796            }
5797        }
5798
5799        if (packageName == null || uninstalling) {
5800            // Remove pending intents.  For now we only do this when force
5801            // stopping users, because we have some problems when doing this
5802            // for packages -- app widgets are not currently cleaned up for
5803            // such packages, so they can be left with bad pending intents.
5804            if (mIntentSenderRecords.size() > 0) {
5805                Iterator<WeakReference<PendingIntentRecord>> it
5806                        = mIntentSenderRecords.values().iterator();
5807                while (it.hasNext()) {
5808                    WeakReference<PendingIntentRecord> wpir = it.next();
5809                    if (wpir == null) {
5810                        it.remove();
5811                        continue;
5812                    }
5813                    PendingIntentRecord pir = wpir.get();
5814                    if (pir == null) {
5815                        it.remove();
5816                        continue;
5817                    }
5818                    if (packageName == null) {
5819                        // Stopping user, remove all objects for the user.
5820                        if (pir.key.userId != userId) {
5821                            // Not the same user, skip it.
5822                            continue;
5823                        }
5824                    } else {
5825                        if (UserHandle.getAppId(pir.uid) != appId) {
5826                            // Different app id, skip it.
5827                            continue;
5828                        }
5829                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5830                            // Different user, skip it.
5831                            continue;
5832                        }
5833                        if (!pir.key.packageName.equals(packageName)) {
5834                            // Different package, skip it.
5835                            continue;
5836                        }
5837                    }
5838                    if (!doit) {
5839                        return true;
5840                    }
5841                    didSomething = true;
5842                    it.remove();
5843                    pir.canceled = true;
5844                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5845                        pir.key.activity.pendingResults.remove(pir.ref);
5846                    }
5847                }
5848            }
5849        }
5850
5851        if (doit) {
5852            if (purgeCache && packageName != null) {
5853                AttributeCache ac = AttributeCache.instance();
5854                if (ac != null) {
5855                    ac.removePackage(packageName);
5856                }
5857            }
5858            if (mBooted) {
5859                mStackSupervisor.resumeTopActivitiesLocked();
5860                mStackSupervisor.scheduleIdleLocked();
5861            }
5862        }
5863
5864        return didSomething;
5865    }
5866
5867    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5868        ProcessRecord old = mProcessNames.remove(name, uid);
5869        if (old != null) {
5870            old.uidRecord.numProcs--;
5871            if (old.uidRecord.numProcs == 0) {
5872                // No more processes using this uid, tell clients it is gone.
5873                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5874                        "No more processes in " + old.uidRecord);
5875                enqueueUidChangeLocked(old.uidRecord, true);
5876                mActiveUids.remove(uid);
5877            }
5878            old.uidRecord = null;
5879        }
5880        mIsolatedProcesses.remove(uid);
5881        return old;
5882    }
5883
5884    private final void addProcessNameLocked(ProcessRecord proc) {
5885        // We shouldn't already have a process under this name, but just in case we
5886        // need to clean up whatever may be there now.
5887        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5888        if (old == proc && proc.persistent) {
5889            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5890            Slog.w(TAG, "Re-adding persistent process " + proc);
5891        } else if (old != null) {
5892            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5893        }
5894        UidRecord uidRec = mActiveUids.get(proc.uid);
5895        if (uidRec == null) {
5896            uidRec = new UidRecord(proc.uid);
5897            // This is the first appearance of the uid, report it now!
5898            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5899                    "Creating new process uid: " + uidRec);
5900            mActiveUids.put(proc.uid, uidRec);
5901            enqueueUidChangeLocked(uidRec, false);
5902        }
5903        proc.uidRecord = uidRec;
5904        uidRec.numProcs++;
5905        mProcessNames.put(proc.processName, proc.uid, proc);
5906        if (proc.isolated) {
5907            mIsolatedProcesses.put(proc.uid, proc);
5908        }
5909    }
5910
5911    private final boolean removeProcessLocked(ProcessRecord app,
5912            boolean callerWillRestart, boolean allowRestart, String reason) {
5913        final String name = app.processName;
5914        final int uid = app.uid;
5915        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5916            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5917
5918        removeProcessNameLocked(name, uid);
5919        if (mHeavyWeightProcess == app) {
5920            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5921                    mHeavyWeightProcess.userId, 0));
5922            mHeavyWeightProcess = null;
5923        }
5924        boolean needRestart = false;
5925        if (app.pid > 0 && app.pid != MY_PID) {
5926            int pid = app.pid;
5927            synchronized (mPidsSelfLocked) {
5928                mPidsSelfLocked.remove(pid);
5929                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5930            }
5931            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5932            if (app.isolated) {
5933                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5934            }
5935            boolean willRestart = false;
5936            if (app.persistent && !app.isolated) {
5937                if (!callerWillRestart) {
5938                    willRestart = true;
5939                } else {
5940                    needRestart = true;
5941                }
5942            }
5943            app.kill(reason, true);
5944            handleAppDiedLocked(app, willRestart, allowRestart);
5945            if (willRestart) {
5946                removeLruProcessLocked(app);
5947                addAppLocked(app.info, false, null /* ABI override */);
5948            }
5949        } else {
5950            mRemovedProcesses.add(app);
5951        }
5952
5953        return needRestart;
5954    }
5955
5956    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5957        cleanupAppInLaunchingProvidersLocked(app, true);
5958        removeProcessLocked(app, false, true, "timeout publishing content providers");
5959    }
5960
5961    private final void processStartTimedOutLocked(ProcessRecord app) {
5962        final int pid = app.pid;
5963        boolean gone = false;
5964        synchronized (mPidsSelfLocked) {
5965            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5966            if (knownApp != null && knownApp.thread == null) {
5967                mPidsSelfLocked.remove(pid);
5968                gone = true;
5969            }
5970        }
5971
5972        if (gone) {
5973            Slog.w(TAG, "Process " + app + " failed to attach");
5974            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5975                    pid, app.uid, app.processName);
5976            removeProcessNameLocked(app.processName, app.uid);
5977            if (mHeavyWeightProcess == app) {
5978                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5979                        mHeavyWeightProcess.userId, 0));
5980                mHeavyWeightProcess = null;
5981            }
5982            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5983            if (app.isolated) {
5984                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5985            }
5986            // Take care of any launching providers waiting for this process.
5987            cleanupAppInLaunchingProvidersLocked(app, true);
5988            // Take care of any services that are waiting for the process.
5989            mServices.processStartTimedOutLocked(app);
5990            app.kill("start timeout", true);
5991            removeLruProcessLocked(app);
5992            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5993                Slog.w(TAG, "Unattached app died before backup, skipping");
5994                try {
5995                    IBackupManager bm = IBackupManager.Stub.asInterface(
5996                            ServiceManager.getService(Context.BACKUP_SERVICE));
5997                    bm.agentDisconnected(app.info.packageName);
5998                } catch (RemoteException e) {
5999                    // Can't happen; the backup manager is local
6000                }
6001            }
6002            if (isPendingBroadcastProcessLocked(pid)) {
6003                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6004                skipPendingBroadcastLocked(pid);
6005            }
6006        } else {
6007            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6008        }
6009    }
6010
6011    private final boolean attachApplicationLocked(IApplicationThread thread,
6012            int pid) {
6013
6014        // Find the application record that is being attached...  either via
6015        // the pid if we are running in multiple processes, or just pull the
6016        // next app record if we are emulating process with anonymous threads.
6017        ProcessRecord app;
6018        if (pid != MY_PID && pid >= 0) {
6019            synchronized (mPidsSelfLocked) {
6020                app = mPidsSelfLocked.get(pid);
6021            }
6022        } else {
6023            app = null;
6024        }
6025
6026        if (app == null) {
6027            Slog.w(TAG, "No pending application record for pid " + pid
6028                    + " (IApplicationThread " + thread + "); dropping process");
6029            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6030            if (pid > 0 && pid != MY_PID) {
6031                Process.killProcessQuiet(pid);
6032                //TODO: killProcessGroup(app.info.uid, pid);
6033            } else {
6034                try {
6035                    thread.scheduleExit();
6036                } catch (Exception e) {
6037                    // Ignore exceptions.
6038                }
6039            }
6040            return false;
6041        }
6042
6043        // If this application record is still attached to a previous
6044        // process, clean it up now.
6045        if (app.thread != null) {
6046            handleAppDiedLocked(app, true, true);
6047        }
6048
6049        // Tell the process all about itself.
6050
6051        if (DEBUG_ALL) Slog.v(
6052                TAG, "Binding process pid " + pid + " to record " + app);
6053
6054        final String processName = app.processName;
6055        try {
6056            AppDeathRecipient adr = new AppDeathRecipient(
6057                    app, pid, thread);
6058            thread.asBinder().linkToDeath(adr, 0);
6059            app.deathRecipient = adr;
6060        } catch (RemoteException e) {
6061            app.resetPackageList(mProcessStats);
6062            startProcessLocked(app, "link fail", processName);
6063            return false;
6064        }
6065
6066        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6067
6068        app.makeActive(thread, mProcessStats);
6069        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6070        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6071        app.forcingToForeground = null;
6072        updateProcessForegroundLocked(app, false, false);
6073        app.hasShownUi = false;
6074        app.debugging = false;
6075        app.cached = false;
6076        app.killedByAm = false;
6077
6078        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6079
6080        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6081        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6082
6083        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6084            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6085            msg.obj = app;
6086            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6087        }
6088
6089        if (!normalMode) {
6090            Slog.i(TAG, "Launching preboot mode app: " + app);
6091        }
6092
6093        if (DEBUG_ALL) Slog.v(
6094            TAG, "New app record " + app
6095            + " thread=" + thread.asBinder() + " pid=" + pid);
6096        try {
6097            int testMode = IApplicationThread.DEBUG_OFF;
6098            if (mDebugApp != null && mDebugApp.equals(processName)) {
6099                testMode = mWaitForDebugger
6100                    ? IApplicationThread.DEBUG_WAIT
6101                    : IApplicationThread.DEBUG_ON;
6102                app.debugging = true;
6103                if (mDebugTransient) {
6104                    mDebugApp = mOrigDebugApp;
6105                    mWaitForDebugger = mOrigWaitForDebugger;
6106                }
6107            }
6108            String profileFile = app.instrumentationProfileFile;
6109            ParcelFileDescriptor profileFd = null;
6110            int samplingInterval = 0;
6111            boolean profileAutoStop = false;
6112            if (mProfileApp != null && mProfileApp.equals(processName)) {
6113                mProfileProc = app;
6114                profileFile = mProfileFile;
6115                profileFd = mProfileFd;
6116                samplingInterval = mSamplingInterval;
6117                profileAutoStop = mAutoStopProfiler;
6118            }
6119            boolean enableTrackAllocation = false;
6120            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6121                enableTrackAllocation = true;
6122                mTrackAllocationApp = null;
6123            }
6124
6125            // If the app is being launched for restore or full backup, set it up specially
6126            boolean isRestrictedBackupMode = false;
6127            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6128                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6129                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6130                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6131            }
6132
6133            notifyPackageUse(app.instrumentationInfo != null
6134                    ? app.instrumentationInfo.packageName
6135                    : app.info.packageName);
6136            if (app.instrumentationClass != null) {
6137                notifyPackageUse(app.instrumentationClass.getPackageName());
6138            }
6139            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6140                    + processName + " with config " + mConfiguration);
6141            ApplicationInfo appInfo = app.instrumentationInfo != null
6142                    ? app.instrumentationInfo : app.info;
6143            app.compat = compatibilityInfoForPackageLocked(appInfo);
6144            if (profileFd != null) {
6145                profileFd = profileFd.dup();
6146            }
6147            ProfilerInfo profilerInfo = profileFile == null ? null
6148                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6149            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6150                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6151                    app.instrumentationUiAutomationConnection, testMode,
6152                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6153                    isRestrictedBackupMode || !normalMode, app.persistent,
6154                    new Configuration(mConfiguration), app.compat,
6155                    getCommonServicesLocked(app.isolated),
6156                    mCoreSettingsObserver.getCoreSettingsLocked());
6157            updateLruProcessLocked(app, false, null);
6158            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6159        } catch (Exception e) {
6160            // todo: Yikes!  What should we do?  For now we will try to
6161            // start another process, but that could easily get us in
6162            // an infinite loop of restarting processes...
6163            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6164
6165            app.resetPackageList(mProcessStats);
6166            app.unlinkDeathRecipient();
6167            startProcessLocked(app, "bind fail", processName);
6168            return false;
6169        }
6170
6171        // Remove this record from the list of starting applications.
6172        mPersistentStartingProcesses.remove(app);
6173        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6174                "Attach application locked removing on hold: " + app);
6175        mProcessesOnHold.remove(app);
6176
6177        boolean badApp = false;
6178        boolean didSomething = false;
6179
6180        // See if the top visible activity is waiting to run in this process...
6181        if (normalMode) {
6182            try {
6183                if (mStackSupervisor.attachApplicationLocked(app)) {
6184                    didSomething = true;
6185                }
6186            } catch (Exception e) {
6187                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6188                badApp = true;
6189            }
6190        }
6191
6192        // Find any services that should be running in this process...
6193        if (!badApp) {
6194            try {
6195                didSomething |= mServices.attachApplicationLocked(app, processName);
6196            } catch (Exception e) {
6197                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6198                badApp = true;
6199            }
6200        }
6201
6202        // Check if a next-broadcast receiver is in this process...
6203        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6204            try {
6205                didSomething |= sendPendingBroadcastsLocked(app);
6206            } catch (Exception e) {
6207                // If the app died trying to launch the receiver we declare it 'bad'
6208                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6209                badApp = true;
6210            }
6211        }
6212
6213        // Check whether the next backup agent is in this process...
6214        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6215            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6216                    "New app is backup target, launching agent for " + app);
6217            notifyPackageUse(mBackupTarget.appInfo.packageName);
6218            try {
6219                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6220                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6221                        mBackupTarget.backupMode);
6222            } catch (Exception e) {
6223                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6224                badApp = true;
6225            }
6226        }
6227
6228        if (badApp) {
6229            app.kill("error during init", true);
6230            handleAppDiedLocked(app, false, true);
6231            return false;
6232        }
6233
6234        if (!didSomething) {
6235            updateOomAdjLocked();
6236        }
6237
6238        return true;
6239    }
6240
6241    @Override
6242    public final void attachApplication(IApplicationThread thread) {
6243        synchronized (this) {
6244            int callingPid = Binder.getCallingPid();
6245            final long origId = Binder.clearCallingIdentity();
6246            attachApplicationLocked(thread, callingPid);
6247            Binder.restoreCallingIdentity(origId);
6248        }
6249    }
6250
6251    @Override
6252    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6253        final long origId = Binder.clearCallingIdentity();
6254        synchronized (this) {
6255            ActivityStack stack = ActivityRecord.getStackLocked(token);
6256            if (stack != null) {
6257                ActivityRecord r =
6258                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6259                if (stopProfiling) {
6260                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6261                        try {
6262                            mProfileFd.close();
6263                        } catch (IOException e) {
6264                        }
6265                        clearProfilerLocked();
6266                    }
6267                }
6268            }
6269        }
6270        Binder.restoreCallingIdentity(origId);
6271    }
6272
6273    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6274        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6275                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6276    }
6277
6278    void enableScreenAfterBoot() {
6279        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6280                SystemClock.uptimeMillis());
6281        mWindowManager.enableScreenAfterBoot();
6282
6283        synchronized (this) {
6284            updateEventDispatchingLocked();
6285        }
6286    }
6287
6288    @Override
6289    public void showBootMessage(final CharSequence msg, final boolean always) {
6290        if (Binder.getCallingUid() != Process.myUid()) {
6291            // These days only the core system can call this, so apps can't get in
6292            // the way of what we show about running them.
6293        }
6294        mWindowManager.showBootMessage(msg, always);
6295    }
6296
6297    @Override
6298    public void keyguardWaitingForActivityDrawn() {
6299        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6300        final long token = Binder.clearCallingIdentity();
6301        try {
6302            synchronized (this) {
6303                if (DEBUG_LOCKSCREEN) logLockScreen("");
6304                mWindowManager.keyguardWaitingForActivityDrawn();
6305                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6306                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6307                    updateSleepIfNeededLocked();
6308                }
6309            }
6310        } finally {
6311            Binder.restoreCallingIdentity(token);
6312        }
6313    }
6314
6315    @Override
6316    public void keyguardGoingAway(boolean disableWindowAnimations,
6317            boolean keyguardGoingToNotificationShade) {
6318        enforceNotIsolatedCaller("keyguardGoingAway");
6319        final long token = Binder.clearCallingIdentity();
6320        try {
6321            synchronized (this) {
6322                if (DEBUG_LOCKSCREEN) logLockScreen("");
6323                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6324                        keyguardGoingToNotificationShade);
6325                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6326                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6327                    updateSleepIfNeededLocked();
6328                }
6329            }
6330        } finally {
6331            Binder.restoreCallingIdentity(token);
6332        }
6333    }
6334
6335    final void finishBooting() {
6336        synchronized (this) {
6337            if (!mBootAnimationComplete) {
6338                mCallFinishBooting = true;
6339                return;
6340            }
6341            mCallFinishBooting = false;
6342        }
6343
6344        ArraySet<String> completedIsas = new ArraySet<String>();
6345        for (String abi : Build.SUPPORTED_ABIS) {
6346            Process.establishZygoteConnectionForAbi(abi);
6347            final String instructionSet = VMRuntime.getInstructionSet(abi);
6348            if (!completedIsas.contains(instructionSet)) {
6349                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6350                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6351                }
6352                completedIsas.add(instructionSet);
6353            }
6354        }
6355
6356        IntentFilter pkgFilter = new IntentFilter();
6357        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6358        pkgFilter.addDataScheme("package");
6359        mContext.registerReceiver(new BroadcastReceiver() {
6360            @Override
6361            public void onReceive(Context context, Intent intent) {
6362                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6363                if (pkgs != null) {
6364                    for (String pkg : pkgs) {
6365                        synchronized (ActivityManagerService.this) {
6366                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6367                                    0, "query restart")) {
6368                                setResultCode(Activity.RESULT_OK);
6369                                return;
6370                            }
6371                        }
6372                    }
6373                }
6374            }
6375        }, pkgFilter);
6376
6377        IntentFilter dumpheapFilter = new IntentFilter();
6378        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6379        mContext.registerReceiver(new BroadcastReceiver() {
6380            @Override
6381            public void onReceive(Context context, Intent intent) {
6382                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6383                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6384                } else {
6385                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6386                }
6387            }
6388        }, dumpheapFilter);
6389
6390        // Let system services know.
6391        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6392
6393        synchronized (this) {
6394            // Ensure that any processes we had put on hold are now started
6395            // up.
6396            final int NP = mProcessesOnHold.size();
6397            if (NP > 0) {
6398                ArrayList<ProcessRecord> procs =
6399                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6400                for (int ip=0; ip<NP; ip++) {
6401                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6402                            + procs.get(ip));
6403                    startProcessLocked(procs.get(ip), "on-hold", null);
6404                }
6405            }
6406
6407            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6408                // Start looking for apps that are abusing wake locks.
6409                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6410                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6411                // Tell anyone interested that we are done booting!
6412                SystemProperties.set("sys.boot_completed", "1");
6413
6414                // And trigger dev.bootcomplete if we are not showing encryption progress
6415                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6416                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6417                    SystemProperties.set("dev.bootcomplete", "1");
6418                }
6419                mUserController.sendBootCompletedLocked(
6420                        new IIntentReceiver.Stub() {
6421                            @Override
6422                            public void performReceive(Intent intent, int resultCode,
6423                                    String data, Bundle extras, boolean ordered,
6424                                    boolean sticky, int sendingUser) {
6425                                synchronized (ActivityManagerService.this) {
6426                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6427                                            true, false);
6428                                }
6429                            }
6430                        });
6431                scheduleStartProfilesLocked();
6432            }
6433        }
6434    }
6435
6436    @Override
6437    public void bootAnimationComplete() {
6438        final boolean callFinishBooting;
6439        synchronized (this) {
6440            callFinishBooting = mCallFinishBooting;
6441            mBootAnimationComplete = true;
6442        }
6443        if (callFinishBooting) {
6444            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6445            finishBooting();
6446            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6447        }
6448    }
6449
6450    final void ensureBootCompleted() {
6451        boolean booting;
6452        boolean enableScreen;
6453        synchronized (this) {
6454            booting = mBooting;
6455            mBooting = false;
6456            enableScreen = !mBooted;
6457            mBooted = true;
6458        }
6459
6460        if (booting) {
6461            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6462            finishBooting();
6463            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6464        }
6465
6466        if (enableScreen) {
6467            enableScreenAfterBoot();
6468        }
6469    }
6470
6471    @Override
6472    public final void activityResumed(IBinder token) {
6473        final long origId = Binder.clearCallingIdentity();
6474        synchronized(this) {
6475            ActivityStack stack = ActivityRecord.getStackLocked(token);
6476            if (stack != null) {
6477                ActivityRecord.activityResumedLocked(token);
6478            }
6479        }
6480        Binder.restoreCallingIdentity(origId);
6481    }
6482
6483    @Override
6484    public final void activityPaused(IBinder token) {
6485        final long origId = Binder.clearCallingIdentity();
6486        synchronized(this) {
6487            ActivityStack stack = ActivityRecord.getStackLocked(token);
6488            if (stack != null) {
6489                stack.activityPausedLocked(token, false);
6490            }
6491        }
6492        Binder.restoreCallingIdentity(origId);
6493    }
6494
6495    @Override
6496    public final void activityStopped(IBinder token, Bundle icicle,
6497            PersistableBundle persistentState, CharSequence description) {
6498        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6499
6500        // Refuse possible leaked file descriptors
6501        if (icicle != null && icicle.hasFileDescriptors()) {
6502            throw new IllegalArgumentException("File descriptors passed in Bundle");
6503        }
6504
6505        final long origId = Binder.clearCallingIdentity();
6506
6507        synchronized (this) {
6508            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6509            if (r != null) {
6510                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6511            }
6512        }
6513
6514        trimApplications();
6515
6516        Binder.restoreCallingIdentity(origId);
6517    }
6518
6519    @Override
6520    public final void activityDestroyed(IBinder token) {
6521        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6522        synchronized (this) {
6523            ActivityStack stack = ActivityRecord.getStackLocked(token);
6524            if (stack != null) {
6525                stack.activityDestroyedLocked(token, "activityDestroyed");
6526            }
6527        }
6528    }
6529
6530    @Override
6531    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6532            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6533        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6534                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6535        synchronized (this) {
6536            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6537            if (record == null) {
6538                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6539                        + "found for: " + token);
6540            }
6541            record.setSizeConfigurations(horizontalSizeConfiguration,
6542                    verticalSizeConfigurations, smallestSizeConfigurations);
6543        }
6544    }
6545
6546    @Override
6547    public final void backgroundResourcesReleased(IBinder token) {
6548        final long origId = Binder.clearCallingIdentity();
6549        try {
6550            synchronized (this) {
6551                ActivityStack stack = ActivityRecord.getStackLocked(token);
6552                if (stack != null) {
6553                    stack.backgroundResourcesReleased();
6554                }
6555            }
6556        } finally {
6557            Binder.restoreCallingIdentity(origId);
6558        }
6559    }
6560
6561    @Override
6562    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6563        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6564    }
6565
6566    @Override
6567    public final void notifyEnterAnimationComplete(IBinder token) {
6568        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6569    }
6570
6571    @Override
6572    public String getCallingPackage(IBinder token) {
6573        synchronized (this) {
6574            ActivityRecord r = getCallingRecordLocked(token);
6575            return r != null ? r.info.packageName : null;
6576        }
6577    }
6578
6579    @Override
6580    public ComponentName getCallingActivity(IBinder token) {
6581        synchronized (this) {
6582            ActivityRecord r = getCallingRecordLocked(token);
6583            return r != null ? r.intent.getComponent() : null;
6584        }
6585    }
6586
6587    private ActivityRecord getCallingRecordLocked(IBinder token) {
6588        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6589        if (r == null) {
6590            return null;
6591        }
6592        return r.resultTo;
6593    }
6594
6595    @Override
6596    public ComponentName getActivityClassForToken(IBinder token) {
6597        synchronized(this) {
6598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6599            if (r == null) {
6600                return null;
6601            }
6602            return r.intent.getComponent();
6603        }
6604    }
6605
6606    @Override
6607    public String getPackageForToken(IBinder token) {
6608        synchronized(this) {
6609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6610            if (r == null) {
6611                return null;
6612            }
6613            return r.packageName;
6614        }
6615    }
6616
6617    @Override
6618    public boolean isRootVoiceInteraction(IBinder token) {
6619        synchronized(this) {
6620            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6621            if (r == null) {
6622                return false;
6623            }
6624            return r.rootVoiceInteraction;
6625        }
6626    }
6627
6628    @Override
6629    public IIntentSender getIntentSender(int type,
6630            String packageName, IBinder token, String resultWho,
6631            int requestCode, Intent[] intents, String[] resolvedTypes,
6632            int flags, Bundle bOptions, int userId) {
6633        enforceNotIsolatedCaller("getIntentSender");
6634        // Refuse possible leaked file descriptors
6635        if (intents != null) {
6636            if (intents.length < 1) {
6637                throw new IllegalArgumentException("Intents array length must be >= 1");
6638            }
6639            for (int i=0; i<intents.length; i++) {
6640                Intent intent = intents[i];
6641                if (intent != null) {
6642                    if (intent.hasFileDescriptors()) {
6643                        throw new IllegalArgumentException("File descriptors passed in Intent");
6644                    }
6645                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6646                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6647                        throw new IllegalArgumentException(
6648                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6649                    }
6650                    intents[i] = new Intent(intent);
6651                }
6652            }
6653            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6654                throw new IllegalArgumentException(
6655                        "Intent array length does not match resolvedTypes length");
6656            }
6657        }
6658        if (bOptions != null) {
6659            if (bOptions.hasFileDescriptors()) {
6660                throw new IllegalArgumentException("File descriptors passed in options");
6661            }
6662        }
6663
6664        synchronized(this) {
6665            int callingUid = Binder.getCallingUid();
6666            int origUserId = userId;
6667            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6668                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6669                    ALLOW_NON_FULL, "getIntentSender", null);
6670            if (origUserId == UserHandle.USER_CURRENT) {
6671                // We don't want to evaluate this until the pending intent is
6672                // actually executed.  However, we do want to always do the
6673                // security checking for it above.
6674                userId = UserHandle.USER_CURRENT;
6675            }
6676            try {
6677                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6678                    int uid = AppGlobals.getPackageManager()
6679                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6680                    if (!UserHandle.isSameApp(callingUid, uid)) {
6681                        String msg = "Permission Denial: getIntentSender() from pid="
6682                            + Binder.getCallingPid()
6683                            + ", uid=" + Binder.getCallingUid()
6684                            + ", (need uid=" + uid + ")"
6685                            + " is not allowed to send as package " + packageName;
6686                        Slog.w(TAG, msg);
6687                        throw new SecurityException(msg);
6688                    }
6689                }
6690
6691                return getIntentSenderLocked(type, packageName, callingUid, userId,
6692                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6693
6694            } catch (RemoteException e) {
6695                throw new SecurityException(e);
6696            }
6697        }
6698    }
6699
6700    IIntentSender getIntentSenderLocked(int type, String packageName,
6701            int callingUid, int userId, IBinder token, String resultWho,
6702            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6703            Bundle bOptions) {
6704        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6705        ActivityRecord activity = null;
6706        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6707            activity = ActivityRecord.isInStackLocked(token);
6708            if (activity == null) {
6709                return null;
6710            }
6711            if (activity.finishing) {
6712                return null;
6713            }
6714        }
6715
6716        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6717        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6718        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6719        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6720                |PendingIntent.FLAG_UPDATE_CURRENT);
6721
6722        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6723                type, packageName, activity, resultWho,
6724                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6725        WeakReference<PendingIntentRecord> ref;
6726        ref = mIntentSenderRecords.get(key);
6727        PendingIntentRecord rec = ref != null ? ref.get() : null;
6728        if (rec != null) {
6729            if (!cancelCurrent) {
6730                if (updateCurrent) {
6731                    if (rec.key.requestIntent != null) {
6732                        rec.key.requestIntent.replaceExtras(intents != null ?
6733                                intents[intents.length - 1] : null);
6734                    }
6735                    if (intents != null) {
6736                        intents[intents.length-1] = rec.key.requestIntent;
6737                        rec.key.allIntents = intents;
6738                        rec.key.allResolvedTypes = resolvedTypes;
6739                    } else {
6740                        rec.key.allIntents = null;
6741                        rec.key.allResolvedTypes = null;
6742                    }
6743                }
6744                return rec;
6745            }
6746            rec.canceled = true;
6747            mIntentSenderRecords.remove(key);
6748        }
6749        if (noCreate) {
6750            return rec;
6751        }
6752        rec = new PendingIntentRecord(this, key, callingUid);
6753        mIntentSenderRecords.put(key, rec.ref);
6754        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6755            if (activity.pendingResults == null) {
6756                activity.pendingResults
6757                        = new HashSet<WeakReference<PendingIntentRecord>>();
6758            }
6759            activity.pendingResults.add(rec.ref);
6760        }
6761        return rec;
6762    }
6763
6764    @Override
6765    public void cancelIntentSender(IIntentSender sender) {
6766        if (!(sender instanceof PendingIntentRecord)) {
6767            return;
6768        }
6769        synchronized(this) {
6770            PendingIntentRecord rec = (PendingIntentRecord)sender;
6771            try {
6772                int uid = AppGlobals.getPackageManager()
6773                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6774                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6775                    String msg = "Permission Denial: cancelIntentSender() from pid="
6776                        + Binder.getCallingPid()
6777                        + ", uid=" + Binder.getCallingUid()
6778                        + " is not allowed to cancel packges "
6779                        + rec.key.packageName;
6780                    Slog.w(TAG, msg);
6781                    throw new SecurityException(msg);
6782                }
6783            } catch (RemoteException e) {
6784                throw new SecurityException(e);
6785            }
6786            cancelIntentSenderLocked(rec, true);
6787        }
6788    }
6789
6790    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6791        rec.canceled = true;
6792        mIntentSenderRecords.remove(rec.key);
6793        if (cleanActivity && rec.key.activity != null) {
6794            rec.key.activity.pendingResults.remove(rec.ref);
6795        }
6796    }
6797
6798    @Override
6799    public String getPackageForIntentSender(IIntentSender pendingResult) {
6800        if (!(pendingResult instanceof PendingIntentRecord)) {
6801            return null;
6802        }
6803        try {
6804            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6805            return res.key.packageName;
6806        } catch (ClassCastException e) {
6807        }
6808        return null;
6809    }
6810
6811    @Override
6812    public int getUidForIntentSender(IIntentSender sender) {
6813        if (sender instanceof PendingIntentRecord) {
6814            try {
6815                PendingIntentRecord res = (PendingIntentRecord)sender;
6816                return res.uid;
6817            } catch (ClassCastException e) {
6818            }
6819        }
6820        return -1;
6821    }
6822
6823    @Override
6824    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6825        if (!(pendingResult instanceof PendingIntentRecord)) {
6826            return false;
6827        }
6828        try {
6829            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6830            if (res.key.allIntents == null) {
6831                return false;
6832            }
6833            for (int i=0; i<res.key.allIntents.length; i++) {
6834                Intent intent = res.key.allIntents[i];
6835                if (intent.getPackage() != null && intent.getComponent() != null) {
6836                    return false;
6837                }
6838            }
6839            return true;
6840        } catch (ClassCastException e) {
6841        }
6842        return false;
6843    }
6844
6845    @Override
6846    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6847        if (!(pendingResult instanceof PendingIntentRecord)) {
6848            return false;
6849        }
6850        try {
6851            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6852            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6853                return true;
6854            }
6855            return false;
6856        } catch (ClassCastException e) {
6857        }
6858        return false;
6859    }
6860
6861    @Override
6862    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6863        if (!(pendingResult instanceof PendingIntentRecord)) {
6864            return null;
6865        }
6866        try {
6867            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6868            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6869        } catch (ClassCastException e) {
6870        }
6871        return null;
6872    }
6873
6874    @Override
6875    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6876        if (!(pendingResult instanceof PendingIntentRecord)) {
6877            return null;
6878        }
6879        try {
6880            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6881            synchronized (this) {
6882                return getTagForIntentSenderLocked(res, prefix);
6883            }
6884        } catch (ClassCastException e) {
6885        }
6886        return null;
6887    }
6888
6889    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6890        final Intent intent = res.key.requestIntent;
6891        if (intent != null) {
6892            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6893                    || res.lastTagPrefix.equals(prefix))) {
6894                return res.lastTag;
6895            }
6896            res.lastTagPrefix = prefix;
6897            final StringBuilder sb = new StringBuilder(128);
6898            if (prefix != null) {
6899                sb.append(prefix);
6900            }
6901            if (intent.getAction() != null) {
6902                sb.append(intent.getAction());
6903            } else if (intent.getComponent() != null) {
6904                intent.getComponent().appendShortString(sb);
6905            } else {
6906                sb.append("?");
6907            }
6908            return res.lastTag = sb.toString();
6909        }
6910        return null;
6911    }
6912
6913    @Override
6914    public void setProcessLimit(int max) {
6915        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6916                "setProcessLimit()");
6917        synchronized (this) {
6918            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6919            mProcessLimitOverride = max;
6920        }
6921        trimApplications();
6922    }
6923
6924    @Override
6925    public int getProcessLimit() {
6926        synchronized (this) {
6927            return mProcessLimitOverride;
6928        }
6929    }
6930
6931    void foregroundTokenDied(ForegroundToken token) {
6932        synchronized (ActivityManagerService.this) {
6933            synchronized (mPidsSelfLocked) {
6934                ForegroundToken cur
6935                    = mForegroundProcesses.get(token.pid);
6936                if (cur != token) {
6937                    return;
6938                }
6939                mForegroundProcesses.remove(token.pid);
6940                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6941                if (pr == null) {
6942                    return;
6943                }
6944                pr.forcingToForeground = null;
6945                updateProcessForegroundLocked(pr, false, false);
6946            }
6947            updateOomAdjLocked();
6948        }
6949    }
6950
6951    @Override
6952    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6953        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6954                "setProcessForeground()");
6955        synchronized(this) {
6956            boolean changed = false;
6957
6958            synchronized (mPidsSelfLocked) {
6959                ProcessRecord pr = mPidsSelfLocked.get(pid);
6960                if (pr == null && isForeground) {
6961                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6962                    return;
6963                }
6964                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6965                if (oldToken != null) {
6966                    oldToken.token.unlinkToDeath(oldToken, 0);
6967                    mForegroundProcesses.remove(pid);
6968                    if (pr != null) {
6969                        pr.forcingToForeground = null;
6970                    }
6971                    changed = true;
6972                }
6973                if (isForeground && token != null) {
6974                    ForegroundToken newToken = new ForegroundToken() {
6975                        @Override
6976                        public void binderDied() {
6977                            foregroundTokenDied(this);
6978                        }
6979                    };
6980                    newToken.pid = pid;
6981                    newToken.token = token;
6982                    try {
6983                        token.linkToDeath(newToken, 0);
6984                        mForegroundProcesses.put(pid, newToken);
6985                        pr.forcingToForeground = token;
6986                        changed = true;
6987                    } catch (RemoteException e) {
6988                        // If the process died while doing this, we will later
6989                        // do the cleanup with the process death link.
6990                    }
6991                }
6992            }
6993
6994            if (changed) {
6995                updateOomAdjLocked();
6996            }
6997        }
6998    }
6999
7000    // =========================================================
7001    // PROCESS INFO
7002    // =========================================================
7003
7004    static class ProcessInfoService extends IProcessInfoService.Stub {
7005        final ActivityManagerService mActivityManagerService;
7006        ProcessInfoService(ActivityManagerService activityManagerService) {
7007            mActivityManagerService = activityManagerService;
7008        }
7009
7010        @Override
7011        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7012            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7013        }
7014    }
7015
7016    /**
7017     * For each PID in the given input array, write the current process state
7018     * for that process into the output array, or -1 to indicate that no
7019     * process with the given PID exists.
7020     */
7021    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7022        if (pids == null) {
7023            throw new NullPointerException("pids");
7024        } else if (states == null) {
7025            throw new NullPointerException("states");
7026        } else if (pids.length != states.length) {
7027            throw new IllegalArgumentException("input and output arrays have different lengths!");
7028        }
7029
7030        synchronized (mPidsSelfLocked) {
7031            for (int i = 0; i < pids.length; i++) {
7032                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7033                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7034                        pr.curProcState;
7035            }
7036        }
7037    }
7038
7039    // =========================================================
7040    // PERMISSIONS
7041    // =========================================================
7042
7043    static class PermissionController extends IPermissionController.Stub {
7044        ActivityManagerService mActivityManagerService;
7045        PermissionController(ActivityManagerService activityManagerService) {
7046            mActivityManagerService = activityManagerService;
7047        }
7048
7049        @Override
7050        public boolean checkPermission(String permission, int pid, int uid) {
7051            return mActivityManagerService.checkPermission(permission, pid,
7052                    uid) == PackageManager.PERMISSION_GRANTED;
7053        }
7054
7055        @Override
7056        public String[] getPackagesForUid(int uid) {
7057            return mActivityManagerService.mContext.getPackageManager()
7058                    .getPackagesForUid(uid);
7059        }
7060
7061        @Override
7062        public boolean isRuntimePermission(String permission) {
7063            try {
7064                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7065                        .getPermissionInfo(permission, 0);
7066                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7067            } catch (NameNotFoundException nnfe) {
7068                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7069            }
7070            return false;
7071        }
7072    }
7073
7074    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7075        @Override
7076        public int checkComponentPermission(String permission, int pid, int uid,
7077                int owningUid, boolean exported) {
7078            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7079                    owningUid, exported);
7080        }
7081
7082        @Override
7083        public Object getAMSLock() {
7084            return ActivityManagerService.this;
7085        }
7086    }
7087
7088    /**
7089     * This can be called with or without the global lock held.
7090     */
7091    int checkComponentPermission(String permission, int pid, int uid,
7092            int owningUid, boolean exported) {
7093        if (pid == MY_PID) {
7094            return PackageManager.PERMISSION_GRANTED;
7095        }
7096        return ActivityManager.checkComponentPermission(permission, uid,
7097                owningUid, exported);
7098    }
7099
7100    /**
7101     * As the only public entry point for permissions checking, this method
7102     * can enforce the semantic that requesting a check on a null global
7103     * permission is automatically denied.  (Internally a null permission
7104     * string is used when calling {@link #checkComponentPermission} in cases
7105     * when only uid-based security is needed.)
7106     *
7107     * This can be called with or without the global lock held.
7108     */
7109    @Override
7110    public int checkPermission(String permission, int pid, int uid) {
7111        if (permission == null) {
7112            return PackageManager.PERMISSION_DENIED;
7113        }
7114        return checkComponentPermission(permission, pid, uid, -1, true);
7115    }
7116
7117    @Override
7118    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7119        if (permission == null) {
7120            return PackageManager.PERMISSION_DENIED;
7121        }
7122
7123        // We might be performing an operation on behalf of an indirect binder
7124        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7125        // client identity accordingly before proceeding.
7126        Identity tlsIdentity = sCallerIdentity.get();
7127        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7128            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7129                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7130            uid = tlsIdentity.uid;
7131            pid = tlsIdentity.pid;
7132        }
7133
7134        return checkComponentPermission(permission, pid, uid, -1, true);
7135    }
7136
7137    /**
7138     * Binder IPC calls go through the public entry point.
7139     * This can be called with or without the global lock held.
7140     */
7141    int checkCallingPermission(String permission) {
7142        return checkPermission(permission,
7143                Binder.getCallingPid(),
7144                UserHandle.getAppId(Binder.getCallingUid()));
7145    }
7146
7147    /**
7148     * This can be called with or without the global lock held.
7149     */
7150    void enforceCallingPermission(String permission, String func) {
7151        if (checkCallingPermission(permission)
7152                == PackageManager.PERMISSION_GRANTED) {
7153            return;
7154        }
7155
7156        String msg = "Permission Denial: " + func + " from pid="
7157                + Binder.getCallingPid()
7158                + ", uid=" + Binder.getCallingUid()
7159                + " requires " + permission;
7160        Slog.w(TAG, msg);
7161        throw new SecurityException(msg);
7162    }
7163
7164    /**
7165     * Determine if UID is holding permissions required to access {@link Uri} in
7166     * the given {@link ProviderInfo}. Final permission checking is always done
7167     * in {@link ContentProvider}.
7168     */
7169    private final boolean checkHoldingPermissionsLocked(
7170            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7171        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7172                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7173        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7174            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7175                    != PERMISSION_GRANTED) {
7176                return false;
7177            }
7178        }
7179        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7180    }
7181
7182    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7183            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7184        if (pi.applicationInfo.uid == uid) {
7185            return true;
7186        } else if (!pi.exported) {
7187            return false;
7188        }
7189
7190        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7191        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7192        try {
7193            // check if target holds top-level <provider> permissions
7194            if (!readMet && pi.readPermission != null && considerUidPermissions
7195                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7196                readMet = true;
7197            }
7198            if (!writeMet && pi.writePermission != null && considerUidPermissions
7199                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7200                writeMet = true;
7201            }
7202
7203            // track if unprotected read/write is allowed; any denied
7204            // <path-permission> below removes this ability
7205            boolean allowDefaultRead = pi.readPermission == null;
7206            boolean allowDefaultWrite = pi.writePermission == null;
7207
7208            // check if target holds any <path-permission> that match uri
7209            final PathPermission[] pps = pi.pathPermissions;
7210            if (pps != null) {
7211                final String path = grantUri.uri.getPath();
7212                int i = pps.length;
7213                while (i > 0 && (!readMet || !writeMet)) {
7214                    i--;
7215                    PathPermission pp = pps[i];
7216                    if (pp.match(path)) {
7217                        if (!readMet) {
7218                            final String pprperm = pp.getReadPermission();
7219                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7220                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7221                                    + ": match=" + pp.match(path)
7222                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7223                            if (pprperm != null) {
7224                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7225                                        == PERMISSION_GRANTED) {
7226                                    readMet = true;
7227                                } else {
7228                                    allowDefaultRead = false;
7229                                }
7230                            }
7231                        }
7232                        if (!writeMet) {
7233                            final String ppwperm = pp.getWritePermission();
7234                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7235                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7236                                    + ": match=" + pp.match(path)
7237                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7238                            if (ppwperm != null) {
7239                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7240                                        == PERMISSION_GRANTED) {
7241                                    writeMet = true;
7242                                } else {
7243                                    allowDefaultWrite = false;
7244                                }
7245                            }
7246                        }
7247                    }
7248                }
7249            }
7250
7251            // grant unprotected <provider> read/write, if not blocked by
7252            // <path-permission> above
7253            if (allowDefaultRead) readMet = true;
7254            if (allowDefaultWrite) writeMet = true;
7255
7256        } catch (RemoteException e) {
7257            return false;
7258        }
7259
7260        return readMet && writeMet;
7261    }
7262
7263    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7264        ProviderInfo pi = null;
7265        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7266        if (cpr != null) {
7267            pi = cpr.info;
7268        } else {
7269            try {
7270                pi = AppGlobals.getPackageManager().resolveContentProvider(
7271                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7272            } catch (RemoteException ex) {
7273            }
7274        }
7275        return pi;
7276    }
7277
7278    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7279        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7280        if (targetUris != null) {
7281            return targetUris.get(grantUri);
7282        }
7283        return null;
7284    }
7285
7286    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7287            String targetPkg, int targetUid, GrantUri grantUri) {
7288        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7289        if (targetUris == null) {
7290            targetUris = Maps.newArrayMap();
7291            mGrantedUriPermissions.put(targetUid, targetUris);
7292        }
7293
7294        UriPermission perm = targetUris.get(grantUri);
7295        if (perm == null) {
7296            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7297            targetUris.put(grantUri, perm);
7298        }
7299
7300        return perm;
7301    }
7302
7303    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7304            final int modeFlags) {
7305        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7306        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7307                : UriPermission.STRENGTH_OWNED;
7308
7309        // Root gets to do everything.
7310        if (uid == 0) {
7311            return true;
7312        }
7313
7314        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7315        if (perms == null) return false;
7316
7317        // First look for exact match
7318        final UriPermission exactPerm = perms.get(grantUri);
7319        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7320            return true;
7321        }
7322
7323        // No exact match, look for prefixes
7324        final int N = perms.size();
7325        for (int i = 0; i < N; i++) {
7326            final UriPermission perm = perms.valueAt(i);
7327            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7328                    && perm.getStrength(modeFlags) >= minStrength) {
7329                return true;
7330            }
7331        }
7332
7333        return false;
7334    }
7335
7336    /**
7337     * @param uri This uri must NOT contain an embedded userId.
7338     * @param userId The userId in which the uri is to be resolved.
7339     */
7340    @Override
7341    public int checkUriPermission(Uri uri, int pid, int uid,
7342            final int modeFlags, int userId, IBinder callerToken) {
7343        enforceNotIsolatedCaller("checkUriPermission");
7344
7345        // Another redirected-binder-call permissions check as in
7346        // {@link checkPermissionWithToken}.
7347        Identity tlsIdentity = sCallerIdentity.get();
7348        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7349            uid = tlsIdentity.uid;
7350            pid = tlsIdentity.pid;
7351        }
7352
7353        // Our own process gets to do everything.
7354        if (pid == MY_PID) {
7355            return PackageManager.PERMISSION_GRANTED;
7356        }
7357        synchronized (this) {
7358            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7359                    ? PackageManager.PERMISSION_GRANTED
7360                    : PackageManager.PERMISSION_DENIED;
7361        }
7362    }
7363
7364    /**
7365     * Check if the targetPkg can be granted permission to access uri by
7366     * the callingUid using the given modeFlags.  Throws a security exception
7367     * if callingUid is not allowed to do this.  Returns the uid of the target
7368     * if the URI permission grant should be performed; returns -1 if it is not
7369     * needed (for example targetPkg already has permission to access the URI).
7370     * If you already know the uid of the target, you can supply it in
7371     * lastTargetUid else set that to -1.
7372     */
7373    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7374            final int modeFlags, int lastTargetUid) {
7375        if (!Intent.isAccessUriMode(modeFlags)) {
7376            return -1;
7377        }
7378
7379        if (targetPkg != null) {
7380            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7381                    "Checking grant " + targetPkg + " permission to " + grantUri);
7382        }
7383
7384        final IPackageManager pm = AppGlobals.getPackageManager();
7385
7386        // If this is not a content: uri, we can't do anything with it.
7387        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7388            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7389                    "Can't grant URI permission for non-content URI: " + grantUri);
7390            return -1;
7391        }
7392
7393        final String authority = grantUri.uri.getAuthority();
7394        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7395        if (pi == null) {
7396            Slog.w(TAG, "No content provider found for permission check: " +
7397                    grantUri.uri.toSafeString());
7398            return -1;
7399        }
7400
7401        int targetUid = lastTargetUid;
7402        if (targetUid < 0 && targetPkg != null) {
7403            try {
7404                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7405                if (targetUid < 0) {
7406                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7407                            "Can't grant URI permission no uid for: " + targetPkg);
7408                    return -1;
7409                }
7410            } catch (RemoteException ex) {
7411                return -1;
7412            }
7413        }
7414
7415        if (targetUid >= 0) {
7416            // First...  does the target actually need this permission?
7417            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7418                // No need to grant the target this permission.
7419                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7420                        "Target " + targetPkg + " already has full permission to " + grantUri);
7421                return -1;
7422            }
7423        } else {
7424            // First...  there is no target package, so can anyone access it?
7425            boolean allowed = pi.exported;
7426            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7427                if (pi.readPermission != null) {
7428                    allowed = false;
7429                }
7430            }
7431            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7432                if (pi.writePermission != null) {
7433                    allowed = false;
7434                }
7435            }
7436            if (allowed) {
7437                return -1;
7438            }
7439        }
7440
7441        /* There is a special cross user grant if:
7442         * - The target is on another user.
7443         * - Apps on the current user can access the uri without any uid permissions.
7444         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7445         * grant uri permissions.
7446         */
7447        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7448                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7449                modeFlags, false /*without considering the uid permissions*/);
7450
7451        // Second...  is the provider allowing granting of URI permissions?
7452        if (!specialCrossUserGrant) {
7453            if (!pi.grantUriPermissions) {
7454                throw new SecurityException("Provider " + pi.packageName
7455                        + "/" + pi.name
7456                        + " does not allow granting of Uri permissions (uri "
7457                        + grantUri + ")");
7458            }
7459            if (pi.uriPermissionPatterns != null) {
7460                final int N = pi.uriPermissionPatterns.length;
7461                boolean allowed = false;
7462                for (int i=0; i<N; i++) {
7463                    if (pi.uriPermissionPatterns[i] != null
7464                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7465                        allowed = true;
7466                        break;
7467                    }
7468                }
7469                if (!allowed) {
7470                    throw new SecurityException("Provider " + pi.packageName
7471                            + "/" + pi.name
7472                            + " does not allow granting of permission to path of Uri "
7473                            + grantUri);
7474                }
7475            }
7476        }
7477
7478        // Third...  does the caller itself have permission to access
7479        // this uri?
7480        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7481            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7482                // Require they hold a strong enough Uri permission
7483                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7484                    throw new SecurityException("Uid " + callingUid
7485                            + " does not have permission to uri " + grantUri);
7486                }
7487            }
7488        }
7489        return targetUid;
7490    }
7491
7492    /**
7493     * @param uri This uri must NOT contain an embedded userId.
7494     * @param userId The userId in which the uri is to be resolved.
7495     */
7496    @Override
7497    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7498            final int modeFlags, int userId) {
7499        enforceNotIsolatedCaller("checkGrantUriPermission");
7500        synchronized(this) {
7501            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7502                    new GrantUri(userId, uri, false), modeFlags, -1);
7503        }
7504    }
7505
7506    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7507            final int modeFlags, UriPermissionOwner owner) {
7508        if (!Intent.isAccessUriMode(modeFlags)) {
7509            return;
7510        }
7511
7512        // So here we are: the caller has the assumed permission
7513        // to the uri, and the target doesn't.  Let's now give this to
7514        // the target.
7515
7516        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7517                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7518
7519        final String authority = grantUri.uri.getAuthority();
7520        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7521        if (pi == null) {
7522            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7523            return;
7524        }
7525
7526        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7527            grantUri.prefix = true;
7528        }
7529        final UriPermission perm = findOrCreateUriPermissionLocked(
7530                pi.packageName, targetPkg, targetUid, grantUri);
7531        perm.grantModes(modeFlags, owner);
7532    }
7533
7534    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7535            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7536        if (targetPkg == null) {
7537            throw new NullPointerException("targetPkg");
7538        }
7539        int targetUid;
7540        final IPackageManager pm = AppGlobals.getPackageManager();
7541        try {
7542            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7543        } catch (RemoteException ex) {
7544            return;
7545        }
7546
7547        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7548                targetUid);
7549        if (targetUid < 0) {
7550            return;
7551        }
7552
7553        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7554                owner);
7555    }
7556
7557    static class NeededUriGrants extends ArrayList<GrantUri> {
7558        final String targetPkg;
7559        final int targetUid;
7560        final int flags;
7561
7562        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7563            this.targetPkg = targetPkg;
7564            this.targetUid = targetUid;
7565            this.flags = flags;
7566        }
7567    }
7568
7569    /**
7570     * Like checkGrantUriPermissionLocked, but takes an Intent.
7571     */
7572    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7573            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7574        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7575                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7576                + " clip=" + (intent != null ? intent.getClipData() : null)
7577                + " from " + intent + "; flags=0x"
7578                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7579
7580        if (targetPkg == null) {
7581            throw new NullPointerException("targetPkg");
7582        }
7583
7584        if (intent == null) {
7585            return null;
7586        }
7587        Uri data = intent.getData();
7588        ClipData clip = intent.getClipData();
7589        if (data == null && clip == null) {
7590            return null;
7591        }
7592        // Default userId for uris in the intent (if they don't specify it themselves)
7593        int contentUserHint = intent.getContentUserHint();
7594        if (contentUserHint == UserHandle.USER_CURRENT) {
7595            contentUserHint = UserHandle.getUserId(callingUid);
7596        }
7597        final IPackageManager pm = AppGlobals.getPackageManager();
7598        int targetUid;
7599        if (needed != null) {
7600            targetUid = needed.targetUid;
7601        } else {
7602            try {
7603                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7604            } catch (RemoteException ex) {
7605                return null;
7606            }
7607            if (targetUid < 0) {
7608                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7609                        "Can't grant URI permission no uid for: " + targetPkg
7610                        + " on user " + targetUserId);
7611                return null;
7612            }
7613        }
7614        if (data != null) {
7615            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7616            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7617                    targetUid);
7618            if (targetUid > 0) {
7619                if (needed == null) {
7620                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7621                }
7622                needed.add(grantUri);
7623            }
7624        }
7625        if (clip != null) {
7626            for (int i=0; i<clip.getItemCount(); i++) {
7627                Uri uri = clip.getItemAt(i).getUri();
7628                if (uri != null) {
7629                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7630                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7631                            targetUid);
7632                    if (targetUid > 0) {
7633                        if (needed == null) {
7634                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7635                        }
7636                        needed.add(grantUri);
7637                    }
7638                } else {
7639                    Intent clipIntent = clip.getItemAt(i).getIntent();
7640                    if (clipIntent != null) {
7641                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7642                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7643                        if (newNeeded != null) {
7644                            needed = newNeeded;
7645                        }
7646                    }
7647                }
7648            }
7649        }
7650
7651        return needed;
7652    }
7653
7654    /**
7655     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7656     */
7657    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7658            UriPermissionOwner owner) {
7659        if (needed != null) {
7660            for (int i=0; i<needed.size(); i++) {
7661                GrantUri grantUri = needed.get(i);
7662                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7663                        grantUri, needed.flags, owner);
7664            }
7665        }
7666    }
7667
7668    void grantUriPermissionFromIntentLocked(int callingUid,
7669            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7670        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7671                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7672        if (needed == null) {
7673            return;
7674        }
7675
7676        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7677    }
7678
7679    /**
7680     * @param uri This uri must NOT contain an embedded userId.
7681     * @param userId The userId in which the uri is to be resolved.
7682     */
7683    @Override
7684    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7685            final int modeFlags, int userId) {
7686        enforceNotIsolatedCaller("grantUriPermission");
7687        GrantUri grantUri = new GrantUri(userId, uri, false);
7688        synchronized(this) {
7689            final ProcessRecord r = getRecordForAppLocked(caller);
7690            if (r == null) {
7691                throw new SecurityException("Unable to find app for caller "
7692                        + caller
7693                        + " when granting permission to uri " + grantUri);
7694            }
7695            if (targetPkg == null) {
7696                throw new IllegalArgumentException("null target");
7697            }
7698            if (grantUri == null) {
7699                throw new IllegalArgumentException("null uri");
7700            }
7701
7702            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7703                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7704                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7705                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7706
7707            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7708                    UserHandle.getUserId(r.uid));
7709        }
7710    }
7711
7712    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7713        if (perm.modeFlags == 0) {
7714            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7715                    perm.targetUid);
7716            if (perms != null) {
7717                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7718                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7719
7720                perms.remove(perm.uri);
7721                if (perms.isEmpty()) {
7722                    mGrantedUriPermissions.remove(perm.targetUid);
7723                }
7724            }
7725        }
7726    }
7727
7728    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7729        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7730                "Revoking all granted permissions to " + grantUri);
7731
7732        final IPackageManager pm = AppGlobals.getPackageManager();
7733        final String authority = grantUri.uri.getAuthority();
7734        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7735        if (pi == null) {
7736            Slog.w(TAG, "No content provider found for permission revoke: "
7737                    + grantUri.toSafeString());
7738            return;
7739        }
7740
7741        // Does the caller have this permission on the URI?
7742        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7743            // If they don't have direct access to the URI, then revoke any
7744            // ownerless URI permissions that have been granted to them.
7745            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7746            if (perms != null) {
7747                boolean persistChanged = false;
7748                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7749                    final UriPermission perm = it.next();
7750                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7751                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7752                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7753                                "Revoking non-owned " + perm.targetUid
7754                                + " permission to " + perm.uri);
7755                        persistChanged |= perm.revokeModes(
7756                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7757                        if (perm.modeFlags == 0) {
7758                            it.remove();
7759                        }
7760                    }
7761                }
7762                if (perms.isEmpty()) {
7763                    mGrantedUriPermissions.remove(callingUid);
7764                }
7765                if (persistChanged) {
7766                    schedulePersistUriGrants();
7767                }
7768            }
7769            return;
7770        }
7771
7772        boolean persistChanged = false;
7773
7774        // Go through all of the permissions and remove any that match.
7775        int N = mGrantedUriPermissions.size();
7776        for (int i = 0; i < N; i++) {
7777            final int targetUid = mGrantedUriPermissions.keyAt(i);
7778            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7779
7780            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7781                final UriPermission perm = it.next();
7782                if (perm.uri.sourceUserId == grantUri.sourceUserId
7783                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7784                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7785                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7786                    persistChanged |= perm.revokeModes(
7787                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7788                    if (perm.modeFlags == 0) {
7789                        it.remove();
7790                    }
7791                }
7792            }
7793
7794            if (perms.isEmpty()) {
7795                mGrantedUriPermissions.remove(targetUid);
7796                N--;
7797                i--;
7798            }
7799        }
7800
7801        if (persistChanged) {
7802            schedulePersistUriGrants();
7803        }
7804    }
7805
7806    /**
7807     * @param uri This uri must NOT contain an embedded userId.
7808     * @param userId The userId in which the uri is to be resolved.
7809     */
7810    @Override
7811    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7812            int userId) {
7813        enforceNotIsolatedCaller("revokeUriPermission");
7814        synchronized(this) {
7815            final ProcessRecord r = getRecordForAppLocked(caller);
7816            if (r == null) {
7817                throw new SecurityException("Unable to find app for caller "
7818                        + caller
7819                        + " when revoking permission to uri " + uri);
7820            }
7821            if (uri == null) {
7822                Slog.w(TAG, "revokeUriPermission: null uri");
7823                return;
7824            }
7825
7826            if (!Intent.isAccessUriMode(modeFlags)) {
7827                return;
7828            }
7829
7830            final String authority = uri.getAuthority();
7831            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7832            if (pi == null) {
7833                Slog.w(TAG, "No content provider found for permission revoke: "
7834                        + uri.toSafeString());
7835                return;
7836            }
7837
7838            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7839        }
7840    }
7841
7842    /**
7843     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7844     * given package.
7845     *
7846     * @param packageName Package name to match, or {@code null} to apply to all
7847     *            packages.
7848     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7849     *            to all users.
7850     * @param persistable If persistable grants should be removed.
7851     */
7852    private void removeUriPermissionsForPackageLocked(
7853            String packageName, int userHandle, boolean persistable) {
7854        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7855            throw new IllegalArgumentException("Must narrow by either package or user");
7856        }
7857
7858        boolean persistChanged = false;
7859
7860        int N = mGrantedUriPermissions.size();
7861        for (int i = 0; i < N; i++) {
7862            final int targetUid = mGrantedUriPermissions.keyAt(i);
7863            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7864
7865            // Only inspect grants matching user
7866            if (userHandle == UserHandle.USER_ALL
7867                    || userHandle == UserHandle.getUserId(targetUid)) {
7868                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7869                    final UriPermission perm = it.next();
7870
7871                    // Only inspect grants matching package
7872                    if (packageName == null || perm.sourcePkg.equals(packageName)
7873                            || perm.targetPkg.equals(packageName)) {
7874                        persistChanged |= perm.revokeModes(persistable
7875                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7876
7877                        // Only remove when no modes remain; any persisted grants
7878                        // will keep this alive.
7879                        if (perm.modeFlags == 0) {
7880                            it.remove();
7881                        }
7882                    }
7883                }
7884
7885                if (perms.isEmpty()) {
7886                    mGrantedUriPermissions.remove(targetUid);
7887                    N--;
7888                    i--;
7889                }
7890            }
7891        }
7892
7893        if (persistChanged) {
7894            schedulePersistUriGrants();
7895        }
7896    }
7897
7898    @Override
7899    public IBinder newUriPermissionOwner(String name) {
7900        enforceNotIsolatedCaller("newUriPermissionOwner");
7901        synchronized(this) {
7902            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7903            return owner.getExternalTokenLocked();
7904        }
7905    }
7906
7907    /**
7908     * @param uri This uri must NOT contain an embedded userId.
7909     * @param sourceUserId The userId in which the uri is to be resolved.
7910     * @param targetUserId The userId of the app that receives the grant.
7911     */
7912    @Override
7913    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7914            final int modeFlags, int sourceUserId, int targetUserId) {
7915        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
7916                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
7917                "grantUriPermissionFromOwner", null);
7918        synchronized(this) {
7919            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7920            if (owner == null) {
7921                throw new IllegalArgumentException("Unknown owner: " + token);
7922            }
7923            if (fromUid != Binder.getCallingUid()) {
7924                if (Binder.getCallingUid() != Process.myUid()) {
7925                    // Only system code can grant URI permissions on behalf
7926                    // of other users.
7927                    throw new SecurityException("nice try");
7928                }
7929            }
7930            if (targetPkg == null) {
7931                throw new IllegalArgumentException("null target");
7932            }
7933            if (uri == null) {
7934                throw new IllegalArgumentException("null uri");
7935            }
7936
7937            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7938                    modeFlags, owner, targetUserId);
7939        }
7940    }
7941
7942    /**
7943     * @param uri This uri must NOT contain an embedded userId.
7944     * @param userId The userId in which the uri is to be resolved.
7945     */
7946    @Override
7947    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7948        synchronized(this) {
7949            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7950            if (owner == null) {
7951                throw new IllegalArgumentException("Unknown owner: " + token);
7952            }
7953
7954            if (uri == null) {
7955                owner.removeUriPermissionsLocked(mode);
7956            } else {
7957                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7958            }
7959        }
7960    }
7961
7962    private void schedulePersistUriGrants() {
7963        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7964            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7965                    10 * DateUtils.SECOND_IN_MILLIS);
7966        }
7967    }
7968
7969    private void writeGrantedUriPermissions() {
7970        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7971
7972        // Snapshot permissions so we can persist without lock
7973        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7974        synchronized (this) {
7975            final int size = mGrantedUriPermissions.size();
7976            for (int i = 0; i < size; i++) {
7977                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7978                for (UriPermission perm : perms.values()) {
7979                    if (perm.persistedModeFlags != 0) {
7980                        persist.add(perm.snapshot());
7981                    }
7982                }
7983            }
7984        }
7985
7986        FileOutputStream fos = null;
7987        try {
7988            fos = mGrantFile.startWrite();
7989
7990            XmlSerializer out = new FastXmlSerializer();
7991            out.setOutput(fos, StandardCharsets.UTF_8.name());
7992            out.startDocument(null, true);
7993            out.startTag(null, TAG_URI_GRANTS);
7994            for (UriPermission.Snapshot perm : persist) {
7995                out.startTag(null, TAG_URI_GRANT);
7996                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7997                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7998                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7999                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8000                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8001                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8002                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8003                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8004                out.endTag(null, TAG_URI_GRANT);
8005            }
8006            out.endTag(null, TAG_URI_GRANTS);
8007            out.endDocument();
8008
8009            mGrantFile.finishWrite(fos);
8010        } catch (IOException e) {
8011            if (fos != null) {
8012                mGrantFile.failWrite(fos);
8013            }
8014        }
8015    }
8016
8017    private void readGrantedUriPermissionsLocked() {
8018        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8019
8020        final long now = System.currentTimeMillis();
8021
8022        FileInputStream fis = null;
8023        try {
8024            fis = mGrantFile.openRead();
8025            final XmlPullParser in = Xml.newPullParser();
8026            in.setInput(fis, StandardCharsets.UTF_8.name());
8027
8028            int type;
8029            while ((type = in.next()) != END_DOCUMENT) {
8030                final String tag = in.getName();
8031                if (type == START_TAG) {
8032                    if (TAG_URI_GRANT.equals(tag)) {
8033                        final int sourceUserId;
8034                        final int targetUserId;
8035                        final int userHandle = readIntAttribute(in,
8036                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8037                        if (userHandle != UserHandle.USER_NULL) {
8038                            // For backwards compatibility.
8039                            sourceUserId = userHandle;
8040                            targetUserId = userHandle;
8041                        } else {
8042                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8043                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8044                        }
8045                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8046                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8047                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8048                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8049                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8050                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8051
8052                        // Sanity check that provider still belongs to source package
8053                        final ProviderInfo pi = getProviderInfoLocked(
8054                                uri.getAuthority(), sourceUserId);
8055                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8056                            int targetUid = -1;
8057                            try {
8058                                targetUid = AppGlobals.getPackageManager()
8059                                        .getPackageUid(targetPkg, targetUserId);
8060                            } catch (RemoteException e) {
8061                            }
8062                            if (targetUid != -1) {
8063                                final UriPermission perm = findOrCreateUriPermissionLocked(
8064                                        sourcePkg, targetPkg, targetUid,
8065                                        new GrantUri(sourceUserId, uri, prefix));
8066                                perm.initPersistedModes(modeFlags, createdTime);
8067                            }
8068                        } else {
8069                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8070                                    + " but instead found " + pi);
8071                        }
8072                    }
8073                }
8074            }
8075        } catch (FileNotFoundException e) {
8076            // Missing grants is okay
8077        } catch (IOException e) {
8078            Slog.wtf(TAG, "Failed reading Uri grants", e);
8079        } catch (XmlPullParserException e) {
8080            Slog.wtf(TAG, "Failed reading Uri grants", e);
8081        } finally {
8082            IoUtils.closeQuietly(fis);
8083        }
8084    }
8085
8086    /**
8087     * @param uri This uri must NOT contain an embedded userId.
8088     * @param userId The userId in which the uri is to be resolved.
8089     */
8090    @Override
8091    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8092        enforceNotIsolatedCaller("takePersistableUriPermission");
8093
8094        Preconditions.checkFlagsArgument(modeFlags,
8095                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8096
8097        synchronized (this) {
8098            final int callingUid = Binder.getCallingUid();
8099            boolean persistChanged = false;
8100            GrantUri grantUri = new GrantUri(userId, uri, false);
8101
8102            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8103                    new GrantUri(userId, uri, false));
8104            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8105                    new GrantUri(userId, uri, true));
8106
8107            final boolean exactValid = (exactPerm != null)
8108                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8109            final boolean prefixValid = (prefixPerm != null)
8110                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8111
8112            if (!(exactValid || prefixValid)) {
8113                throw new SecurityException("No persistable permission grants found for UID "
8114                        + callingUid + " and Uri " + grantUri.toSafeString());
8115            }
8116
8117            if (exactValid) {
8118                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8119            }
8120            if (prefixValid) {
8121                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8122            }
8123
8124            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8125
8126            if (persistChanged) {
8127                schedulePersistUriGrants();
8128            }
8129        }
8130    }
8131
8132    /**
8133     * @param uri This uri must NOT contain an embedded userId.
8134     * @param userId The userId in which the uri is to be resolved.
8135     */
8136    @Override
8137    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8138        enforceNotIsolatedCaller("releasePersistableUriPermission");
8139
8140        Preconditions.checkFlagsArgument(modeFlags,
8141                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8142
8143        synchronized (this) {
8144            final int callingUid = Binder.getCallingUid();
8145            boolean persistChanged = false;
8146
8147            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8148                    new GrantUri(userId, uri, false));
8149            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8150                    new GrantUri(userId, uri, true));
8151            if (exactPerm == null && prefixPerm == null) {
8152                throw new SecurityException("No permission grants found for UID " + callingUid
8153                        + " and Uri " + uri.toSafeString());
8154            }
8155
8156            if (exactPerm != null) {
8157                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8158                removeUriPermissionIfNeededLocked(exactPerm);
8159            }
8160            if (prefixPerm != null) {
8161                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8162                removeUriPermissionIfNeededLocked(prefixPerm);
8163            }
8164
8165            if (persistChanged) {
8166                schedulePersistUriGrants();
8167            }
8168        }
8169    }
8170
8171    /**
8172     * Prune any older {@link UriPermission} for the given UID until outstanding
8173     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8174     *
8175     * @return if any mutations occured that require persisting.
8176     */
8177    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8178        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8179        if (perms == null) return false;
8180        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8181
8182        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8183        for (UriPermission perm : perms.values()) {
8184            if (perm.persistedModeFlags != 0) {
8185                persisted.add(perm);
8186            }
8187        }
8188
8189        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8190        if (trimCount <= 0) return false;
8191
8192        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8193        for (int i = 0; i < trimCount; i++) {
8194            final UriPermission perm = persisted.get(i);
8195
8196            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8197                    "Trimming grant created at " + perm.persistedCreateTime);
8198
8199            perm.releasePersistableModes(~0);
8200            removeUriPermissionIfNeededLocked(perm);
8201        }
8202
8203        return true;
8204    }
8205
8206    @Override
8207    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8208            String packageName, boolean incoming) {
8209        enforceNotIsolatedCaller("getPersistedUriPermissions");
8210        Preconditions.checkNotNull(packageName, "packageName");
8211
8212        final int callingUid = Binder.getCallingUid();
8213        final IPackageManager pm = AppGlobals.getPackageManager();
8214        try {
8215            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8216            if (packageUid != callingUid) {
8217                throw new SecurityException(
8218                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8219            }
8220        } catch (RemoteException e) {
8221            throw new SecurityException("Failed to verify package name ownership");
8222        }
8223
8224        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8225        synchronized (this) {
8226            if (incoming) {
8227                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8228                        callingUid);
8229                if (perms == null) {
8230                    Slog.w(TAG, "No permission grants found for " + packageName);
8231                } else {
8232                    for (UriPermission perm : perms.values()) {
8233                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8234                            result.add(perm.buildPersistedPublicApiObject());
8235                        }
8236                    }
8237                }
8238            } else {
8239                final int size = mGrantedUriPermissions.size();
8240                for (int i = 0; i < size; i++) {
8241                    final ArrayMap<GrantUri, UriPermission> perms =
8242                            mGrantedUriPermissions.valueAt(i);
8243                    for (UriPermission perm : perms.values()) {
8244                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8245                            result.add(perm.buildPersistedPublicApiObject());
8246                        }
8247                    }
8248                }
8249            }
8250        }
8251        return new ParceledListSlice<android.content.UriPermission>(result);
8252    }
8253
8254    @Override
8255    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8256        synchronized (this) {
8257            ProcessRecord app =
8258                who != null ? getRecordForAppLocked(who) : null;
8259            if (app == null) return;
8260
8261            Message msg = Message.obtain();
8262            msg.what = WAIT_FOR_DEBUGGER_MSG;
8263            msg.obj = app;
8264            msg.arg1 = waiting ? 1 : 0;
8265            mUiHandler.sendMessage(msg);
8266        }
8267    }
8268
8269    @Override
8270    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8271        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8272        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8273        outInfo.availMem = Process.getFreeMemory();
8274        outInfo.totalMem = Process.getTotalMemory();
8275        outInfo.threshold = homeAppMem;
8276        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8277        outInfo.hiddenAppThreshold = cachedAppMem;
8278        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8279                ProcessList.SERVICE_ADJ);
8280        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8281                ProcessList.VISIBLE_APP_ADJ);
8282        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8283                ProcessList.FOREGROUND_APP_ADJ);
8284    }
8285
8286    // =========================================================
8287    // TASK MANAGEMENT
8288    // =========================================================
8289
8290    @Override
8291    public List<IAppTask> getAppTasks(String callingPackage) {
8292        int callingUid = Binder.getCallingUid();
8293        long ident = Binder.clearCallingIdentity();
8294
8295        synchronized(this) {
8296            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8297            try {
8298                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8299
8300                final int N = mRecentTasks.size();
8301                for (int i = 0; i < N; i++) {
8302                    TaskRecord tr = mRecentTasks.get(i);
8303                    // Skip tasks that do not match the caller.  We don't need to verify
8304                    // callingPackage, because we are also limiting to callingUid and know
8305                    // that will limit to the correct security sandbox.
8306                    if (tr.effectiveUid != callingUid) {
8307                        continue;
8308                    }
8309                    Intent intent = tr.getBaseIntent();
8310                    if (intent == null ||
8311                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8312                        continue;
8313                    }
8314                    ActivityManager.RecentTaskInfo taskInfo =
8315                            createRecentTaskInfoFromTaskRecord(tr);
8316                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8317                    list.add(taskImpl);
8318                }
8319            } finally {
8320                Binder.restoreCallingIdentity(ident);
8321            }
8322            return list;
8323        }
8324    }
8325
8326    @Override
8327    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8328        final int callingUid = Binder.getCallingUid();
8329        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8330
8331        synchronized(this) {
8332            if (DEBUG_ALL) Slog.v(
8333                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8334
8335            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8336                    callingUid);
8337
8338            // TODO: Improve with MRU list from all ActivityStacks.
8339            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8340        }
8341
8342        return list;
8343    }
8344
8345    /**
8346     * Creates a new RecentTaskInfo from a TaskRecord.
8347     */
8348    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8349        // Update the task description to reflect any changes in the task stack
8350        tr.updateTaskDescription();
8351
8352        // Compose the recent task info
8353        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8354        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8355        rti.persistentId = tr.taskId;
8356        rti.baseIntent = new Intent(tr.getBaseIntent());
8357        rti.origActivity = tr.origActivity;
8358        rti.realActivity = tr.realActivity;
8359        rti.description = tr.lastDescription;
8360        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8361        rti.userId = tr.userId;
8362        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8363        rti.firstActiveTime = tr.firstActiveTime;
8364        rti.lastActiveTime = tr.lastActiveTime;
8365        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8366        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8367        rti.numActivities = 0;
8368        if (tr.mBounds != null) {
8369            rti.bounds = new Rect(tr.mBounds);
8370        }
8371
8372        ActivityRecord base = null;
8373        ActivityRecord top = null;
8374        ActivityRecord tmp;
8375
8376        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8377            tmp = tr.mActivities.get(i);
8378            if (tmp.finishing) {
8379                continue;
8380            }
8381            base = tmp;
8382            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8383                top = base;
8384            }
8385            rti.numActivities++;
8386        }
8387
8388        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8389        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8390
8391        return rti;
8392    }
8393
8394    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8395        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8396                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8397        if (!allowed) {
8398            if (checkPermission(android.Manifest.permission.GET_TASKS,
8399                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8400                // Temporary compatibility: some existing apps on the system image may
8401                // still be requesting the old permission and not switched to the new
8402                // one; if so, we'll still allow them full access.  This means we need
8403                // to see if they are holding the old permission and are a system app.
8404                try {
8405                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8406                        allowed = true;
8407                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8408                                + " is using old GET_TASKS but privileged; allowing");
8409                    }
8410                } catch (RemoteException e) {
8411                }
8412            }
8413        }
8414        if (!allowed) {
8415            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8416                    + " does not hold REAL_GET_TASKS; limiting output");
8417        }
8418        return allowed;
8419    }
8420
8421    @Override
8422    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8423        final int callingUid = Binder.getCallingUid();
8424        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8425                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8426
8427        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8428        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8429        synchronized (this) {
8430            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8431                    callingUid);
8432            final boolean detailed = checkCallingPermission(
8433                    android.Manifest.permission.GET_DETAILED_TASKS)
8434                    == PackageManager.PERMISSION_GRANTED;
8435
8436            final int recentsCount = mRecentTasks.size();
8437            ArrayList<ActivityManager.RecentTaskInfo> res =
8438                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8439
8440            final Set<Integer> includedUsers;
8441            if (includeProfiles) {
8442                includedUsers = mUserController.getProfileIds(userId);
8443            } else {
8444                includedUsers = new HashSet<>();
8445            }
8446            includedUsers.add(Integer.valueOf(userId));
8447
8448            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8449                TaskRecord tr = mRecentTasks.get(i);
8450                // Only add calling user or related users recent tasks
8451                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8452                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8453                    continue;
8454                }
8455
8456                // Return the entry if desired by the caller.  We always return
8457                // the first entry, because callers always expect this to be the
8458                // foreground app.  We may filter others if the caller has
8459                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8460                // we should exclude the entry.
8461
8462                if (i == 0
8463                        || withExcluded
8464                        || (tr.intent == null)
8465                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8466                                == 0)) {
8467                    if (!allowed) {
8468                        // If the caller doesn't have the GET_TASKS permission, then only
8469                        // allow them to see a small subset of tasks -- their own and home.
8470                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8471                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8472                            continue;
8473                        }
8474                    }
8475                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8476                        if (tr.stack != null && tr.stack.isHomeStack()) {
8477                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8478                                    "Skipping, home stack task: " + tr);
8479                            continue;
8480                        }
8481                    }
8482                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8483                        // Don't include auto remove tasks that are finished or finishing.
8484                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8485                                "Skipping, auto-remove without activity: " + tr);
8486                        continue;
8487                    }
8488                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8489                            && !tr.isAvailable) {
8490                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8491                                "Skipping, unavail real act: " + tr);
8492                        continue;
8493                    }
8494
8495                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8496                    if (!detailed) {
8497                        rti.baseIntent.replaceExtras((Bundle)null);
8498                    }
8499
8500                    res.add(rti);
8501                    maxNum--;
8502                }
8503            }
8504            return res;
8505        }
8506    }
8507
8508    @Override
8509    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8510        synchronized (this) {
8511            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8512                    "getTaskThumbnail()");
8513            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8514                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8515            if (tr != null) {
8516                return tr.getTaskThumbnailLocked();
8517            }
8518        }
8519        return null;
8520    }
8521
8522    @Override
8523    public int addAppTask(IBinder activityToken, Intent intent,
8524            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8525        final int callingUid = Binder.getCallingUid();
8526        final long callingIdent = Binder.clearCallingIdentity();
8527
8528        try {
8529            synchronized (this) {
8530                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8531                if (r == null) {
8532                    throw new IllegalArgumentException("Activity does not exist; token="
8533                            + activityToken);
8534                }
8535                ComponentName comp = intent.getComponent();
8536                if (comp == null) {
8537                    throw new IllegalArgumentException("Intent " + intent
8538                            + " must specify explicit component");
8539                }
8540                if (thumbnail.getWidth() != mThumbnailWidth
8541                        || thumbnail.getHeight() != mThumbnailHeight) {
8542                    throw new IllegalArgumentException("Bad thumbnail size: got "
8543                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8544                            + mThumbnailWidth + "x" + mThumbnailHeight);
8545                }
8546                if (intent.getSelector() != null) {
8547                    intent.setSelector(null);
8548                }
8549                if (intent.getSourceBounds() != null) {
8550                    intent.setSourceBounds(null);
8551                }
8552                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8553                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8554                        // The caller has added this as an auto-remove task...  that makes no
8555                        // sense, so turn off auto-remove.
8556                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8557                    }
8558                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8559                    // Must be a new task.
8560                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8561                }
8562                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8563                    mLastAddedTaskActivity = null;
8564                }
8565                ActivityInfo ainfo = mLastAddedTaskActivity;
8566                if (ainfo == null) {
8567                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8568                            comp, 0, UserHandle.getUserId(callingUid));
8569                    if (ainfo.applicationInfo.uid != callingUid) {
8570                        throw new SecurityException(
8571                                "Can't add task for another application: target uid="
8572                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8573                    }
8574                }
8575
8576                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8577                        intent, description);
8578
8579                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8580                if (trimIdx >= 0) {
8581                    // If this would have caused a trim, then we'll abort because that
8582                    // means it would be added at the end of the list but then just removed.
8583                    return INVALID_TASK_ID;
8584                }
8585
8586                final int N = mRecentTasks.size();
8587                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8588                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8589                    tr.removedFromRecents();
8590                }
8591
8592                task.inRecents = true;
8593                mRecentTasks.add(task);
8594                r.task.stack.addTask(task, false, false);
8595
8596                task.setLastThumbnail(thumbnail);
8597                task.freeLastThumbnail();
8598
8599                return task.taskId;
8600            }
8601        } finally {
8602            Binder.restoreCallingIdentity(callingIdent);
8603        }
8604    }
8605
8606    @Override
8607    public Point getAppTaskThumbnailSize() {
8608        synchronized (this) {
8609            return new Point(mThumbnailWidth,  mThumbnailHeight);
8610        }
8611    }
8612
8613    @Override
8614    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8615        synchronized (this) {
8616            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8617            if (r != null) {
8618                r.setTaskDescription(td);
8619                r.task.updateTaskDescription();
8620            }
8621        }
8622    }
8623
8624    @Override
8625    public void setTaskResizeable(int taskId, boolean resizeable) {
8626        synchronized (this) {
8627            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8628                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8629            if (task == null) {
8630                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8631                return;
8632            }
8633            if (task.mResizeable != resizeable) {
8634                task.mResizeable = resizeable;
8635                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8636                mStackSupervisor.resumeTopActivitiesLocked();
8637            }
8638        }
8639    }
8640
8641    @Override
8642    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8643        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8644                "resizeTask()");
8645        long ident = Binder.clearCallingIdentity();
8646        try {
8647            synchronized (this) {
8648                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8649                if (task == null) {
8650                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8651                    return;
8652                }
8653                // Place the task in the right stack if it isn't there already based on
8654                // the requested bounds.
8655                // The stack transition logic is:
8656                // - a null bounds on a freeform task moves that task to fullscreen
8657                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8658                //   that task to freeform
8659                // - otherwise the task is not moved
8660                int stackId = task.stack.mStackId;
8661                if (!StackId.isTaskResizeAllowed(stackId)) {
8662                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8663                }
8664                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8665                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8666                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8667                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8668                }
8669                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8670                if (stackId != task.stack.mStackId) {
8671                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8672                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8673                    preserveWindow = false;
8674                }
8675
8676                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8677            }
8678        } finally {
8679            Binder.restoreCallingIdentity(ident);
8680        }
8681    }
8682
8683    @Override
8684    public Rect getTaskBounds(int taskId) {
8685        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8686                "getTaskBounds()");
8687        long ident = Binder.clearCallingIdentity();
8688        Rect rect = new Rect();
8689        try {
8690            synchronized (this) {
8691                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8692                if (task == null) {
8693                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8694                    return rect;
8695                }
8696                mWindowManager.getTaskBounds(task.taskId, rect);
8697            }
8698        } finally {
8699            Binder.restoreCallingIdentity(ident);
8700        }
8701        return rect;
8702    }
8703
8704    @Override
8705    public Bitmap getTaskDescriptionIcon(String filename) {
8706        if (!FileUtils.isValidExtFilename(filename)
8707                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8708            throw new IllegalArgumentException("Bad filename: " + filename);
8709        }
8710        return mTaskPersister.getTaskDescriptionIcon(filename);
8711    }
8712
8713    @Override
8714    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8715            throws RemoteException {
8716        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8717                opts.getCustomInPlaceResId() == 0) {
8718            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8719                    "with valid animation");
8720        }
8721        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8722        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8723                opts.getCustomInPlaceResId());
8724        mWindowManager.executeAppTransition();
8725    }
8726
8727    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
8728            boolean removeFromRecents) {
8729        if (removeFromRecents) {
8730            mRecentTasks.remove(tr);
8731            tr.removedFromRecents();
8732        }
8733        ComponentName component = tr.getBaseIntent().getComponent();
8734        if (component == null) {
8735            Slog.w(TAG, "No component for base intent of task: " + tr);
8736            return;
8737        }
8738
8739        // Find any running services associated with this app and stop if needed.
8740        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8741
8742        if (!killProcess) {
8743            return;
8744        }
8745
8746        // Determine if the process(es) for this task should be killed.
8747        final String pkg = component.getPackageName();
8748        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8749        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8750        for (int i = 0; i < pmap.size(); i++) {
8751
8752            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8753            for (int j = 0; j < uids.size(); j++) {
8754                ProcessRecord proc = uids.valueAt(j);
8755                if (proc.userId != tr.userId) {
8756                    // Don't kill process for a different user.
8757                    continue;
8758                }
8759                if (proc == mHomeProcess) {
8760                    // Don't kill the home process along with tasks from the same package.
8761                    continue;
8762                }
8763                if (!proc.pkgList.containsKey(pkg)) {
8764                    // Don't kill process that is not associated with this task.
8765                    continue;
8766                }
8767
8768                for (int k = 0; k < proc.activities.size(); k++) {
8769                    TaskRecord otherTask = proc.activities.get(k).task;
8770                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8771                        // Don't kill process(es) that has an activity in a different task that is
8772                        // also in recents.
8773                        return;
8774                    }
8775                }
8776
8777                if (proc.foregroundServices) {
8778                    // Don't kill process(es) with foreground service.
8779                    return;
8780                }
8781
8782                // Add process to kill list.
8783                procsToKill.add(proc);
8784            }
8785        }
8786
8787        // Kill the running processes.
8788        for (int i = 0; i < procsToKill.size(); i++) {
8789            ProcessRecord pr = procsToKill.get(i);
8790            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8791                    && pr.curReceiver == null) {
8792                pr.kill("remove task", true);
8793            } else {
8794                // We delay killing processes that are not in the background or running a receiver.
8795                pr.waitingToKill = "remove task";
8796            }
8797        }
8798    }
8799
8800    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8801        // Remove all tasks with activities in the specified package from the list of recent tasks
8802        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8803            TaskRecord tr = mRecentTasks.get(i);
8804            if (tr.userId != userId) continue;
8805
8806            ComponentName cn = tr.intent.getComponent();
8807            if (cn != null && cn.getPackageName().equals(packageName)) {
8808                // If the package name matches, remove the task.
8809                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
8810            }
8811        }
8812    }
8813
8814    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8815            int userId) {
8816
8817        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8818            TaskRecord tr = mRecentTasks.get(i);
8819            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8820                continue;
8821            }
8822
8823            ComponentName cn = tr.intent.getComponent();
8824            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8825                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8826            if (sameComponent) {
8827                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
8828            }
8829        }
8830    }
8831
8832    /**
8833     * Removes the task with the specified task id.
8834     *
8835     * @param taskId Identifier of the task to be removed.
8836     * @param killProcess Kill any process associated with the task if possible.
8837     * @param removeFromRecents Whether to also remove the task from recents.
8838     * @return Returns true if the given task was found and removed.
8839     */
8840    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
8841            boolean removeFromRecents) {
8842        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8843                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8844        if (tr != null) {
8845            tr.removeTaskActivitiesLocked();
8846            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
8847            if (tr.isPersistable) {
8848                notifyTaskPersisterLocked(null, true);
8849            }
8850            return true;
8851        }
8852        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8853        return false;
8854    }
8855
8856    @Override
8857    public boolean removeTask(int taskId) {
8858        synchronized (this) {
8859            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8860                    "removeTask()");
8861            long ident = Binder.clearCallingIdentity();
8862            try {
8863                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
8864            } finally {
8865                Binder.restoreCallingIdentity(ident);
8866            }
8867        }
8868    }
8869
8870    /**
8871     * TODO: Add mController hook
8872     */
8873    @Override
8874    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
8875        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8876
8877        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8878        synchronized(this) {
8879            moveTaskToFrontLocked(taskId, flags, bOptions);
8880        }
8881    }
8882
8883    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
8884        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
8885
8886        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8887                Binder.getCallingUid(), -1, -1, "Task to front")) {
8888            ActivityOptions.abort(options);
8889            return;
8890        }
8891        final long origId = Binder.clearCallingIdentity();
8892        try {
8893            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8894            if (task == null) {
8895                Slog.d(TAG, "Could not find task for id: "+ taskId);
8896                return;
8897            }
8898            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8899                mStackSupervisor.showLockTaskToast();
8900                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8901                return;
8902            }
8903            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8904            if (prev != null && prev.isRecentsActivity()) {
8905                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8906            }
8907            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8908        } finally {
8909            Binder.restoreCallingIdentity(origId);
8910        }
8911        ActivityOptions.abort(options);
8912    }
8913
8914    /**
8915     * Moves an activity, and all of the other activities within the same task, to the bottom
8916     * of the history stack.  The activity's order within the task is unchanged.
8917     *
8918     * @param token A reference to the activity we wish to move
8919     * @param nonRoot If false then this only works if the activity is the root
8920     *                of a task; if true it will work for any activity in a task.
8921     * @return Returns true if the move completed, false if not.
8922     */
8923    @Override
8924    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8925        enforceNotIsolatedCaller("moveActivityTaskToBack");
8926        synchronized(this) {
8927            final long origId = Binder.clearCallingIdentity();
8928            try {
8929                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8930                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8931                if (task != null) {
8932                    if (mStackSupervisor.isLockedTask(task)) {
8933                        mStackSupervisor.showLockTaskToast();
8934                        return false;
8935                    }
8936                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8937                }
8938            } finally {
8939                Binder.restoreCallingIdentity(origId);
8940            }
8941        }
8942        return false;
8943    }
8944
8945    @Override
8946    public void moveTaskBackwards(int task) {
8947        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8948                "moveTaskBackwards()");
8949
8950        synchronized(this) {
8951            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8952                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8953                return;
8954            }
8955            final long origId = Binder.clearCallingIdentity();
8956            moveTaskBackwardsLocked(task);
8957            Binder.restoreCallingIdentity(origId);
8958        }
8959    }
8960
8961    private final void moveTaskBackwardsLocked(int task) {
8962        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8963    }
8964
8965    @Override
8966    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8967            IActivityContainerCallback callback) throws RemoteException {
8968        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8969                "createActivityContainer()");
8970        synchronized (this) {
8971            if (parentActivityToken == null) {
8972                throw new IllegalArgumentException("parent token must not be null");
8973            }
8974            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8975            if (r == null) {
8976                return null;
8977            }
8978            if (callback == null) {
8979                throw new IllegalArgumentException("callback must not be null");
8980            }
8981            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8982        }
8983    }
8984
8985    @Override
8986    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8987        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8988                "deleteActivityContainer()");
8989        synchronized (this) {
8990            mStackSupervisor.deleteActivityContainer(container);
8991        }
8992    }
8993
8994    @Override
8995    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8996        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8997                "createStackOnDisplay()");
8998        synchronized (this) {
8999            final int stackId = mStackSupervisor.getNextStackId();
9000            final ActivityStack stack =
9001                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9002            if (stack == null) {
9003                return null;
9004            }
9005            return stack.mActivityContainer;
9006        }
9007    }
9008
9009    @Override
9010    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9011        synchronized (this) {
9012            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9013            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9014                return stack.mActivityContainer.getDisplayId();
9015            }
9016            return Display.DEFAULT_DISPLAY;
9017        }
9018    }
9019
9020    @Override
9021    public int getActivityStackId(IBinder token) throws RemoteException {
9022        synchronized (this) {
9023            ActivityStack stack = ActivityRecord.getStackLocked(token);
9024            if (stack == null) {
9025                return INVALID_STACK_ID;
9026            }
9027            return stack.mStackId;
9028        }
9029    }
9030
9031    @Override
9032    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9033        if (stackId == HOME_STACK_ID) {
9034            throw new IllegalArgumentException(
9035                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9036        }
9037        synchronized (this) {
9038            long ident = Binder.clearCallingIdentity();
9039            try {
9040                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9041                if (r == null) {
9042                    throw new IllegalArgumentException(
9043                            "moveActivityToStack: No activity record matching token=" + token);
9044                }
9045                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9046                        + " to stackId=" + stackId);
9047                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9048                        "moveActivityToStack");
9049            } finally {
9050                Binder.restoreCallingIdentity(ident);
9051            }
9052        }
9053    }
9054
9055    @Override
9056    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9057        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9058                "moveTaskToStack()");
9059        if (stackId == HOME_STACK_ID) {
9060            throw new IllegalArgumentException(
9061                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9062        }
9063        synchronized (this) {
9064            long ident = Binder.clearCallingIdentity();
9065            try {
9066                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9067                        + " to stackId=" + stackId + " toTop=" + toTop);
9068                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9069                        "moveTaskToStack");
9070            } finally {
9071                Binder.restoreCallingIdentity(ident);
9072            }
9073        }
9074    }
9075
9076    /**
9077     * Moves the input task to the docked stack.
9078     *
9079     * @param taskId Id of task to move.
9080     * @param createMode The mode the docked stack should be created in if it doesn't exist
9081     *                   already. See
9082     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9083     *                   and
9084     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9085     * @param toTop If the task and stack should be moved to the top.
9086     */
9087    @Override
9088    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) {
9089        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9090                "moveTaskToDockedStack()");
9091        synchronized (this) {
9092            long ident = Binder.clearCallingIdentity();
9093            try {
9094                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9095                        + " to createMode=" + createMode + " toTop=" + toTop);
9096                mWindowManager.setDockedStackCreateMode(createMode);
9097                mStackSupervisor.moveTaskToStackLocked(
9098                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack");
9099            } finally {
9100                Binder.restoreCallingIdentity(ident);
9101            }
9102        }
9103    }
9104
9105    /**
9106     * Moves the top activity in the input stackId to the pinned stack.
9107     *
9108     * @param stackId Id of stack to move the top activity to pinned stack.
9109     * @param bounds Bounds to use for pinned stack.
9110     *
9111     * @return True if the top activity of the input stack was successfully moved to the pinned
9112     *          stack.
9113     */
9114    @Override
9115    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9116        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9117                "moveTopActivityToPinnedStack()");
9118        synchronized (this) {
9119            long ident = Binder.clearCallingIdentity();
9120            try {
9121                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9122            } finally {
9123                Binder.restoreCallingIdentity(ident);
9124            }
9125        }
9126    }
9127
9128    @Override
9129    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9130        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9131                "resizeStack()");
9132        long ident = Binder.clearCallingIdentity();
9133        try {
9134            synchronized (this) {
9135                mStackSupervisor.resizeStackLocked(
9136                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9137            }
9138        } finally {
9139            Binder.restoreCallingIdentity(ident);
9140        }
9141    }
9142
9143    @Override
9144    public void positionTaskInStack(int taskId, int stackId, int position) {
9145        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9146                "positionTaskInStack()");
9147        if (stackId == HOME_STACK_ID) {
9148            throw new IllegalArgumentException(
9149                    "positionTaskInStack: Attempt to change the position of task "
9150                    + taskId + " in/to home stack");
9151        }
9152        synchronized (this) {
9153            long ident = Binder.clearCallingIdentity();
9154            try {
9155                if (DEBUG_STACK) Slog.d(TAG_STACK,
9156                        "positionTaskInStack: positioning task=" + taskId
9157                        + " in stackId=" + stackId + " at position=" + position);
9158                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9159            } finally {
9160                Binder.restoreCallingIdentity(ident);
9161            }
9162        }
9163    }
9164
9165    @Override
9166    public List<StackInfo> getAllStackInfos() {
9167        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9168                "getAllStackInfos()");
9169        long ident = Binder.clearCallingIdentity();
9170        try {
9171            synchronized (this) {
9172                return mStackSupervisor.getAllStackInfosLocked();
9173            }
9174        } finally {
9175            Binder.restoreCallingIdentity(ident);
9176        }
9177    }
9178
9179    @Override
9180    public StackInfo getStackInfo(int stackId) {
9181        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9182                "getStackInfo()");
9183        long ident = Binder.clearCallingIdentity();
9184        try {
9185            synchronized (this) {
9186                return mStackSupervisor.getStackInfoLocked(stackId);
9187            }
9188        } finally {
9189            Binder.restoreCallingIdentity(ident);
9190        }
9191    }
9192
9193    @Override
9194    public boolean isInHomeStack(int taskId) {
9195        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9196                "getStackInfo()");
9197        long ident = Binder.clearCallingIdentity();
9198        try {
9199            synchronized (this) {
9200                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9201                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9202                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9203            }
9204        } finally {
9205            Binder.restoreCallingIdentity(ident);
9206        }
9207    }
9208
9209    @Override
9210    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9211        synchronized(this) {
9212            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9213        }
9214    }
9215
9216    @Override
9217    public void updateDeviceOwner(String packageName) {
9218        final int callingUid = Binder.getCallingUid();
9219        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9220            throw new SecurityException("updateDeviceOwner called from non-system process");
9221        }
9222        synchronized (this) {
9223            mDeviceOwnerName = packageName;
9224        }
9225    }
9226
9227    @Override
9228    public void updateLockTaskPackages(int userId, String[] packages) {
9229        final int callingUid = Binder.getCallingUid();
9230        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9231            throw new SecurityException("updateLockTaskPackage called from non-system process");
9232        }
9233        synchronized (this) {
9234            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9235                    Arrays.toString(packages));
9236            mLockTaskPackages.put(userId, packages);
9237            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9238        }
9239    }
9240
9241
9242    void startLockTaskModeLocked(TaskRecord task) {
9243        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9244        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9245            return;
9246        }
9247
9248        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9249        // is initiated by system after the pinning request was shown and locked mode is initiated
9250        // by an authorized app directly
9251        final int callingUid = Binder.getCallingUid();
9252        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9253        long ident = Binder.clearCallingIdentity();
9254        try {
9255            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9256            if (!isSystemInitiated) {
9257                task.mLockTaskUid = callingUid;
9258                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9259                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9260                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9261                    StatusBarManagerInternal statusBarManager =
9262                            LocalServices.getService(StatusBarManagerInternal.class);
9263                    if (statusBarManager != null) {
9264                        statusBarManager.showScreenPinningRequest();
9265                    }
9266                    return;
9267                }
9268
9269                if (stack == null || task != stack.topTask()) {
9270                    throw new IllegalArgumentException("Invalid task, not in foreground");
9271                }
9272            }
9273            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9274                    "Locking fully");
9275            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9276                    ActivityManager.LOCK_TASK_MODE_PINNED :
9277                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9278                    "startLockTask", true);
9279        } finally {
9280            Binder.restoreCallingIdentity(ident);
9281        }
9282    }
9283
9284    @Override
9285    public void startLockTaskMode(int taskId) {
9286        synchronized (this) {
9287            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9288            if (task != null) {
9289                startLockTaskModeLocked(task);
9290            }
9291        }
9292    }
9293
9294    @Override
9295    public void startLockTaskMode(IBinder token) {
9296        synchronized (this) {
9297            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9298            if (r == null) {
9299                return;
9300            }
9301            final TaskRecord task = r.task;
9302            if (task != null) {
9303                startLockTaskModeLocked(task);
9304            }
9305        }
9306    }
9307
9308    @Override
9309    public void startLockTaskModeOnCurrent() throws RemoteException {
9310        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9311                "startLockTaskModeOnCurrent");
9312        long ident = Binder.clearCallingIdentity();
9313        try {
9314            synchronized (this) {
9315                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9316                if (r != null) {
9317                    startLockTaskModeLocked(r.task);
9318                }
9319            }
9320        } finally {
9321            Binder.restoreCallingIdentity(ident);
9322        }
9323    }
9324
9325    @Override
9326    public void stopLockTaskMode() {
9327        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9328        if (lockTask == null) {
9329            // Our work here is done.
9330            return;
9331        }
9332
9333        final int callingUid = Binder.getCallingUid();
9334        final int lockTaskUid = lockTask.mLockTaskUid;
9335        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9336        // It is possible lockTaskMode was started by the system process because
9337        // android:lockTaskMode is set to a locking value in the application manifest instead of
9338        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9339        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9340        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9341                callingUid != lockTaskUid
9342                && (lockTaskUid != 0
9343                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9344            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9345                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9346        }
9347
9348        long ident = Binder.clearCallingIdentity();
9349        try {
9350            Log.d(TAG, "stopLockTaskMode");
9351            // Stop lock task
9352            synchronized (this) {
9353                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9354                        "stopLockTask", true);
9355            }
9356        } finally {
9357            Binder.restoreCallingIdentity(ident);
9358        }
9359    }
9360
9361    @Override
9362    public void stopLockTaskModeOnCurrent() throws RemoteException {
9363        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9364                "stopLockTaskModeOnCurrent");
9365        long ident = Binder.clearCallingIdentity();
9366        try {
9367            stopLockTaskMode();
9368        } finally {
9369            Binder.restoreCallingIdentity(ident);
9370        }
9371    }
9372
9373    @Override
9374    public boolean isInLockTaskMode() {
9375        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9376    }
9377
9378    @Override
9379    public int getLockTaskModeState() {
9380        synchronized (this) {
9381            return mStackSupervisor.getLockTaskModeState();
9382        }
9383    }
9384
9385    @Override
9386    public void showLockTaskEscapeMessage(IBinder token) {
9387        synchronized (this) {
9388            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9389            if (r == null) {
9390                return;
9391            }
9392            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9393        }
9394    }
9395
9396    // =========================================================
9397    // CONTENT PROVIDERS
9398    // =========================================================
9399
9400    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9401        List<ProviderInfo> providers = null;
9402        try {
9403            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9404                queryContentProviders(app.processName, app.uid,
9405                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9406            providers = slice != null ? slice.getList() : null;
9407        } catch (RemoteException ex) {
9408        }
9409        if (DEBUG_MU) Slog.v(TAG_MU,
9410                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9411        int userId = app.userId;
9412        if (providers != null) {
9413            int N = providers.size();
9414            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9415            for (int i=0; i<N; i++) {
9416                ProviderInfo cpi =
9417                    (ProviderInfo)providers.get(i);
9418                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9419                        cpi.name, cpi.flags);
9420                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9421                    // This is a singleton provider, but a user besides the
9422                    // default user is asking to initialize a process it runs
9423                    // in...  well, no, it doesn't actually run in this process,
9424                    // it runs in the process of the default user.  Get rid of it.
9425                    providers.remove(i);
9426                    N--;
9427                    i--;
9428                    continue;
9429                }
9430
9431                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9432                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9433                if (cpr == null) {
9434                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9435                    mProviderMap.putProviderByClass(comp, cpr);
9436                }
9437                if (DEBUG_MU) Slog.v(TAG_MU,
9438                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9439                app.pubProviders.put(cpi.name, cpr);
9440                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9441                    // Don't add this if it is a platform component that is marked
9442                    // to run in multiple processes, because this is actually
9443                    // part of the framework so doesn't make sense to track as a
9444                    // separate apk in the process.
9445                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9446                            mProcessStats);
9447                }
9448                notifyPackageUse(cpi.applicationInfo.packageName);
9449            }
9450        }
9451        return providers;
9452    }
9453
9454    /**
9455     * Check if {@link ProcessRecord} has a possible chance at accessing the
9456     * given {@link ProviderInfo}. Final permission checking is always done
9457     * in {@link ContentProvider}.
9458     */
9459    private final String checkContentProviderPermissionLocked(
9460            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9461        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9462        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9463        boolean checkedGrants = false;
9464        if (checkUser) {
9465            // Looking for cross-user grants before enforcing the typical cross-users permissions
9466            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9467            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9468                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9469                    return null;
9470                }
9471                checkedGrants = true;
9472            }
9473            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9474                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9475            if (userId != tmpTargetUserId) {
9476                // When we actually went to determine the final targer user ID, this ended
9477                // up different than our initial check for the authority.  This is because
9478                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9479                // SELF.  So we need to re-check the grants again.
9480                checkedGrants = false;
9481            }
9482        }
9483        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9484                cpi.applicationInfo.uid, cpi.exported)
9485                == PackageManager.PERMISSION_GRANTED) {
9486            return null;
9487        }
9488        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9489                cpi.applicationInfo.uid, cpi.exported)
9490                == PackageManager.PERMISSION_GRANTED) {
9491            return null;
9492        }
9493
9494        PathPermission[] pps = cpi.pathPermissions;
9495        if (pps != null) {
9496            int i = pps.length;
9497            while (i > 0) {
9498                i--;
9499                PathPermission pp = pps[i];
9500                String pprperm = pp.getReadPermission();
9501                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9502                        cpi.applicationInfo.uid, cpi.exported)
9503                        == PackageManager.PERMISSION_GRANTED) {
9504                    return null;
9505                }
9506                String ppwperm = pp.getWritePermission();
9507                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9508                        cpi.applicationInfo.uid, cpi.exported)
9509                        == PackageManager.PERMISSION_GRANTED) {
9510                    return null;
9511                }
9512            }
9513        }
9514        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9515            return null;
9516        }
9517
9518        String msg;
9519        if (!cpi.exported) {
9520            msg = "Permission Denial: opening provider " + cpi.name
9521                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9522                    + ", uid=" + callingUid + ") that is not exported from uid "
9523                    + cpi.applicationInfo.uid;
9524        } else {
9525            msg = "Permission Denial: opening provider " + cpi.name
9526                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9527                    + ", uid=" + callingUid + ") requires "
9528                    + cpi.readPermission + " or " + cpi.writePermission;
9529        }
9530        Slog.w(TAG, msg);
9531        return msg;
9532    }
9533
9534    /**
9535     * Returns if the ContentProvider has granted a uri to callingUid
9536     */
9537    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9538        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9539        if (perms != null) {
9540            for (int i=perms.size()-1; i>=0; i--) {
9541                GrantUri grantUri = perms.keyAt(i);
9542                if (grantUri.sourceUserId == userId || !checkUser) {
9543                    if (matchesProvider(grantUri.uri, cpi)) {
9544                        return true;
9545                    }
9546                }
9547            }
9548        }
9549        return false;
9550    }
9551
9552    /**
9553     * Returns true if the uri authority is one of the authorities specified in the provider.
9554     */
9555    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9556        String uriAuth = uri.getAuthority();
9557        String cpiAuth = cpi.authority;
9558        if (cpiAuth.indexOf(';') == -1) {
9559            return cpiAuth.equals(uriAuth);
9560        }
9561        String[] cpiAuths = cpiAuth.split(";");
9562        int length = cpiAuths.length;
9563        for (int i = 0; i < length; i++) {
9564            if (cpiAuths[i].equals(uriAuth)) return true;
9565        }
9566        return false;
9567    }
9568
9569    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9570            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9571        if (r != null) {
9572            for (int i=0; i<r.conProviders.size(); i++) {
9573                ContentProviderConnection conn = r.conProviders.get(i);
9574                if (conn.provider == cpr) {
9575                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9576                            "Adding provider requested by "
9577                            + r.processName + " from process "
9578                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9579                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9580                    if (stable) {
9581                        conn.stableCount++;
9582                        conn.numStableIncs++;
9583                    } else {
9584                        conn.unstableCount++;
9585                        conn.numUnstableIncs++;
9586                    }
9587                    return conn;
9588                }
9589            }
9590            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9591            if (stable) {
9592                conn.stableCount = 1;
9593                conn.numStableIncs = 1;
9594            } else {
9595                conn.unstableCount = 1;
9596                conn.numUnstableIncs = 1;
9597            }
9598            cpr.connections.add(conn);
9599            r.conProviders.add(conn);
9600            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9601            return conn;
9602        }
9603        cpr.addExternalProcessHandleLocked(externalProcessToken);
9604        return null;
9605    }
9606
9607    boolean decProviderCountLocked(ContentProviderConnection conn,
9608            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9609        if (conn != null) {
9610            cpr = conn.provider;
9611            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9612                    "Removing provider requested by "
9613                    + conn.client.processName + " from process "
9614                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9615                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9616            if (stable) {
9617                conn.stableCount--;
9618            } else {
9619                conn.unstableCount--;
9620            }
9621            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9622                cpr.connections.remove(conn);
9623                conn.client.conProviders.remove(conn);
9624                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9625                return true;
9626            }
9627            return false;
9628        }
9629        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9630        return false;
9631    }
9632
9633    private void checkTime(long startTime, String where) {
9634        long now = SystemClock.elapsedRealtime();
9635        if ((now-startTime) > 1000) {
9636            // If we are taking more than a second, log about it.
9637            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9638        }
9639    }
9640
9641    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9642            String name, IBinder token, boolean stable, int userId) {
9643        ContentProviderRecord cpr;
9644        ContentProviderConnection conn = null;
9645        ProviderInfo cpi = null;
9646
9647        synchronized(this) {
9648            long startTime = SystemClock.elapsedRealtime();
9649
9650            ProcessRecord r = null;
9651            if (caller != null) {
9652                r = getRecordForAppLocked(caller);
9653                if (r == null) {
9654                    throw new SecurityException(
9655                            "Unable to find app for caller " + caller
9656                          + " (pid=" + Binder.getCallingPid()
9657                          + ") when getting content provider " + name);
9658                }
9659            }
9660
9661            boolean checkCrossUser = true;
9662
9663            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9664
9665            // First check if this content provider has been published...
9666            cpr = mProviderMap.getProviderByName(name, userId);
9667            // If that didn't work, check if it exists for user 0 and then
9668            // verify that it's a singleton provider before using it.
9669            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9670                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9671                if (cpr != null) {
9672                    cpi = cpr.info;
9673                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9674                            cpi.name, cpi.flags)
9675                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9676                        userId = UserHandle.USER_SYSTEM;
9677                        checkCrossUser = false;
9678                    } else {
9679                        cpr = null;
9680                        cpi = null;
9681                    }
9682                }
9683            }
9684
9685            boolean providerRunning = cpr != null;
9686            if (providerRunning) {
9687                cpi = cpr.info;
9688                String msg;
9689                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9690                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9691                        != null) {
9692                    throw new SecurityException(msg);
9693                }
9694                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9695
9696                if (r != null && cpr.canRunHere(r)) {
9697                    // This provider has been published or is in the process
9698                    // of being published...  but it is also allowed to run
9699                    // in the caller's process, so don't make a connection
9700                    // and just let the caller instantiate its own instance.
9701                    ContentProviderHolder holder = cpr.newHolder(null);
9702                    // don't give caller the provider object, it needs
9703                    // to make its own.
9704                    holder.provider = null;
9705                    return holder;
9706                }
9707
9708                final long origId = Binder.clearCallingIdentity();
9709
9710                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9711
9712                // In this case the provider instance already exists, so we can
9713                // return it right away.
9714                conn = incProviderCountLocked(r, cpr, token, stable);
9715                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9716                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9717                        // If this is a perceptible app accessing the provider,
9718                        // make sure to count it as being accessed and thus
9719                        // back up on the LRU list.  This is good because
9720                        // content providers are often expensive to start.
9721                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9722                        updateLruProcessLocked(cpr.proc, false, null);
9723                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9724                    }
9725                }
9726
9727                if (cpr.proc != null) {
9728                    if (false) {
9729                        if (cpr.name.flattenToShortString().equals(
9730                                "com.android.providers.calendar/.CalendarProvider2")) {
9731                            Slog.v(TAG, "****************** KILLING "
9732                                + cpr.name.flattenToShortString());
9733                            Process.killProcess(cpr.proc.pid);
9734                        }
9735                    }
9736                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9737                    boolean success = updateOomAdjLocked(cpr.proc);
9738                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9739                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9740                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9741                    // NOTE: there is still a race here where a signal could be
9742                    // pending on the process even though we managed to update its
9743                    // adj level.  Not sure what to do about this, but at least
9744                    // the race is now smaller.
9745                    if (!success) {
9746                        // Uh oh...  it looks like the provider's process
9747                        // has been killed on us.  We need to wait for a new
9748                        // process to be started, and make sure its death
9749                        // doesn't kill our process.
9750                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9751                                + " is crashing; detaching " + r);
9752                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9753                        checkTime(startTime, "getContentProviderImpl: before appDied");
9754                        appDiedLocked(cpr.proc);
9755                        checkTime(startTime, "getContentProviderImpl: after appDied");
9756                        if (!lastRef) {
9757                            // This wasn't the last ref our process had on
9758                            // the provider...  we have now been killed, bail.
9759                            return null;
9760                        }
9761                        providerRunning = false;
9762                        conn = null;
9763                    }
9764                }
9765
9766                Binder.restoreCallingIdentity(origId);
9767            }
9768
9769            if (!providerRunning) {
9770                try {
9771                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9772                    cpi = AppGlobals.getPackageManager().
9773                        resolveContentProvider(name,
9774                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9775                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9776                } catch (RemoteException ex) {
9777                }
9778                if (cpi == null) {
9779                    return null;
9780                }
9781                // If the provider is a singleton AND
9782                // (it's a call within the same user || the provider is a
9783                // privileged app)
9784                // Then allow connecting to the singleton provider
9785                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9786                        cpi.name, cpi.flags)
9787                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9788                if (singleton) {
9789                    userId = UserHandle.USER_SYSTEM;
9790                }
9791                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9792                checkTime(startTime, "getContentProviderImpl: got app info for user");
9793
9794                String msg;
9795                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9796                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9797                        != null) {
9798                    throw new SecurityException(msg);
9799                }
9800                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9801
9802                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9803                        && !cpi.processName.equals("system")) {
9804                    // If this content provider does not run in the system
9805                    // process, and the system is not yet ready to run other
9806                    // processes, then fail fast instead of hanging.
9807                    throw new IllegalArgumentException(
9808                            "Attempt to launch content provider before system ready");
9809                }
9810
9811                // Make sure that the user who owns this provider is running.  If not,
9812                // we don't want to allow it to run.
9813                if (!mUserController.isUserRunningLocked(userId, false)) {
9814                    Slog.w(TAG, "Unable to launch app "
9815                            + cpi.applicationInfo.packageName + "/"
9816                            + cpi.applicationInfo.uid + " for provider "
9817                            + name + ": user " + userId + " is stopped");
9818                    return null;
9819                }
9820
9821                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9822                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9823                cpr = mProviderMap.getProviderByClass(comp, userId);
9824                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9825                final boolean firstClass = cpr == null;
9826                if (firstClass) {
9827                    final long ident = Binder.clearCallingIdentity();
9828                    try {
9829                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9830                        ApplicationInfo ai =
9831                            AppGlobals.getPackageManager().
9832                                getApplicationInfo(
9833                                        cpi.applicationInfo.packageName,
9834                                        STOCK_PM_FLAGS, userId);
9835                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9836                        if (ai == null) {
9837                            Slog.w(TAG, "No package info for content provider "
9838                                    + cpi.name);
9839                            return null;
9840                        }
9841                        ai = getAppInfoForUser(ai, userId);
9842                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9843                    } catch (RemoteException ex) {
9844                        // pm is in same process, this will never happen.
9845                    } finally {
9846                        Binder.restoreCallingIdentity(ident);
9847                    }
9848                }
9849
9850                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9851
9852                if (r != null && cpr.canRunHere(r)) {
9853                    // If this is a multiprocess provider, then just return its
9854                    // info and allow the caller to instantiate it.  Only do
9855                    // this if the provider is the same user as the caller's
9856                    // process, or can run as root (so can be in any process).
9857                    return cpr.newHolder(null);
9858                }
9859
9860                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9861                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9862                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9863
9864                // This is single process, and our app is now connecting to it.
9865                // See if we are already in the process of launching this
9866                // provider.
9867                final int N = mLaunchingProviders.size();
9868                int i;
9869                for (i = 0; i < N; i++) {
9870                    if (mLaunchingProviders.get(i) == cpr) {
9871                        break;
9872                    }
9873                }
9874
9875                // If the provider is not already being launched, then get it
9876                // started.
9877                if (i >= N) {
9878                    final long origId = Binder.clearCallingIdentity();
9879
9880                    try {
9881                        // Content provider is now in use, its package can't be stopped.
9882                        try {
9883                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9884                            AppGlobals.getPackageManager().setPackageStoppedState(
9885                                    cpr.appInfo.packageName, false, userId);
9886                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9887                        } catch (RemoteException e) {
9888                        } catch (IllegalArgumentException e) {
9889                            Slog.w(TAG, "Failed trying to unstop package "
9890                                    + cpr.appInfo.packageName + ": " + e);
9891                        }
9892
9893                        // Use existing process if already started
9894                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9895                        ProcessRecord proc = getProcessRecordLocked(
9896                                cpi.processName, cpr.appInfo.uid, false);
9897                        if (proc != null && proc.thread != null) {
9898                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9899                                    "Installing in existing process " + proc);
9900                            if (!proc.pubProviders.containsKey(cpi.name)) {
9901                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9902                                proc.pubProviders.put(cpi.name, cpr);
9903                                try {
9904                                    proc.thread.scheduleInstallProvider(cpi);
9905                                } catch (RemoteException e) {
9906                                }
9907                            }
9908                        } else {
9909                            checkTime(startTime, "getContentProviderImpl: before start process");
9910                            proc = startProcessLocked(cpi.processName,
9911                                    cpr.appInfo, false, 0, "content provider",
9912                                    new ComponentName(cpi.applicationInfo.packageName,
9913                                            cpi.name), false, false, false);
9914                            checkTime(startTime, "getContentProviderImpl: after start process");
9915                            if (proc == null) {
9916                                Slog.w(TAG, "Unable to launch app "
9917                                        + cpi.applicationInfo.packageName + "/"
9918                                        + cpi.applicationInfo.uid + " for provider "
9919                                        + name + ": process is bad");
9920                                return null;
9921                            }
9922                        }
9923                        cpr.launchingApp = proc;
9924                        mLaunchingProviders.add(cpr);
9925                    } finally {
9926                        Binder.restoreCallingIdentity(origId);
9927                    }
9928                }
9929
9930                checkTime(startTime, "getContentProviderImpl: updating data structures");
9931
9932                // Make sure the provider is published (the same provider class
9933                // may be published under multiple names).
9934                if (firstClass) {
9935                    mProviderMap.putProviderByClass(comp, cpr);
9936                }
9937
9938                mProviderMap.putProviderByName(name, cpr);
9939                conn = incProviderCountLocked(r, cpr, token, stable);
9940                if (conn != null) {
9941                    conn.waiting = true;
9942                }
9943            }
9944            checkTime(startTime, "getContentProviderImpl: done!");
9945        }
9946
9947        // Wait for the provider to be published...
9948        synchronized (cpr) {
9949            while (cpr.provider == null) {
9950                if (cpr.launchingApp == null) {
9951                    Slog.w(TAG, "Unable to launch app "
9952                            + cpi.applicationInfo.packageName + "/"
9953                            + cpi.applicationInfo.uid + " for provider "
9954                            + name + ": launching app became null");
9955                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9956                            UserHandle.getUserId(cpi.applicationInfo.uid),
9957                            cpi.applicationInfo.packageName,
9958                            cpi.applicationInfo.uid, name);
9959                    return null;
9960                }
9961                try {
9962                    if (DEBUG_MU) Slog.v(TAG_MU,
9963                            "Waiting to start provider " + cpr
9964                            + " launchingApp=" + cpr.launchingApp);
9965                    if (conn != null) {
9966                        conn.waiting = true;
9967                    }
9968                    cpr.wait();
9969                } catch (InterruptedException ex) {
9970                } finally {
9971                    if (conn != null) {
9972                        conn.waiting = false;
9973                    }
9974                }
9975            }
9976        }
9977        return cpr != null ? cpr.newHolder(conn) : null;
9978    }
9979
9980    @Override
9981    public final ContentProviderHolder getContentProvider(
9982            IApplicationThread caller, String name, int userId, boolean stable) {
9983        enforceNotIsolatedCaller("getContentProvider");
9984        if (caller == null) {
9985            String msg = "null IApplicationThread when getting content provider "
9986                    + name;
9987            Slog.w(TAG, msg);
9988            throw new SecurityException(msg);
9989        }
9990        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9991        // with cross-user grant.
9992        return getContentProviderImpl(caller, name, null, stable, userId);
9993    }
9994
9995    public ContentProviderHolder getContentProviderExternal(
9996            String name, int userId, IBinder token) {
9997        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9998            "Do not have permission in call getContentProviderExternal()");
9999        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10000                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10001        return getContentProviderExternalUnchecked(name, token, userId);
10002    }
10003
10004    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10005            IBinder token, int userId) {
10006        return getContentProviderImpl(null, name, token, true, userId);
10007    }
10008
10009    /**
10010     * Drop a content provider from a ProcessRecord's bookkeeping
10011     */
10012    public void removeContentProvider(IBinder connection, boolean stable) {
10013        enforceNotIsolatedCaller("removeContentProvider");
10014        long ident = Binder.clearCallingIdentity();
10015        try {
10016            synchronized (this) {
10017                ContentProviderConnection conn;
10018                try {
10019                    conn = (ContentProviderConnection)connection;
10020                } catch (ClassCastException e) {
10021                    String msg ="removeContentProvider: " + connection
10022                            + " not a ContentProviderConnection";
10023                    Slog.w(TAG, msg);
10024                    throw new IllegalArgumentException(msg);
10025                }
10026                if (conn == null) {
10027                    throw new NullPointerException("connection is null");
10028                }
10029                if (decProviderCountLocked(conn, null, null, stable)) {
10030                    updateOomAdjLocked();
10031                }
10032            }
10033        } finally {
10034            Binder.restoreCallingIdentity(ident);
10035        }
10036    }
10037
10038    public void removeContentProviderExternal(String name, IBinder token) {
10039        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10040            "Do not have permission in call removeContentProviderExternal()");
10041        int userId = UserHandle.getCallingUserId();
10042        long ident = Binder.clearCallingIdentity();
10043        try {
10044            removeContentProviderExternalUnchecked(name, token, userId);
10045        } finally {
10046            Binder.restoreCallingIdentity(ident);
10047        }
10048    }
10049
10050    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10051        synchronized (this) {
10052            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10053            if(cpr == null) {
10054                //remove from mProvidersByClass
10055                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10056                return;
10057            }
10058
10059            //update content provider record entry info
10060            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10061            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10062            if (localCpr.hasExternalProcessHandles()) {
10063                if (localCpr.removeExternalProcessHandleLocked(token)) {
10064                    updateOomAdjLocked();
10065                } else {
10066                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10067                            + " with no external reference for token: "
10068                            + token + ".");
10069                }
10070            } else {
10071                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10072                        + " with no external references.");
10073            }
10074        }
10075    }
10076
10077    public final void publishContentProviders(IApplicationThread caller,
10078            List<ContentProviderHolder> providers) {
10079        if (providers == null) {
10080            return;
10081        }
10082
10083        enforceNotIsolatedCaller("publishContentProviders");
10084        synchronized (this) {
10085            final ProcessRecord r = getRecordForAppLocked(caller);
10086            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10087            if (r == null) {
10088                throw new SecurityException(
10089                        "Unable to find app for caller " + caller
10090                      + " (pid=" + Binder.getCallingPid()
10091                      + ") when publishing content providers");
10092            }
10093
10094            final long origId = Binder.clearCallingIdentity();
10095
10096            final int N = providers.size();
10097            for (int i = 0; i < N; i++) {
10098                ContentProviderHolder src = providers.get(i);
10099                if (src == null || src.info == null || src.provider == null) {
10100                    continue;
10101                }
10102                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10103                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10104                if (dst != null) {
10105                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10106                    mProviderMap.putProviderByClass(comp, dst);
10107                    String names[] = dst.info.authority.split(";");
10108                    for (int j = 0; j < names.length; j++) {
10109                        mProviderMap.putProviderByName(names[j], dst);
10110                    }
10111
10112                    int launchingCount = mLaunchingProviders.size();
10113                    int j;
10114                    boolean wasInLaunchingProviders = false;
10115                    for (j = 0; j < launchingCount; j++) {
10116                        if (mLaunchingProviders.get(j) == dst) {
10117                            mLaunchingProviders.remove(j);
10118                            wasInLaunchingProviders = true;
10119                            j--;
10120                            launchingCount--;
10121                        }
10122                    }
10123                    if (wasInLaunchingProviders) {
10124                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10125                    }
10126                    synchronized (dst) {
10127                        dst.provider = src.provider;
10128                        dst.proc = r;
10129                        dst.notifyAll();
10130                    }
10131                    updateOomAdjLocked(r);
10132                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10133                            src.info.authority);
10134                }
10135            }
10136
10137            Binder.restoreCallingIdentity(origId);
10138        }
10139    }
10140
10141    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10142        ContentProviderConnection conn;
10143        try {
10144            conn = (ContentProviderConnection)connection;
10145        } catch (ClassCastException e) {
10146            String msg ="refContentProvider: " + connection
10147                    + " not a ContentProviderConnection";
10148            Slog.w(TAG, msg);
10149            throw new IllegalArgumentException(msg);
10150        }
10151        if (conn == null) {
10152            throw new NullPointerException("connection is null");
10153        }
10154
10155        synchronized (this) {
10156            if (stable > 0) {
10157                conn.numStableIncs += stable;
10158            }
10159            stable = conn.stableCount + stable;
10160            if (stable < 0) {
10161                throw new IllegalStateException("stableCount < 0: " + stable);
10162            }
10163
10164            if (unstable > 0) {
10165                conn.numUnstableIncs += unstable;
10166            }
10167            unstable = conn.unstableCount + unstable;
10168            if (unstable < 0) {
10169                throw new IllegalStateException("unstableCount < 0: " + unstable);
10170            }
10171
10172            if ((stable+unstable) <= 0) {
10173                throw new IllegalStateException("ref counts can't go to zero here: stable="
10174                        + stable + " unstable=" + unstable);
10175            }
10176            conn.stableCount = stable;
10177            conn.unstableCount = unstable;
10178            return !conn.dead;
10179        }
10180    }
10181
10182    public void unstableProviderDied(IBinder connection) {
10183        ContentProviderConnection conn;
10184        try {
10185            conn = (ContentProviderConnection)connection;
10186        } catch (ClassCastException e) {
10187            String msg ="refContentProvider: " + connection
10188                    + " not a ContentProviderConnection";
10189            Slog.w(TAG, msg);
10190            throw new IllegalArgumentException(msg);
10191        }
10192        if (conn == null) {
10193            throw new NullPointerException("connection is null");
10194        }
10195
10196        // Safely retrieve the content provider associated with the connection.
10197        IContentProvider provider;
10198        synchronized (this) {
10199            provider = conn.provider.provider;
10200        }
10201
10202        if (provider == null) {
10203            // Um, yeah, we're way ahead of you.
10204            return;
10205        }
10206
10207        // Make sure the caller is being honest with us.
10208        if (provider.asBinder().pingBinder()) {
10209            // Er, no, still looks good to us.
10210            synchronized (this) {
10211                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10212                        + " says " + conn + " died, but we don't agree");
10213                return;
10214            }
10215        }
10216
10217        // Well look at that!  It's dead!
10218        synchronized (this) {
10219            if (conn.provider.provider != provider) {
10220                // But something changed...  good enough.
10221                return;
10222            }
10223
10224            ProcessRecord proc = conn.provider.proc;
10225            if (proc == null || proc.thread == null) {
10226                // Seems like the process is already cleaned up.
10227                return;
10228            }
10229
10230            // As far as we're concerned, this is just like receiving a
10231            // death notification...  just a bit prematurely.
10232            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10233                    + ") early provider death");
10234            final long ident = Binder.clearCallingIdentity();
10235            try {
10236                appDiedLocked(proc);
10237            } finally {
10238                Binder.restoreCallingIdentity(ident);
10239            }
10240        }
10241    }
10242
10243    @Override
10244    public void appNotRespondingViaProvider(IBinder connection) {
10245        enforceCallingPermission(
10246                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10247
10248        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10249        if (conn == null) {
10250            Slog.w(TAG, "ContentProviderConnection is null");
10251            return;
10252        }
10253
10254        final ProcessRecord host = conn.provider.proc;
10255        if (host == null) {
10256            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10257            return;
10258        }
10259
10260        final long token = Binder.clearCallingIdentity();
10261        try {
10262            appNotResponding(host, null, null, false, "ContentProvider not responding");
10263        } finally {
10264            Binder.restoreCallingIdentity(token);
10265        }
10266    }
10267
10268    public final void installSystemProviders() {
10269        List<ProviderInfo> providers;
10270        synchronized (this) {
10271            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10272            providers = generateApplicationProvidersLocked(app);
10273            if (providers != null) {
10274                for (int i=providers.size()-1; i>=0; i--) {
10275                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10276                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10277                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10278                                + ": not system .apk");
10279                        providers.remove(i);
10280                    }
10281                }
10282            }
10283        }
10284        if (providers != null) {
10285            mSystemThread.installSystemProviders(providers);
10286        }
10287
10288        mCoreSettingsObserver = new CoreSettingsObserver(this);
10289
10290        //mUsageStatsService.monitorPackages();
10291    }
10292
10293    /**
10294     * Allows apps to retrieve the MIME type of a URI.
10295     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10296     * users, then it does not need permission to access the ContentProvider.
10297     * Either, it needs cross-user uri grants.
10298     *
10299     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10300     *
10301     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10302     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10303     */
10304    public String getProviderMimeType(Uri uri, int userId) {
10305        enforceNotIsolatedCaller("getProviderMimeType");
10306        final String name = uri.getAuthority();
10307        int callingUid = Binder.getCallingUid();
10308        int callingPid = Binder.getCallingPid();
10309        long ident = 0;
10310        boolean clearedIdentity = false;
10311        synchronized (this) {
10312            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10313        }
10314        if (canClearIdentity(callingPid, callingUid, userId)) {
10315            clearedIdentity = true;
10316            ident = Binder.clearCallingIdentity();
10317        }
10318        ContentProviderHolder holder = null;
10319        try {
10320            holder = getContentProviderExternalUnchecked(name, null, userId);
10321            if (holder != null) {
10322                return holder.provider.getType(uri);
10323            }
10324        } catch (RemoteException e) {
10325            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10326            return null;
10327        } finally {
10328            // We need to clear the identity to call removeContentProviderExternalUnchecked
10329            if (!clearedIdentity) {
10330                ident = Binder.clearCallingIdentity();
10331            }
10332            try {
10333                if (holder != null) {
10334                    removeContentProviderExternalUnchecked(name, null, userId);
10335                }
10336            } finally {
10337                Binder.restoreCallingIdentity(ident);
10338            }
10339        }
10340
10341        return null;
10342    }
10343
10344    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10345        if (UserHandle.getUserId(callingUid) == userId) {
10346            return true;
10347        }
10348        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10349                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10350                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10351                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10352                return true;
10353        }
10354        return false;
10355    }
10356
10357    // =========================================================
10358    // GLOBAL MANAGEMENT
10359    // =========================================================
10360
10361    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10362            boolean isolated, int isolatedUid) {
10363        String proc = customProcess != null ? customProcess : info.processName;
10364        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10365        final int userId = UserHandle.getUserId(info.uid);
10366        int uid = info.uid;
10367        if (isolated) {
10368            if (isolatedUid == 0) {
10369                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10370                while (true) {
10371                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10372                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10373                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10374                    }
10375                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10376                    mNextIsolatedProcessUid++;
10377                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10378                        // No process for this uid, use it.
10379                        break;
10380                    }
10381                    stepsLeft--;
10382                    if (stepsLeft <= 0) {
10383                        return null;
10384                    }
10385                }
10386            } else {
10387                // Special case for startIsolatedProcess (internal only), where
10388                // the uid of the isolated process is specified by the caller.
10389                uid = isolatedUid;
10390            }
10391        }
10392        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10393        if (!mBooted && !mBooting
10394                && userId == UserHandle.USER_SYSTEM
10395                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10396            r.persistent = true;
10397        }
10398        addProcessNameLocked(r);
10399        return r;
10400    }
10401
10402    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10403            String abiOverride) {
10404        ProcessRecord app;
10405        if (!isolated) {
10406            app = getProcessRecordLocked(info.processName, info.uid, true);
10407        } else {
10408            app = null;
10409        }
10410
10411        if (app == null) {
10412            app = newProcessRecordLocked(info, null, isolated, 0);
10413            updateLruProcessLocked(app, false, null);
10414            updateOomAdjLocked();
10415        }
10416
10417        // This package really, really can not be stopped.
10418        try {
10419            AppGlobals.getPackageManager().setPackageStoppedState(
10420                    info.packageName, false, UserHandle.getUserId(app.uid));
10421        } catch (RemoteException e) {
10422        } catch (IllegalArgumentException e) {
10423            Slog.w(TAG, "Failed trying to unstop package "
10424                    + info.packageName + ": " + e);
10425        }
10426
10427        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10428            app.persistent = true;
10429            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10430        }
10431        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10432            mPersistentStartingProcesses.add(app);
10433            startProcessLocked(app, "added application", app.processName, abiOverride,
10434                    null /* entryPoint */, null /* entryPointArgs */);
10435        }
10436
10437        return app;
10438    }
10439
10440    public void unhandledBack() {
10441        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10442                "unhandledBack()");
10443
10444        synchronized(this) {
10445            final long origId = Binder.clearCallingIdentity();
10446            try {
10447                getFocusedStack().unhandledBackLocked();
10448            } finally {
10449                Binder.restoreCallingIdentity(origId);
10450            }
10451        }
10452    }
10453
10454    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10455        enforceNotIsolatedCaller("openContentUri");
10456        final int userId = UserHandle.getCallingUserId();
10457        String name = uri.getAuthority();
10458        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10459        ParcelFileDescriptor pfd = null;
10460        if (cph != null) {
10461            // We record the binder invoker's uid in thread-local storage before
10462            // going to the content provider to open the file.  Later, in the code
10463            // that handles all permissions checks, we look for this uid and use
10464            // that rather than the Activity Manager's own uid.  The effect is that
10465            // we do the check against the caller's permissions even though it looks
10466            // to the content provider like the Activity Manager itself is making
10467            // the request.
10468            Binder token = new Binder();
10469            sCallerIdentity.set(new Identity(
10470                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10471            try {
10472                pfd = cph.provider.openFile(null, uri, "r", null, token);
10473            } catch (FileNotFoundException e) {
10474                // do nothing; pfd will be returned null
10475            } finally {
10476                // Ensure that whatever happens, we clean up the identity state
10477                sCallerIdentity.remove();
10478                // Ensure we're done with the provider.
10479                removeContentProviderExternalUnchecked(name, null, userId);
10480            }
10481        } else {
10482            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10483        }
10484        return pfd;
10485    }
10486
10487    // Actually is sleeping or shutting down or whatever else in the future
10488    // is an inactive state.
10489    public boolean isSleepingOrShuttingDown() {
10490        return isSleeping() || mShuttingDown;
10491    }
10492
10493    public boolean isSleeping() {
10494        return mSleeping;
10495    }
10496
10497    void onWakefulnessChanged(int wakefulness) {
10498        synchronized(this) {
10499            mWakefulness = wakefulness;
10500            updateSleepIfNeededLocked();
10501        }
10502    }
10503
10504    void finishRunningVoiceLocked() {
10505        if (mRunningVoice != null) {
10506            mRunningVoice = null;
10507            mVoiceWakeLock.release();
10508            updateSleepIfNeededLocked();
10509        }
10510    }
10511
10512    void startTimeTrackingFocusedActivityLocked() {
10513        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10514            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10515        }
10516    }
10517
10518    void updateSleepIfNeededLocked() {
10519        if (mSleeping && !shouldSleepLocked()) {
10520            mSleeping = false;
10521            startTimeTrackingFocusedActivityLocked();
10522            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10523            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10524            updateOomAdjLocked();
10525        } else if (!mSleeping && shouldSleepLocked()) {
10526            mSleeping = true;
10527            if (mCurAppTimeTracker != null) {
10528                mCurAppTimeTracker.stop();
10529            }
10530            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10531            mStackSupervisor.goingToSleepLocked();
10532            updateOomAdjLocked();
10533
10534            // Initialize the wake times of all processes.
10535            checkExcessivePowerUsageLocked(false);
10536            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10537            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10538            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10539        }
10540    }
10541
10542    private boolean shouldSleepLocked() {
10543        // Resume applications while running a voice interactor.
10544        if (mRunningVoice != null) {
10545            return false;
10546        }
10547
10548        // TODO: Transform the lock screen state into a sleep token instead.
10549        switch (mWakefulness) {
10550            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10551            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10552            case PowerManagerInternal.WAKEFULNESS_DOZING:
10553                // Pause applications whenever the lock screen is shown or any sleep
10554                // tokens have been acquired.
10555                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10556            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10557            default:
10558                // If we're asleep then pause applications unconditionally.
10559                return true;
10560        }
10561    }
10562
10563    /** Pokes the task persister. */
10564    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10565        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10566            // Never persist the home stack.
10567            return;
10568        }
10569        mTaskPersister.wakeup(task, flush);
10570    }
10571
10572    /** Notifies all listeners when the task stack has changed. */
10573    void notifyTaskStackChangedLocked() {
10574        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10575        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10576        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10577    }
10578
10579    @Override
10580    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10581        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10582    }
10583
10584    @Override
10585    public boolean shutdown(int timeout) {
10586        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10587                != PackageManager.PERMISSION_GRANTED) {
10588            throw new SecurityException("Requires permission "
10589                    + android.Manifest.permission.SHUTDOWN);
10590        }
10591
10592        boolean timedout = false;
10593
10594        synchronized(this) {
10595            mShuttingDown = true;
10596            updateEventDispatchingLocked();
10597            timedout = mStackSupervisor.shutdownLocked(timeout);
10598        }
10599
10600        mAppOpsService.shutdown();
10601        if (mUsageStatsService != null) {
10602            mUsageStatsService.prepareShutdown();
10603        }
10604        mBatteryStatsService.shutdown();
10605        synchronized (this) {
10606            mProcessStats.shutdownLocked();
10607            notifyTaskPersisterLocked(null, true);
10608        }
10609
10610        return timedout;
10611    }
10612
10613    public final void activitySlept(IBinder token) {
10614        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10615
10616        final long origId = Binder.clearCallingIdentity();
10617
10618        synchronized (this) {
10619            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10620            if (r != null) {
10621                mStackSupervisor.activitySleptLocked(r);
10622            }
10623        }
10624
10625        Binder.restoreCallingIdentity(origId);
10626    }
10627
10628    private String lockScreenShownToString() {
10629        switch (mLockScreenShown) {
10630            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10631            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10632            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10633            default: return "Unknown=" + mLockScreenShown;
10634        }
10635    }
10636
10637    void logLockScreen(String msg) {
10638        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10639                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10640                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10641                + " mSleeping=" + mSleeping);
10642    }
10643
10644    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10645        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10646        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10647            boolean wasRunningVoice = mRunningVoice != null;
10648            mRunningVoice = session;
10649            if (!wasRunningVoice) {
10650                mVoiceWakeLock.acquire();
10651                updateSleepIfNeededLocked();
10652            }
10653        }
10654    }
10655
10656    private void updateEventDispatchingLocked() {
10657        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10658    }
10659
10660    public void setLockScreenShown(boolean shown) {
10661        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10662                != PackageManager.PERMISSION_GRANTED) {
10663            throw new SecurityException("Requires permission "
10664                    + android.Manifest.permission.DEVICE_POWER);
10665        }
10666
10667        synchronized(this) {
10668            long ident = Binder.clearCallingIdentity();
10669            try {
10670                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10671                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10672                updateSleepIfNeededLocked();
10673            } finally {
10674                Binder.restoreCallingIdentity(ident);
10675            }
10676        }
10677    }
10678
10679    @Override
10680    public void stopAppSwitches() {
10681        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10682                != PackageManager.PERMISSION_GRANTED) {
10683            throw new SecurityException("Requires permission "
10684                    + android.Manifest.permission.STOP_APP_SWITCHES);
10685        }
10686
10687        synchronized(this) {
10688            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10689                    + APP_SWITCH_DELAY_TIME;
10690            mDidAppSwitch = false;
10691            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10692            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10693            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10694        }
10695    }
10696
10697    public void resumeAppSwitches() {
10698        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10699                != PackageManager.PERMISSION_GRANTED) {
10700            throw new SecurityException("Requires permission "
10701                    + android.Manifest.permission.STOP_APP_SWITCHES);
10702        }
10703
10704        synchronized(this) {
10705            // Note that we don't execute any pending app switches... we will
10706            // let those wait until either the timeout, or the next start
10707            // activity request.
10708            mAppSwitchesAllowedTime = 0;
10709        }
10710    }
10711
10712    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10713            int callingPid, int callingUid, String name) {
10714        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10715            return true;
10716        }
10717
10718        int perm = checkComponentPermission(
10719                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10720                sourceUid, -1, true);
10721        if (perm == PackageManager.PERMISSION_GRANTED) {
10722            return true;
10723        }
10724
10725        // If the actual IPC caller is different from the logical source, then
10726        // also see if they are allowed to control app switches.
10727        if (callingUid != -1 && callingUid != sourceUid) {
10728            perm = checkComponentPermission(
10729                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10730                    callingUid, -1, true);
10731            if (perm == PackageManager.PERMISSION_GRANTED) {
10732                return true;
10733            }
10734        }
10735
10736        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10737        return false;
10738    }
10739
10740    public void setDebugApp(String packageName, boolean waitForDebugger,
10741            boolean persistent) {
10742        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10743                "setDebugApp()");
10744
10745        long ident = Binder.clearCallingIdentity();
10746        try {
10747            // Note that this is not really thread safe if there are multiple
10748            // callers into it at the same time, but that's not a situation we
10749            // care about.
10750            if (persistent) {
10751                final ContentResolver resolver = mContext.getContentResolver();
10752                Settings.Global.putString(
10753                    resolver, Settings.Global.DEBUG_APP,
10754                    packageName);
10755                Settings.Global.putInt(
10756                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10757                    waitForDebugger ? 1 : 0);
10758            }
10759
10760            synchronized (this) {
10761                if (!persistent) {
10762                    mOrigDebugApp = mDebugApp;
10763                    mOrigWaitForDebugger = mWaitForDebugger;
10764                }
10765                mDebugApp = packageName;
10766                mWaitForDebugger = waitForDebugger;
10767                mDebugTransient = !persistent;
10768                if (packageName != null) {
10769                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10770                            false, UserHandle.USER_ALL, "set debug app");
10771                }
10772            }
10773        } finally {
10774            Binder.restoreCallingIdentity(ident);
10775        }
10776    }
10777
10778    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10779        synchronized (this) {
10780            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10781            if (!isDebuggable) {
10782                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10783                    throw new SecurityException("Process not debuggable: " + app.packageName);
10784                }
10785            }
10786
10787            mTrackAllocationApp = processName;
10788        }
10789    }
10790
10791    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10792        synchronized (this) {
10793            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10794            if (!isDebuggable) {
10795                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10796                    throw new SecurityException("Process not debuggable: " + app.packageName);
10797                }
10798            }
10799            mProfileApp = processName;
10800            mProfileFile = profilerInfo.profileFile;
10801            if (mProfileFd != null) {
10802                try {
10803                    mProfileFd.close();
10804                } catch (IOException e) {
10805                }
10806                mProfileFd = null;
10807            }
10808            mProfileFd = profilerInfo.profileFd;
10809            mSamplingInterval = profilerInfo.samplingInterval;
10810            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10811            mProfileType = 0;
10812        }
10813    }
10814
10815    @Override
10816    public void setAlwaysFinish(boolean enabled) {
10817        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10818                "setAlwaysFinish()");
10819
10820        Settings.Global.putInt(
10821                mContext.getContentResolver(),
10822                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10823
10824        synchronized (this) {
10825            mAlwaysFinishActivities = enabled;
10826        }
10827    }
10828
10829    @Override
10830    public void setActivityController(IActivityController controller) {
10831        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10832                "setActivityController()");
10833        synchronized (this) {
10834            mController = controller;
10835            Watchdog.getInstance().setActivityController(controller);
10836        }
10837    }
10838
10839    @Override
10840    public void setUserIsMonkey(boolean userIsMonkey) {
10841        synchronized (this) {
10842            synchronized (mPidsSelfLocked) {
10843                final int callingPid = Binder.getCallingPid();
10844                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10845                if (precessRecord == null) {
10846                    throw new SecurityException("Unknown process: " + callingPid);
10847                }
10848                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10849                    throw new SecurityException("Only an instrumentation process "
10850                            + "with a UiAutomation can call setUserIsMonkey");
10851                }
10852            }
10853            mUserIsMonkey = userIsMonkey;
10854        }
10855    }
10856
10857    @Override
10858    public boolean isUserAMonkey() {
10859        synchronized (this) {
10860            // If there is a controller also implies the user is a monkey.
10861            return (mUserIsMonkey || mController != null);
10862        }
10863    }
10864
10865    public void requestBugReport() {
10866        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10867        SystemProperties.set("ctl.start", "bugreport");
10868    }
10869
10870    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10871        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10872    }
10873
10874    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10875        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10876            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10877        }
10878        return KEY_DISPATCHING_TIMEOUT;
10879    }
10880
10881    @Override
10882    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10883        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10884                != PackageManager.PERMISSION_GRANTED) {
10885            throw new SecurityException("Requires permission "
10886                    + android.Manifest.permission.FILTER_EVENTS);
10887        }
10888        ProcessRecord proc;
10889        long timeout;
10890        synchronized (this) {
10891            synchronized (mPidsSelfLocked) {
10892                proc = mPidsSelfLocked.get(pid);
10893            }
10894            timeout = getInputDispatchingTimeoutLocked(proc);
10895        }
10896
10897        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10898            return -1;
10899        }
10900
10901        return timeout;
10902    }
10903
10904    /**
10905     * Handle input dispatching timeouts.
10906     * Returns whether input dispatching should be aborted or not.
10907     */
10908    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10909            final ActivityRecord activity, final ActivityRecord parent,
10910            final boolean aboveSystem, String reason) {
10911        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10912                != PackageManager.PERMISSION_GRANTED) {
10913            throw new SecurityException("Requires permission "
10914                    + android.Manifest.permission.FILTER_EVENTS);
10915        }
10916
10917        final String annotation;
10918        if (reason == null) {
10919            annotation = "Input dispatching timed out";
10920        } else {
10921            annotation = "Input dispatching timed out (" + reason + ")";
10922        }
10923
10924        if (proc != null) {
10925            synchronized (this) {
10926                if (proc.debugging) {
10927                    return false;
10928                }
10929
10930                if (mDidDexOpt) {
10931                    // Give more time since we were dexopting.
10932                    mDidDexOpt = false;
10933                    return false;
10934                }
10935
10936                if (proc.instrumentationClass != null) {
10937                    Bundle info = new Bundle();
10938                    info.putString("shortMsg", "keyDispatchingTimedOut");
10939                    info.putString("longMsg", annotation);
10940                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10941                    return true;
10942                }
10943            }
10944            mHandler.post(new Runnable() {
10945                @Override
10946                public void run() {
10947                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10948                }
10949            });
10950        }
10951
10952        return true;
10953    }
10954
10955    @Override
10956    public Bundle getAssistContextExtras(int requestType) {
10957        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10958                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10959        if (pae == null) {
10960            return null;
10961        }
10962        synchronized (pae) {
10963            while (!pae.haveResult) {
10964                try {
10965                    pae.wait();
10966                } catch (InterruptedException e) {
10967                }
10968            }
10969        }
10970        synchronized (this) {
10971            buildAssistBundleLocked(pae, pae.result);
10972            mPendingAssistExtras.remove(pae);
10973            mUiHandler.removeCallbacks(pae);
10974        }
10975        return pae.extras;
10976    }
10977
10978    @Override
10979    public boolean isAssistDataAllowedOnCurrentActivity() {
10980        int userId;
10981        synchronized (this) {
10982            userId = mUserController.getCurrentUserIdLocked();
10983            ActivityRecord activity = getFocusedStack().topActivity();
10984            if (activity == null) {
10985                return false;
10986            }
10987            userId = activity.userId;
10988        }
10989        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10990                Context.DEVICE_POLICY_SERVICE);
10991        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10992    }
10993
10994    @Override
10995    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10996        long ident = Binder.clearCallingIdentity();
10997        try {
10998            synchronized (this) {
10999                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11000                ActivityRecord top = getFocusedStack().topActivity();
11001                if (top != caller) {
11002                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11003                            + " is not current top " + top);
11004                    return false;
11005                }
11006                if (!top.nowVisible) {
11007                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11008                            + " is not visible");
11009                    return false;
11010                }
11011            }
11012            AssistUtils utils = new AssistUtils(mContext);
11013            return utils.showSessionForActiveService(args,
11014                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11015        } finally {
11016            Binder.restoreCallingIdentity(ident);
11017        }
11018    }
11019
11020    @Override
11021    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11022            IBinder activityToken) {
11023        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11024                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11025    }
11026
11027    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11028            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11029            long timeout) {
11030        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11031                "enqueueAssistContext()");
11032        synchronized (this) {
11033            ActivityRecord activity = getFocusedStack().topActivity();
11034            if (activity == null) {
11035                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11036                return null;
11037            }
11038            if (activity.app == null || activity.app.thread == null) {
11039                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11040                return null;
11041            }
11042            if (activityToken != null) {
11043                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11044                if (activity != caller) {
11045                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11046                            + " is not current top " + activity);
11047                    return null;
11048                }
11049            }
11050            PendingAssistExtras pae;
11051            Bundle extras = new Bundle();
11052            if (args != null) {
11053                extras.putAll(args);
11054            }
11055            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11056            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11057            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11058            try {
11059                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11060                        requestType);
11061                mPendingAssistExtras.add(pae);
11062                mUiHandler.postDelayed(pae, timeout);
11063            } catch (RemoteException e) {
11064                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11065                return null;
11066            }
11067            return pae;
11068        }
11069    }
11070
11071    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11072        IResultReceiver receiver;
11073        synchronized (this) {
11074            mPendingAssistExtras.remove(pae);
11075            receiver = pae.receiver;
11076        }
11077        if (receiver != null) {
11078            // Caller wants result sent back to them.
11079            try {
11080                pae.receiver.send(0, null);
11081            } catch (RemoteException e) {
11082            }
11083        }
11084    }
11085
11086    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11087        if (result != null) {
11088            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11089        }
11090        if (pae.hint != null) {
11091            pae.extras.putBoolean(pae.hint, true);
11092        }
11093    }
11094
11095    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11096            AssistContent content, Uri referrer) {
11097        PendingAssistExtras pae = (PendingAssistExtras)token;
11098        synchronized (pae) {
11099            pae.result = extras;
11100            pae.structure = structure;
11101            pae.content = content;
11102            if (referrer != null) {
11103                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11104            }
11105            pae.haveResult = true;
11106            pae.notifyAll();
11107            if (pae.intent == null && pae.receiver == null) {
11108                // Caller is just waiting for the result.
11109                return;
11110            }
11111        }
11112
11113        // We are now ready to launch the assist activity.
11114        IResultReceiver sendReceiver = null;
11115        Bundle sendBundle = null;
11116        synchronized (this) {
11117            buildAssistBundleLocked(pae, extras);
11118            boolean exists = mPendingAssistExtras.remove(pae);
11119            mUiHandler.removeCallbacks(pae);
11120            if (!exists) {
11121                // Timed out.
11122                return;
11123            }
11124            if ((sendReceiver=pae.receiver) != null) {
11125                // Caller wants result sent back to them.
11126                sendBundle = new Bundle();
11127                sendBundle.putBundle("data", pae.extras);
11128                sendBundle.putParcelable("structure", pae.structure);
11129                sendBundle.putParcelable("content", pae.content);
11130            }
11131        }
11132        if (sendReceiver != null) {
11133            try {
11134                sendReceiver.send(0, sendBundle);
11135            } catch (RemoteException e) {
11136            }
11137            return;
11138        }
11139
11140        long ident = Binder.clearCallingIdentity();
11141        try {
11142            pae.intent.replaceExtras(pae.extras);
11143            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11144                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11145                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11146            closeSystemDialogs("assist");
11147            try {
11148                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11149            } catch (ActivityNotFoundException e) {
11150                Slog.w(TAG, "No activity to handle assist action.", e);
11151            }
11152        } finally {
11153            Binder.restoreCallingIdentity(ident);
11154        }
11155    }
11156
11157    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11158            Bundle args) {
11159        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11160                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11161    }
11162
11163    public void registerProcessObserver(IProcessObserver observer) {
11164        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11165                "registerProcessObserver()");
11166        synchronized (this) {
11167            mProcessObservers.register(observer);
11168        }
11169    }
11170
11171    @Override
11172    public void unregisterProcessObserver(IProcessObserver observer) {
11173        synchronized (this) {
11174            mProcessObservers.unregister(observer);
11175        }
11176    }
11177
11178    public void registerUidObserver(IUidObserver observer) {
11179        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11180                "registerUidObserver()");
11181        synchronized (this) {
11182            mUidObservers.register(observer);
11183        }
11184    }
11185
11186    @Override
11187    public void unregisterUidObserver(IUidObserver observer) {
11188        synchronized (this) {
11189            mUidObservers.unregister(observer);
11190        }
11191    }
11192
11193    @Override
11194    public boolean convertFromTranslucent(IBinder token) {
11195        final long origId = Binder.clearCallingIdentity();
11196        try {
11197            synchronized (this) {
11198                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11199                if (r == null) {
11200                    return false;
11201                }
11202                final boolean translucentChanged = r.changeWindowTranslucency(true);
11203                if (translucentChanged) {
11204                    r.task.stack.releaseBackgroundResources(r);
11205                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11206                }
11207                mWindowManager.setAppFullscreen(token, true);
11208                return translucentChanged;
11209            }
11210        } finally {
11211            Binder.restoreCallingIdentity(origId);
11212        }
11213    }
11214
11215    @Override
11216    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11217        final long origId = Binder.clearCallingIdentity();
11218        try {
11219            synchronized (this) {
11220                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11221                if (r == null) {
11222                    return false;
11223                }
11224                int index = r.task.mActivities.lastIndexOf(r);
11225                if (index > 0) {
11226                    ActivityRecord under = r.task.mActivities.get(index - 1);
11227                    under.returningOptions = options;
11228                }
11229                final boolean translucentChanged = r.changeWindowTranslucency(false);
11230                if (translucentChanged) {
11231                    r.task.stack.convertActivityToTranslucent(r);
11232                }
11233                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11234                mWindowManager.setAppFullscreen(token, false);
11235                return translucentChanged;
11236            }
11237        } finally {
11238            Binder.restoreCallingIdentity(origId);
11239        }
11240    }
11241
11242    @Override
11243    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11244        final long origId = Binder.clearCallingIdentity();
11245        try {
11246            synchronized (this) {
11247                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11248                if (r != null) {
11249                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11250                }
11251            }
11252            return false;
11253        } finally {
11254            Binder.restoreCallingIdentity(origId);
11255        }
11256    }
11257
11258    @Override
11259    public boolean isBackgroundVisibleBehind(IBinder token) {
11260        final long origId = Binder.clearCallingIdentity();
11261        try {
11262            synchronized (this) {
11263                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11264                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11265                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11266                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11267                return visible;
11268            }
11269        } finally {
11270            Binder.restoreCallingIdentity(origId);
11271        }
11272    }
11273
11274    @Override
11275    public ActivityOptions getActivityOptions(IBinder token) {
11276        final long origId = Binder.clearCallingIdentity();
11277        try {
11278            synchronized (this) {
11279                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11280                if (r != null) {
11281                    final ActivityOptions activityOptions = r.pendingOptions;
11282                    r.pendingOptions = null;
11283                    return activityOptions;
11284                }
11285                return null;
11286            }
11287        } finally {
11288            Binder.restoreCallingIdentity(origId);
11289        }
11290    }
11291
11292    @Override
11293    public void setImmersive(IBinder token, boolean immersive) {
11294        synchronized(this) {
11295            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11296            if (r == null) {
11297                throw new IllegalArgumentException();
11298            }
11299            r.immersive = immersive;
11300
11301            // update associated state if we're frontmost
11302            if (r == mFocusedActivity) {
11303                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11304                applyUpdateLockStateLocked(r);
11305            }
11306        }
11307    }
11308
11309    @Override
11310    public boolean isImmersive(IBinder token) {
11311        synchronized (this) {
11312            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11313            if (r == null) {
11314                throw new IllegalArgumentException();
11315            }
11316            return r.immersive;
11317        }
11318    }
11319
11320    public boolean isTopActivityImmersive() {
11321        enforceNotIsolatedCaller("startActivity");
11322        synchronized (this) {
11323            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11324            return (r != null) ? r.immersive : false;
11325        }
11326    }
11327
11328    @Override
11329    public boolean isTopOfTask(IBinder token) {
11330        synchronized (this) {
11331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11332            if (r == null) {
11333                throw new IllegalArgumentException();
11334            }
11335            return r.task.getTopActivity() == r;
11336        }
11337    }
11338
11339    public final void enterSafeMode() {
11340        synchronized(this) {
11341            // It only makes sense to do this before the system is ready
11342            // and started launching other packages.
11343            if (!mSystemReady) {
11344                try {
11345                    AppGlobals.getPackageManager().enterSafeMode();
11346                } catch (RemoteException e) {
11347                }
11348            }
11349
11350            mSafeMode = true;
11351        }
11352    }
11353
11354    public final void showSafeModeOverlay() {
11355        View v = LayoutInflater.from(mContext).inflate(
11356                com.android.internal.R.layout.safe_mode, null);
11357        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11358        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11359        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11360        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11361        lp.gravity = Gravity.BOTTOM | Gravity.START;
11362        lp.format = v.getBackground().getOpacity();
11363        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11364                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11365        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11366        ((WindowManager)mContext.getSystemService(
11367                Context.WINDOW_SERVICE)).addView(v, lp);
11368    }
11369
11370    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11371        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11372            return;
11373        }
11374        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11375        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11376        synchronized (stats) {
11377            if (mBatteryStatsService.isOnBattery()) {
11378                mBatteryStatsService.enforceCallingPermission();
11379                int MY_UID = Binder.getCallingUid();
11380                final int uid;
11381                if (sender == null) {
11382                    uid = sourceUid;
11383                } else {
11384                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11385                }
11386                BatteryStatsImpl.Uid.Pkg pkg =
11387                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11388                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11389                pkg.noteWakeupAlarmLocked(tag);
11390            }
11391        }
11392    }
11393
11394    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11395        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11396            return;
11397        }
11398        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11399        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11400        synchronized (stats) {
11401            mBatteryStatsService.enforceCallingPermission();
11402            int MY_UID = Binder.getCallingUid();
11403            final int uid;
11404            if (sender == null) {
11405                uid = sourceUid;
11406            } else {
11407                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11408            }
11409            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11410        }
11411    }
11412
11413    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11414        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11415            return;
11416        }
11417        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11418        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11419        synchronized (stats) {
11420            mBatteryStatsService.enforceCallingPermission();
11421            int MY_UID = Binder.getCallingUid();
11422            final int uid;
11423            if (sender == null) {
11424                uid = sourceUid;
11425            } else {
11426                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11427            }
11428            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11429        }
11430    }
11431
11432    public boolean killPids(int[] pids, String pReason, boolean secure) {
11433        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11434            throw new SecurityException("killPids only available to the system");
11435        }
11436        String reason = (pReason == null) ? "Unknown" : pReason;
11437        // XXX Note: don't acquire main activity lock here, because the window
11438        // manager calls in with its locks held.
11439
11440        boolean killed = false;
11441        synchronized (mPidsSelfLocked) {
11442            int[] types = new int[pids.length];
11443            int worstType = 0;
11444            for (int i=0; i<pids.length; i++) {
11445                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11446                if (proc != null) {
11447                    int type = proc.setAdj;
11448                    types[i] = type;
11449                    if (type > worstType) {
11450                        worstType = type;
11451                    }
11452                }
11453            }
11454
11455            // If the worst oom_adj is somewhere in the cached proc LRU range,
11456            // then constrain it so we will kill all cached procs.
11457            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11458                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11459                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11460            }
11461
11462            // If this is not a secure call, don't let it kill processes that
11463            // are important.
11464            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11465                worstType = ProcessList.SERVICE_ADJ;
11466            }
11467
11468            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11469            for (int i=0; i<pids.length; i++) {
11470                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11471                if (proc == null) {
11472                    continue;
11473                }
11474                int adj = proc.setAdj;
11475                if (adj >= worstType && !proc.killedByAm) {
11476                    proc.kill(reason, true);
11477                    killed = true;
11478                }
11479            }
11480        }
11481        return killed;
11482    }
11483
11484    @Override
11485    public void killUid(int appId, int userId, String reason) {
11486        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11487        synchronized (this) {
11488            final long identity = Binder.clearCallingIdentity();
11489            try {
11490                killPackageProcessesLocked(null, appId, userId,
11491                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11492                        reason != null ? reason : "kill uid");
11493            } finally {
11494                Binder.restoreCallingIdentity(identity);
11495            }
11496        }
11497    }
11498
11499    @Override
11500    public boolean killProcessesBelowForeground(String reason) {
11501        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11502            throw new SecurityException("killProcessesBelowForeground() only available to system");
11503        }
11504
11505        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11506    }
11507
11508    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11509        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11510            throw new SecurityException("killProcessesBelowAdj() only available to system");
11511        }
11512
11513        boolean killed = false;
11514        synchronized (mPidsSelfLocked) {
11515            final int size = mPidsSelfLocked.size();
11516            for (int i = 0; i < size; i++) {
11517                final int pid = mPidsSelfLocked.keyAt(i);
11518                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11519                if (proc == null) continue;
11520
11521                final int adj = proc.setAdj;
11522                if (adj > belowAdj && !proc.killedByAm) {
11523                    proc.kill(reason, true);
11524                    killed = true;
11525                }
11526            }
11527        }
11528        return killed;
11529    }
11530
11531    @Override
11532    public void hang(final IBinder who, boolean allowRestart) {
11533        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11534                != PackageManager.PERMISSION_GRANTED) {
11535            throw new SecurityException("Requires permission "
11536                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11537        }
11538
11539        final IBinder.DeathRecipient death = new DeathRecipient() {
11540            @Override
11541            public void binderDied() {
11542                synchronized (this) {
11543                    notifyAll();
11544                }
11545            }
11546        };
11547
11548        try {
11549            who.linkToDeath(death, 0);
11550        } catch (RemoteException e) {
11551            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11552            return;
11553        }
11554
11555        synchronized (this) {
11556            Watchdog.getInstance().setAllowRestart(allowRestart);
11557            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11558            synchronized (death) {
11559                while (who.isBinderAlive()) {
11560                    try {
11561                        death.wait();
11562                    } catch (InterruptedException e) {
11563                    }
11564                }
11565            }
11566            Watchdog.getInstance().setAllowRestart(true);
11567        }
11568    }
11569
11570    @Override
11571    public void restart() {
11572        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11573                != PackageManager.PERMISSION_GRANTED) {
11574            throw new SecurityException("Requires permission "
11575                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11576        }
11577
11578        Log.i(TAG, "Sending shutdown broadcast...");
11579
11580        BroadcastReceiver br = new BroadcastReceiver() {
11581            @Override public void onReceive(Context context, Intent intent) {
11582                // Now the broadcast is done, finish up the low-level shutdown.
11583                Log.i(TAG, "Shutting down activity manager...");
11584                shutdown(10000);
11585                Log.i(TAG, "Shutdown complete, restarting!");
11586                Process.killProcess(Process.myPid());
11587                System.exit(10);
11588            }
11589        };
11590
11591        // First send the high-level shut down broadcast.
11592        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11593        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11594        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11595        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11596        mContext.sendOrderedBroadcastAsUser(intent,
11597                UserHandle.ALL, null, br, mHandler, 0, null, null);
11598        */
11599        br.onReceive(mContext, intent);
11600    }
11601
11602    private long getLowRamTimeSinceIdle(long now) {
11603        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11604    }
11605
11606    @Override
11607    public void performIdleMaintenance() {
11608        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11609                != PackageManager.PERMISSION_GRANTED) {
11610            throw new SecurityException("Requires permission "
11611                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11612        }
11613
11614        synchronized (this) {
11615            final long now = SystemClock.uptimeMillis();
11616            final long timeSinceLastIdle = now - mLastIdleTime;
11617            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11618            mLastIdleTime = now;
11619            mLowRamTimeSinceLastIdle = 0;
11620            if (mLowRamStartTime != 0) {
11621                mLowRamStartTime = now;
11622            }
11623
11624            StringBuilder sb = new StringBuilder(128);
11625            sb.append("Idle maintenance over ");
11626            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11627            sb.append(" low RAM for ");
11628            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11629            Slog.i(TAG, sb.toString());
11630
11631            // If at least 1/3 of our time since the last idle period has been spent
11632            // with RAM low, then we want to kill processes.
11633            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11634
11635            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11636                ProcessRecord proc = mLruProcesses.get(i);
11637                if (proc.notCachedSinceIdle) {
11638                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11639                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11640                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11641                        if (doKilling && proc.initialIdlePss != 0
11642                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11643                            sb = new StringBuilder(128);
11644                            sb.append("Kill");
11645                            sb.append(proc.processName);
11646                            sb.append(" in idle maint: pss=");
11647                            sb.append(proc.lastPss);
11648                            sb.append(", initialPss=");
11649                            sb.append(proc.initialIdlePss);
11650                            sb.append(", period=");
11651                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11652                            sb.append(", lowRamPeriod=");
11653                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11654                            Slog.wtfQuiet(TAG, sb.toString());
11655                            proc.kill("idle maint (pss " + proc.lastPss
11656                                    + " from " + proc.initialIdlePss + ")", true);
11657                        }
11658                    }
11659                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11660                    proc.notCachedSinceIdle = true;
11661                    proc.initialIdlePss = 0;
11662                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11663                            mTestPssMode, isSleeping(), now);
11664                }
11665            }
11666
11667            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11668            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11669        }
11670    }
11671
11672    private void retrieveSettings() {
11673        final ContentResolver resolver = mContext.getContentResolver();
11674        String debugApp = Settings.Global.getString(resolver, Settings.Global.DEBUG_APP);
11675        boolean waitForDebugger = Settings.Global.getInt(
11676            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11677        boolean alwaysFinishActivities = Settings.Global.getInt(
11678            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11679        boolean forceRtl = Settings.Global.getInt(
11680                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11681        int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
11682        boolean forceResizable = Settings.Global.getInt(
11683                resolver, Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
11684                defaultForceResizable) != 0;
11685        // Transfer any global setting for forcing RTL layout, into a System Property
11686        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11687
11688        Configuration configuration = new Configuration();
11689        Settings.System.getConfiguration(resolver, configuration);
11690        if (forceRtl) {
11691            // This will take care of setting the correct layout direction flags
11692            configuration.setLayoutDirection(configuration.locale);
11693        }
11694
11695        synchronized (this) {
11696            mDebugApp = mOrigDebugApp = debugApp;
11697            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11698            mAlwaysFinishActivities = alwaysFinishActivities;
11699            mForceResizableActivites = forceResizable;
11700            // This happens before any activities are started, so we can
11701            // change mConfiguration in-place.
11702            updateConfigurationLocked(configuration, null, true);
11703            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11704                    "Initial config: " + mConfiguration);
11705        }
11706    }
11707
11708    /** Loads resources after the current configuration has been set. */
11709    private void loadResourcesOnSystemReady() {
11710        final Resources res = mContext.getResources();
11711        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11712        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11713        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11714    }
11715
11716    public boolean testIsSystemReady() {
11717        // no need to synchronize(this) just to read & return the value
11718        return mSystemReady;
11719    }
11720
11721    private static File getCalledPreBootReceiversFile() {
11722        File dataDir = Environment.getDataDirectory();
11723        File systemDir = new File(dataDir, "system");
11724        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11725        return fname;
11726    }
11727
11728    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11729        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11730        File file = getCalledPreBootReceiversFile();
11731        FileInputStream fis = null;
11732        try {
11733            fis = new FileInputStream(file);
11734            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11735            int fvers = dis.readInt();
11736            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11737                String vers = dis.readUTF();
11738                String codename = dis.readUTF();
11739                String build = dis.readUTF();
11740                if (android.os.Build.VERSION.RELEASE.equals(vers)
11741                        && android.os.Build.VERSION.CODENAME.equals(codename)
11742                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11743                    int num = dis.readInt();
11744                    while (num > 0) {
11745                        num--;
11746                        String pkg = dis.readUTF();
11747                        String cls = dis.readUTF();
11748                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11749                    }
11750                }
11751            }
11752        } catch (FileNotFoundException e) {
11753        } catch (IOException e) {
11754            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11755        } finally {
11756            if (fis != null) {
11757                try {
11758                    fis.close();
11759                } catch (IOException e) {
11760                }
11761            }
11762        }
11763        return lastDoneReceivers;
11764    }
11765
11766    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11767        File file = getCalledPreBootReceiversFile();
11768        FileOutputStream fos = null;
11769        DataOutputStream dos = null;
11770        try {
11771            fos = new FileOutputStream(file);
11772            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11773            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11774            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11775            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11776            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11777            dos.writeInt(list.size());
11778            for (int i=0; i<list.size(); i++) {
11779                dos.writeUTF(list.get(i).getPackageName());
11780                dos.writeUTF(list.get(i).getClassName());
11781            }
11782        } catch (IOException e) {
11783            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11784            file.delete();
11785        } finally {
11786            FileUtils.sync(fos);
11787            if (dos != null) {
11788                try {
11789                    dos.close();
11790                } catch (IOException e) {
11791                    // TODO Auto-generated catch block
11792                    e.printStackTrace();
11793                }
11794            }
11795        }
11796    }
11797
11798    final class PreBootContinuation extends IIntentReceiver.Stub {
11799        final Intent intent;
11800        final Runnable onFinishCallback;
11801        final ArrayList<ComponentName> doneReceivers;
11802        final List<ResolveInfo> ris;
11803        final int[] users;
11804        int lastRi = -1;
11805        int curRi = 0;
11806        int curUser = 0;
11807
11808        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11809                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11810            intent = _intent;
11811            onFinishCallback = _onFinishCallback;
11812            doneReceivers = _doneReceivers;
11813            ris = _ris;
11814            users = _users;
11815        }
11816
11817        void go() {
11818            if (lastRi != curRi) {
11819                ActivityInfo ai = ris.get(curRi).activityInfo;
11820                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11821                intent.setComponent(comp);
11822                doneReceivers.add(comp);
11823                lastRi = curRi;
11824                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11825                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11826            }
11827            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11828                    + " for user " + users[curUser]);
11829            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11830            broadcastIntentLocked(null, null, intent, null, this,
11831                    0, null, null, null, AppOpsManager.OP_NONE,
11832                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11833        }
11834
11835        public void performReceive(Intent intent, int resultCode,
11836                String data, Bundle extras, boolean ordered,
11837                boolean sticky, int sendingUser) {
11838            curUser++;
11839            if (curUser >= users.length) {
11840                curUser = 0;
11841                curRi++;
11842                if (curRi >= ris.size()) {
11843                    // All done sending broadcasts!
11844                    if (onFinishCallback != null) {
11845                        // The raw IIntentReceiver interface is called
11846                        // with the AM lock held, so redispatch to
11847                        // execute our code without the lock.
11848                        mHandler.post(onFinishCallback);
11849                    }
11850                    return;
11851                }
11852            }
11853            go();
11854        }
11855    }
11856
11857    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11858            ArrayList<ComponentName> doneReceivers) {
11859        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11860        List<ResolveInfo> ris = null;
11861        try {
11862            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11863                    intent, null, 0, UserHandle.USER_SYSTEM);
11864        } catch (RemoteException e) {
11865        }
11866        if (ris == null) {
11867            return false;
11868        }
11869        for (int i=ris.size()-1; i>=0; i--) {
11870            if ((ris.get(i).activityInfo.applicationInfo.flags
11871                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11872                ris.remove(i);
11873            }
11874        }
11875        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11876
11877        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11878        for (int i=0; i<ris.size(); i++) {
11879            ActivityInfo ai = ris.get(i).activityInfo;
11880            ComponentName comp = new ComponentName(ai.packageName, ai.name);
11881            if (lastDoneReceivers.contains(comp)) {
11882                // We already did the pre boot receiver for this app with the current
11883                // platform version, so don't do it again...
11884                ris.remove(i);
11885                i--;
11886                // ...however, do keep it as one that has been done, so we don't
11887                // forget about it when rewriting the file of last done receivers.
11888                doneReceivers.add(comp);
11889            }
11890        }
11891
11892        if (ris.size() <= 0) {
11893            return false;
11894        }
11895
11896        // TODO: can we still do this with per user encryption?
11897        final int[] users = mUserController.getUsers();
11898        if (users.length <= 0) {
11899            return false;
11900        }
11901
11902        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11903                ris, users);
11904        cont.go();
11905        return true;
11906    }
11907
11908    public void systemReady(final Runnable goingCallback) {
11909        synchronized(this) {
11910            if (mSystemReady) {
11911                // If we're done calling all the receivers, run the next "boot phase" passed in
11912                // by the SystemServer
11913                if (goingCallback != null) {
11914                    goingCallback.run();
11915                }
11916                return;
11917            }
11918
11919            mLocalDeviceIdleController
11920                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11921
11922            // Make sure we have the current profile info, since it is needed for
11923            // security checks.
11924            mUserController.updateCurrentProfileIdsLocked();
11925
11926            mRecentTasks.clear();
11927            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
11928            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11929            mTaskPersister.startPersisting();
11930
11931            // Check to see if there are any update receivers to run.
11932            if (!mDidUpdate) {
11933                if (mWaitingUpdate) {
11934                    return;
11935                }
11936                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11937                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11938                    public void run() {
11939                        synchronized (ActivityManagerService.this) {
11940                            mDidUpdate = true;
11941                        }
11942                        showBootMessage(mContext.getText(
11943                                R.string.android_upgrading_complete),
11944                                false);
11945                        writeLastDonePreBootReceivers(doneReceivers);
11946                        systemReady(goingCallback);
11947                    }
11948                }, doneReceivers);
11949
11950                if (mWaitingUpdate) {
11951                    return;
11952                }
11953                mDidUpdate = true;
11954            }
11955
11956            mAppOpsService.systemReady();
11957            mSystemReady = true;
11958        }
11959
11960        ArrayList<ProcessRecord> procsToKill = null;
11961        synchronized(mPidsSelfLocked) {
11962            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11963                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11964                if (!isAllowedWhileBooting(proc.info)){
11965                    if (procsToKill == null) {
11966                        procsToKill = new ArrayList<ProcessRecord>();
11967                    }
11968                    procsToKill.add(proc);
11969                }
11970            }
11971        }
11972
11973        synchronized(this) {
11974            if (procsToKill != null) {
11975                for (int i=procsToKill.size()-1; i>=0; i--) {
11976                    ProcessRecord proc = procsToKill.get(i);
11977                    Slog.i(TAG, "Removing system update proc: " + proc);
11978                    removeProcessLocked(proc, true, false, "system update done");
11979                }
11980            }
11981
11982            // Now that we have cleaned up any update processes, we
11983            // are ready to start launching real processes and know that
11984            // we won't trample on them any more.
11985            mProcessesReady = true;
11986        }
11987
11988        Slog.i(TAG, "System now ready");
11989        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11990            SystemClock.uptimeMillis());
11991
11992        synchronized(this) {
11993            // Make sure we have no pre-ready processes sitting around.
11994
11995            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11996                ResolveInfo ri = mContext.getPackageManager()
11997                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11998                                STOCK_PM_FLAGS);
11999                CharSequence errorMsg = null;
12000                if (ri != null) {
12001                    ActivityInfo ai = ri.activityInfo;
12002                    ApplicationInfo app = ai.applicationInfo;
12003                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12004                        mTopAction = Intent.ACTION_FACTORY_TEST;
12005                        mTopData = null;
12006                        mTopComponent = new ComponentName(app.packageName,
12007                                ai.name);
12008                    } else {
12009                        errorMsg = mContext.getResources().getText(
12010                                com.android.internal.R.string.factorytest_not_system);
12011                    }
12012                } else {
12013                    errorMsg = mContext.getResources().getText(
12014                            com.android.internal.R.string.factorytest_no_action);
12015                }
12016                if (errorMsg != null) {
12017                    mTopAction = null;
12018                    mTopData = null;
12019                    mTopComponent = null;
12020                    Message msg = Message.obtain();
12021                    msg.what = SHOW_FACTORY_ERROR_MSG;
12022                    msg.getData().putCharSequence("msg", errorMsg);
12023                    mUiHandler.sendMessage(msg);
12024                }
12025            }
12026        }
12027
12028        retrieveSettings();
12029        loadResourcesOnSystemReady();
12030        final int currentUserId;
12031        synchronized (this) {
12032            currentUserId = mUserController.getCurrentUserIdLocked();
12033            readGrantedUriPermissionsLocked();
12034        }
12035
12036        if (goingCallback != null) goingCallback.run();
12037
12038
12039        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12040                Integer.toString(currentUserId), currentUserId);
12041        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12042                Integer.toString(currentUserId), currentUserId);
12043        mSystemServiceManager.startUser(currentUserId);
12044
12045        synchronized (this) {
12046            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12047                try {
12048                    List apps = AppGlobals.getPackageManager().
12049                        getPersistentApplications(STOCK_PM_FLAGS);
12050                    if (apps != null) {
12051                        int N = apps.size();
12052                        int i;
12053                        for (i=0; i<N; i++) {
12054                            ApplicationInfo info
12055                                = (ApplicationInfo)apps.get(i);
12056                            if (info != null &&
12057                                    !info.packageName.equals("android")) {
12058                                addAppLocked(info, false, null /* ABI override */);
12059                            }
12060                        }
12061                    }
12062                } catch (RemoteException ex) {
12063                    // pm is in same process, this will never happen.
12064                }
12065            }
12066
12067            enableSystemUserApps();
12068
12069            // Start up initial activity.
12070            mBooting = true;
12071            startHomeActivityLocked(currentUserId, "systemReady");
12072
12073            try {
12074                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12075                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12076                            + " data partition or your device will be unstable.");
12077                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
12078                }
12079            } catch (RemoteException e) {
12080            }
12081
12082            if (!Build.isBuildConsistent()) {
12083                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12084                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
12085            }
12086
12087            long ident = Binder.clearCallingIdentity();
12088            try {
12089                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12090                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12091                        | Intent.FLAG_RECEIVER_FOREGROUND);
12092                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12093                broadcastIntentLocked(null, null, intent,
12094                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12095                        null, false, false, MY_PID, Process.SYSTEM_UID,
12096                        currentUserId);
12097                intent = new Intent(Intent.ACTION_USER_STARTING);
12098                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12099                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12100                broadcastIntentLocked(null, null, intent,
12101                        null, new IIntentReceiver.Stub() {
12102                            @Override
12103                            public void performReceive(Intent intent, int resultCode, String data,
12104                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12105                                    throws RemoteException {
12106                            }
12107                        }, 0, null, null,
12108                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12109                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12110            } catch (Throwable t) {
12111                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12112            } finally {
12113                Binder.restoreCallingIdentity(ident);
12114            }
12115            mStackSupervisor.resumeTopActivitiesLocked();
12116            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12117        }
12118    }
12119
12120    private void enableSystemUserApps() {
12121        // For system user, enable apps based on the following conditions:
12122        // - app is whitelisted; or has no launcher icons; or has INTERACT_ACROSS_USERS permission
12123        // - app is not in the blacklist
12124        if (UserManager.isSplitSystemUser()) {
12125            AppsQueryHelper queryHelper = new AppsQueryHelper(mContext);
12126            Set<String> enableApps = new HashSet<>();
12127            enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
12128                            | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
12129                            | AppsQueryHelper.GET_DEFAULT_IMES,
12130                            /* systemAppsOnly */ true, UserHandle.SYSTEM));
12131            ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
12132            enableApps.addAll(wlApps);
12133            ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
12134            enableApps.removeAll(blApps);
12135
12136            List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true,
12137                    UserHandle.SYSTEM);
12138            final int systemAppsSize = systemApps.size();
12139            for (int i = 0; i < systemAppsSize; i++) {
12140                String pName = systemApps.get(i);
12141                boolean enable = enableApps.contains(pName);
12142                try {
12143                    if (enable) {
12144                        AppGlobals.getPackageManager().installExistingPackageAsUser(pName,
12145                                UserHandle.USER_SYSTEM);
12146                    } else {
12147                        AppGlobals.getPackageManager().deletePackageAsUser(pName, null,
12148                                UserHandle.USER_SYSTEM, PackageManager.DELETE_SYSTEM_APP);
12149                    }
12150                } catch (RemoteException e) {
12151                    Slog.e(TAG, "Error occured when processing package " + pName, e);
12152                }
12153            }
12154        }
12155    }
12156
12157    private boolean makeAppCrashingLocked(ProcessRecord app,
12158            String shortMsg, String longMsg, String stackTrace) {
12159        app.crashing = true;
12160        app.crashingReport = generateProcessError(app,
12161                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12162        startAppProblemLocked(app);
12163        app.stopFreezingAllLocked();
12164        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12165    }
12166
12167    private void makeAppNotRespondingLocked(ProcessRecord app,
12168            String activity, String shortMsg, String longMsg) {
12169        app.notResponding = true;
12170        app.notRespondingReport = generateProcessError(app,
12171                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12172                activity, shortMsg, longMsg, null);
12173        startAppProblemLocked(app);
12174        app.stopFreezingAllLocked();
12175    }
12176
12177    /**
12178     * Generate a process error record, suitable for attachment to a ProcessRecord.
12179     *
12180     * @param app The ProcessRecord in which the error occurred.
12181     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12182     *                      ActivityManager.AppErrorStateInfo
12183     * @param activity The activity associated with the crash, if known.
12184     * @param shortMsg Short message describing the crash.
12185     * @param longMsg Long message describing the crash.
12186     * @param stackTrace Full crash stack trace, may be null.
12187     *
12188     * @return Returns a fully-formed AppErrorStateInfo record.
12189     */
12190    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12191            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12192        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12193
12194        report.condition = condition;
12195        report.processName = app.processName;
12196        report.pid = app.pid;
12197        report.uid = app.info.uid;
12198        report.tag = activity;
12199        report.shortMsg = shortMsg;
12200        report.longMsg = longMsg;
12201        report.stackTrace = stackTrace;
12202
12203        return report;
12204    }
12205
12206    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12207        synchronized (this) {
12208            app.crashing = false;
12209            app.crashingReport = null;
12210            app.notResponding = false;
12211            app.notRespondingReport = null;
12212            if (app.anrDialog == fromDialog) {
12213                app.anrDialog = null;
12214            }
12215            if (app.waitDialog == fromDialog) {
12216                app.waitDialog = null;
12217            }
12218            if (app.pid > 0 && app.pid != MY_PID) {
12219                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12220                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12221                app.kill("user request after error", true);
12222            }
12223        }
12224    }
12225
12226    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12227            String shortMsg, String longMsg, String stackTrace) {
12228        long now = SystemClock.uptimeMillis();
12229
12230        Long crashTime;
12231        if (!app.isolated) {
12232            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12233        } else {
12234            crashTime = null;
12235        }
12236        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12237            // This process loses!
12238            Slog.w(TAG, "Process " + app.info.processName
12239                    + " has crashed too many times: killing!");
12240            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12241                    app.userId, app.info.processName, app.uid);
12242            mStackSupervisor.handleAppCrashLocked(app);
12243            if (!app.persistent) {
12244                // We don't want to start this process again until the user
12245                // explicitly does so...  but for persistent process, we really
12246                // need to keep it running.  If a persistent process is actually
12247                // repeatedly crashing, then badness for everyone.
12248                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12249                        app.info.processName);
12250                if (!app.isolated) {
12251                    // XXX We don't have a way to mark isolated processes
12252                    // as bad, since they don't have a peristent identity.
12253                    mBadProcesses.put(app.info.processName, app.uid,
12254                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12255                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12256                }
12257                app.bad = true;
12258                app.removed = true;
12259                // Don't let services in this process be restarted and potentially
12260                // annoy the user repeatedly.  Unless it is persistent, since those
12261                // processes run critical code.
12262                removeProcessLocked(app, false, false, "crash");
12263                mStackSupervisor.resumeTopActivitiesLocked();
12264                return false;
12265            }
12266            mStackSupervisor.resumeTopActivitiesLocked();
12267        } else {
12268            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12269        }
12270
12271        // Bump up the crash count of any services currently running in the proc.
12272        for (int i=app.services.size()-1; i>=0; i--) {
12273            // Any services running in the application need to be placed
12274            // back in the pending list.
12275            ServiceRecord sr = app.services.valueAt(i);
12276            sr.crashCount++;
12277        }
12278
12279        // If the crashing process is what we consider to be the "home process" and it has been
12280        // replaced by a third-party app, clear the package preferred activities from packages
12281        // with a home activity running in the process to prevent a repeatedly crashing app
12282        // from blocking the user to manually clear the list.
12283        final ArrayList<ActivityRecord> activities = app.activities;
12284        if (app == mHomeProcess && activities.size() > 0
12285                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12286            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12287                final ActivityRecord r = activities.get(activityNdx);
12288                if (r.isHomeActivity()) {
12289                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12290                    try {
12291                        ActivityThread.getPackageManager()
12292                                .clearPackagePreferredActivities(r.packageName);
12293                    } catch (RemoteException c) {
12294                        // pm is in same process, this will never happen.
12295                    }
12296                }
12297            }
12298        }
12299
12300        if (!app.isolated) {
12301            // XXX Can't keep track of crash times for isolated processes,
12302            // because they don't have a perisistent identity.
12303            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12304        }
12305
12306        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12307        return true;
12308    }
12309
12310    void startAppProblemLocked(ProcessRecord app) {
12311        // If this app is not running under the current user, then we
12312        // can't give it a report button because that would require
12313        // launching the report UI under a different user.
12314        app.errorReportReceiver = null;
12315
12316        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12317            if (app.userId == userId) {
12318                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12319                        mContext, app.info.packageName, app.info.flags);
12320            }
12321        }
12322        skipCurrentReceiverLocked(app);
12323    }
12324
12325    void skipCurrentReceiverLocked(ProcessRecord app) {
12326        for (BroadcastQueue queue : mBroadcastQueues) {
12327            queue.skipCurrentReceiverLocked(app);
12328        }
12329    }
12330
12331    /**
12332     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12333     * The application process will exit immediately after this call returns.
12334     * @param app object of the crashing app, null for the system server
12335     * @param crashInfo describing the exception
12336     */
12337    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12338        ProcessRecord r = findAppProcess(app, "Crash");
12339        final String processName = app == null ? "system_server"
12340                : (r == null ? "unknown" : r.processName);
12341
12342        handleApplicationCrashInner("crash", r, processName, crashInfo);
12343    }
12344
12345    /* Native crash reporting uses this inner version because it needs to be somewhat
12346     * decoupled from the AM-managed cleanup lifecycle
12347     */
12348    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12349            ApplicationErrorReport.CrashInfo crashInfo) {
12350        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12351                UserHandle.getUserId(Binder.getCallingUid()), processName,
12352                r == null ? -1 : r.info.flags,
12353                crashInfo.exceptionClassName,
12354                crashInfo.exceptionMessage,
12355                crashInfo.throwFileName,
12356                crashInfo.throwLineNumber);
12357
12358        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12359
12360        crashApplication(r, crashInfo);
12361    }
12362
12363    public void handleApplicationStrictModeViolation(
12364            IBinder app,
12365            int violationMask,
12366            StrictMode.ViolationInfo info) {
12367        ProcessRecord r = findAppProcess(app, "StrictMode");
12368        if (r == null) {
12369            return;
12370        }
12371
12372        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12373            Integer stackFingerprint = info.hashCode();
12374            boolean logIt = true;
12375            synchronized (mAlreadyLoggedViolatedStacks) {
12376                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12377                    logIt = false;
12378                    // TODO: sub-sample into EventLog for these, with
12379                    // the info.durationMillis?  Then we'd get
12380                    // the relative pain numbers, without logging all
12381                    // the stack traces repeatedly.  We'd want to do
12382                    // likewise in the client code, which also does
12383                    // dup suppression, before the Binder call.
12384                } else {
12385                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12386                        mAlreadyLoggedViolatedStacks.clear();
12387                    }
12388                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12389                }
12390            }
12391            if (logIt) {
12392                logStrictModeViolationToDropBox(r, info);
12393            }
12394        }
12395
12396        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12397            AppErrorResult result = new AppErrorResult();
12398            synchronized (this) {
12399                final long origId = Binder.clearCallingIdentity();
12400
12401                Message msg = Message.obtain();
12402                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12403                HashMap<String, Object> data = new HashMap<String, Object>();
12404                data.put("result", result);
12405                data.put("app", r);
12406                data.put("violationMask", violationMask);
12407                data.put("info", info);
12408                msg.obj = data;
12409                mUiHandler.sendMessage(msg);
12410
12411                Binder.restoreCallingIdentity(origId);
12412            }
12413            int res = result.get();
12414            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12415        }
12416    }
12417
12418    // Depending on the policy in effect, there could be a bunch of
12419    // these in quick succession so we try to batch these together to
12420    // minimize disk writes, number of dropbox entries, and maximize
12421    // compression, by having more fewer, larger records.
12422    private void logStrictModeViolationToDropBox(
12423            ProcessRecord process,
12424            StrictMode.ViolationInfo info) {
12425        if (info == null) {
12426            return;
12427        }
12428        final boolean isSystemApp = process == null ||
12429                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12430                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12431        final String processName = process == null ? "unknown" : process.processName;
12432        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12433        final DropBoxManager dbox = (DropBoxManager)
12434                mContext.getSystemService(Context.DROPBOX_SERVICE);
12435
12436        // Exit early if the dropbox isn't configured to accept this report type.
12437        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12438
12439        boolean bufferWasEmpty;
12440        boolean needsFlush;
12441        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12442        synchronized (sb) {
12443            bufferWasEmpty = sb.length() == 0;
12444            appendDropBoxProcessHeaders(process, processName, sb);
12445            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12446            sb.append("System-App: ").append(isSystemApp).append("\n");
12447            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12448            if (info.violationNumThisLoop != 0) {
12449                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12450            }
12451            if (info.numAnimationsRunning != 0) {
12452                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12453            }
12454            if (info.broadcastIntentAction != null) {
12455                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12456            }
12457            if (info.durationMillis != -1) {
12458                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12459            }
12460            if (info.numInstances != -1) {
12461                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12462            }
12463            if (info.tags != null) {
12464                for (String tag : info.tags) {
12465                    sb.append("Span-Tag: ").append(tag).append("\n");
12466                }
12467            }
12468            sb.append("\n");
12469            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12470                sb.append(info.crashInfo.stackTrace);
12471                sb.append("\n");
12472            }
12473            if (info.message != null) {
12474                sb.append(info.message);
12475                sb.append("\n");
12476            }
12477
12478            // Only buffer up to ~64k.  Various logging bits truncate
12479            // things at 128k.
12480            needsFlush = (sb.length() > 64 * 1024);
12481        }
12482
12483        // Flush immediately if the buffer's grown too large, or this
12484        // is a non-system app.  Non-system apps are isolated with a
12485        // different tag & policy and not batched.
12486        //
12487        // Batching is useful during internal testing with
12488        // StrictMode settings turned up high.  Without batching,
12489        // thousands of separate files could be created on boot.
12490        if (!isSystemApp || needsFlush) {
12491            new Thread("Error dump: " + dropboxTag) {
12492                @Override
12493                public void run() {
12494                    String report;
12495                    synchronized (sb) {
12496                        report = sb.toString();
12497                        sb.delete(0, sb.length());
12498                        sb.trimToSize();
12499                    }
12500                    if (report.length() != 0) {
12501                        dbox.addText(dropboxTag, report);
12502                    }
12503                }
12504            }.start();
12505            return;
12506        }
12507
12508        // System app batching:
12509        if (!bufferWasEmpty) {
12510            // An existing dropbox-writing thread is outstanding, so
12511            // we don't need to start it up.  The existing thread will
12512            // catch the buffer appends we just did.
12513            return;
12514        }
12515
12516        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12517        // (After this point, we shouldn't access AMS internal data structures.)
12518        new Thread("Error dump: " + dropboxTag) {
12519            @Override
12520            public void run() {
12521                // 5 second sleep to let stacks arrive and be batched together
12522                try {
12523                    Thread.sleep(5000);  // 5 seconds
12524                } catch (InterruptedException e) {}
12525
12526                String errorReport;
12527                synchronized (mStrictModeBuffer) {
12528                    errorReport = mStrictModeBuffer.toString();
12529                    if (errorReport.length() == 0) {
12530                        return;
12531                    }
12532                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12533                    mStrictModeBuffer.trimToSize();
12534                }
12535                dbox.addText(dropboxTag, errorReport);
12536            }
12537        }.start();
12538    }
12539
12540    /**
12541     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12542     * @param app object of the crashing app, null for the system server
12543     * @param tag reported by the caller
12544     * @param system whether this wtf is coming from the system
12545     * @param crashInfo describing the context of the error
12546     * @return true if the process should exit immediately (WTF is fatal)
12547     */
12548    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12549            final ApplicationErrorReport.CrashInfo crashInfo) {
12550        final int callingUid = Binder.getCallingUid();
12551        final int callingPid = Binder.getCallingPid();
12552
12553        if (system) {
12554            // If this is coming from the system, we could very well have low-level
12555            // system locks held, so we want to do this all asynchronously.  And we
12556            // never want this to become fatal, so there is that too.
12557            mHandler.post(new Runnable() {
12558                @Override public void run() {
12559                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12560                }
12561            });
12562            return false;
12563        }
12564
12565        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12566                crashInfo);
12567
12568        if (r != null && r.pid != Process.myPid() &&
12569                Settings.Global.getInt(mContext.getContentResolver(),
12570                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12571            crashApplication(r, crashInfo);
12572            return true;
12573        } else {
12574            return false;
12575        }
12576    }
12577
12578    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12579            final ApplicationErrorReport.CrashInfo crashInfo) {
12580        final ProcessRecord r = findAppProcess(app, "WTF");
12581        final String processName = app == null ? "system_server"
12582                : (r == null ? "unknown" : r.processName);
12583
12584        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12585                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12586
12587        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12588
12589        return r;
12590    }
12591
12592    /**
12593     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12594     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12595     */
12596    private ProcessRecord findAppProcess(IBinder app, String reason) {
12597        if (app == null) {
12598            return null;
12599        }
12600
12601        synchronized (this) {
12602            final int NP = mProcessNames.getMap().size();
12603            for (int ip=0; ip<NP; ip++) {
12604                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12605                final int NA = apps.size();
12606                for (int ia=0; ia<NA; ia++) {
12607                    ProcessRecord p = apps.valueAt(ia);
12608                    if (p.thread != null && p.thread.asBinder() == app) {
12609                        return p;
12610                    }
12611                }
12612            }
12613
12614            Slog.w(TAG, "Can't find mystery application for " + reason
12615                    + " from pid=" + Binder.getCallingPid()
12616                    + " uid=" + Binder.getCallingUid() + ": " + app);
12617            return null;
12618        }
12619    }
12620
12621    /**
12622     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12623     * to append various headers to the dropbox log text.
12624     */
12625    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12626            StringBuilder sb) {
12627        // Watchdog thread ends up invoking this function (with
12628        // a null ProcessRecord) to add the stack file to dropbox.
12629        // Do not acquire a lock on this (am) in such cases, as it
12630        // could cause a potential deadlock, if and when watchdog
12631        // is invoked due to unavailability of lock on am and it
12632        // would prevent watchdog from killing system_server.
12633        if (process == null) {
12634            sb.append("Process: ").append(processName).append("\n");
12635            return;
12636        }
12637        // Note: ProcessRecord 'process' is guarded by the service
12638        // instance.  (notably process.pkgList, which could otherwise change
12639        // concurrently during execution of this method)
12640        synchronized (this) {
12641            sb.append("Process: ").append(processName).append("\n");
12642            int flags = process.info.flags;
12643            IPackageManager pm = AppGlobals.getPackageManager();
12644            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12645            for (int ip=0; ip<process.pkgList.size(); ip++) {
12646                String pkg = process.pkgList.keyAt(ip);
12647                sb.append("Package: ").append(pkg);
12648                try {
12649                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12650                    if (pi != null) {
12651                        sb.append(" v").append(pi.versionCode);
12652                        if (pi.versionName != null) {
12653                            sb.append(" (").append(pi.versionName).append(")");
12654                        }
12655                    }
12656                } catch (RemoteException e) {
12657                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12658                }
12659                sb.append("\n");
12660            }
12661        }
12662    }
12663
12664    private static String processClass(ProcessRecord process) {
12665        if (process == null || process.pid == MY_PID) {
12666            return "system_server";
12667        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12668            return "system_app";
12669        } else {
12670            return "data_app";
12671        }
12672    }
12673
12674    /**
12675     * Write a description of an error (crash, WTF, ANR) to the drop box.
12676     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12677     * @param process which caused the error, null means the system server
12678     * @param activity which triggered the error, null if unknown
12679     * @param parent activity related to the error, null if unknown
12680     * @param subject line related to the error, null if absent
12681     * @param report in long form describing the error, null if absent
12682     * @param logFile to include in the report, null if none
12683     * @param crashInfo giving an application stack trace, null if absent
12684     */
12685    public void addErrorToDropBox(String eventType,
12686            ProcessRecord process, String processName, ActivityRecord activity,
12687            ActivityRecord parent, String subject,
12688            final String report, final File logFile,
12689            final ApplicationErrorReport.CrashInfo crashInfo) {
12690        // NOTE -- this must never acquire the ActivityManagerService lock,
12691        // otherwise the watchdog may be prevented from resetting the system.
12692
12693        final String dropboxTag = processClass(process) + "_" + eventType;
12694        final DropBoxManager dbox = (DropBoxManager)
12695                mContext.getSystemService(Context.DROPBOX_SERVICE);
12696
12697        // Exit early if the dropbox isn't configured to accept this report type.
12698        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12699
12700        final StringBuilder sb = new StringBuilder(1024);
12701        appendDropBoxProcessHeaders(process, processName, sb);
12702        if (activity != null) {
12703            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12704        }
12705        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12706            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12707        }
12708        if (parent != null && parent != activity) {
12709            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12710        }
12711        if (subject != null) {
12712            sb.append("Subject: ").append(subject).append("\n");
12713        }
12714        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12715        if (Debug.isDebuggerConnected()) {
12716            sb.append("Debugger: Connected\n");
12717        }
12718        sb.append("\n");
12719
12720        // Do the rest in a worker thread to avoid blocking the caller on I/O
12721        // (After this point, we shouldn't access AMS internal data structures.)
12722        Thread worker = new Thread("Error dump: " + dropboxTag) {
12723            @Override
12724            public void run() {
12725                if (report != null) {
12726                    sb.append(report);
12727                }
12728                if (logFile != null) {
12729                    try {
12730                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12731                                    "\n\n[[TRUNCATED]]"));
12732                    } catch (IOException e) {
12733                        Slog.e(TAG, "Error reading " + logFile, e);
12734                    }
12735                }
12736                if (crashInfo != null && crashInfo.stackTrace != null) {
12737                    sb.append(crashInfo.stackTrace);
12738                }
12739
12740                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12741                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12742                if (lines > 0) {
12743                    sb.append("\n");
12744
12745                    // Merge several logcat streams, and take the last N lines
12746                    InputStreamReader input = null;
12747                    try {
12748                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12749                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12750                                "-b", "crash",
12751                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12752
12753                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12754                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12755                        input = new InputStreamReader(logcat.getInputStream());
12756
12757                        int num;
12758                        char[] buf = new char[8192];
12759                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12760                    } catch (IOException e) {
12761                        Slog.e(TAG, "Error running logcat", e);
12762                    } finally {
12763                        if (input != null) try { input.close(); } catch (IOException e) {}
12764                    }
12765                }
12766
12767                dbox.addText(dropboxTag, sb.toString());
12768            }
12769        };
12770
12771        if (process == null) {
12772            // If process is null, we are being called from some internal code
12773            // and may be about to die -- run this synchronously.
12774            worker.run();
12775        } else {
12776            worker.start();
12777        }
12778    }
12779
12780    /**
12781     * Bring up the "unexpected error" dialog box for a crashing app.
12782     * Deal with edge cases (intercepts from instrumented applications,
12783     * ActivityController, error intent receivers, that sort of thing).
12784     * @param r the application crashing
12785     * @param crashInfo describing the failure
12786     */
12787    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12788        long timeMillis = System.currentTimeMillis();
12789        String shortMsg = crashInfo.exceptionClassName;
12790        String longMsg = crashInfo.exceptionMessage;
12791        String stackTrace = crashInfo.stackTrace;
12792        if (shortMsg != null && longMsg != null) {
12793            longMsg = shortMsg + ": " + longMsg;
12794        } else if (shortMsg != null) {
12795            longMsg = shortMsg;
12796        }
12797
12798        AppErrorResult result = new AppErrorResult();
12799        synchronized (this) {
12800            if (mController != null) {
12801                try {
12802                    String name = r != null ? r.processName : null;
12803                    int pid = r != null ? r.pid : Binder.getCallingPid();
12804                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12805                    if (!mController.appCrashed(name, pid,
12806                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12807                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12808                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12809                            Slog.w(TAG, "Skip killing native crashed app " + name
12810                                    + "(" + pid + ") during testing");
12811                        } else {
12812                            Slog.w(TAG, "Force-killing crashed app " + name
12813                                    + " at watcher's request");
12814                            if (r != null) {
12815                                r.kill("crash", true);
12816                            } else {
12817                                // Huh.
12818                                Process.killProcess(pid);
12819                                killProcessGroup(uid, pid);
12820                            }
12821                        }
12822                        return;
12823                    }
12824                } catch (RemoteException e) {
12825                    mController = null;
12826                    Watchdog.getInstance().setActivityController(null);
12827                }
12828            }
12829
12830            final long origId = Binder.clearCallingIdentity();
12831
12832            // If this process is running instrumentation, finish it.
12833            if (r != null && r.instrumentationClass != null) {
12834                Slog.w(TAG, "Error in app " + r.processName
12835                      + " running instrumentation " + r.instrumentationClass + ":");
12836                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12837                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12838                Bundle info = new Bundle();
12839                info.putString("shortMsg", shortMsg);
12840                info.putString("longMsg", longMsg);
12841                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12842                Binder.restoreCallingIdentity(origId);
12843                return;
12844            }
12845
12846            // Log crash in battery stats.
12847            if (r != null) {
12848                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12849            }
12850
12851            // If we can't identify the process or it's already exceeded its crash quota,
12852            // quit right away without showing a crash dialog.
12853            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12854                Binder.restoreCallingIdentity(origId);
12855                return;
12856            }
12857
12858            Message msg = Message.obtain();
12859            msg.what = SHOW_ERROR_MSG;
12860            HashMap data = new HashMap();
12861            data.put("result", result);
12862            data.put("app", r);
12863            msg.obj = data;
12864            mUiHandler.sendMessage(msg);
12865
12866            Binder.restoreCallingIdentity(origId);
12867        }
12868
12869        int res = result.get();
12870
12871        Intent appErrorIntent = null;
12872        synchronized (this) {
12873            if (r != null && !r.isolated) {
12874                // XXX Can't keep track of crash time for isolated processes,
12875                // since they don't have a persistent identity.
12876                mProcessCrashTimes.put(r.info.processName, r.uid,
12877                        SystemClock.uptimeMillis());
12878            }
12879            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12880                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12881            }
12882        }
12883
12884        if (appErrorIntent != null) {
12885            try {
12886                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12887            } catch (ActivityNotFoundException e) {
12888                Slog.w(TAG, "bug report receiver dissappeared", e);
12889            }
12890        }
12891    }
12892
12893    Intent createAppErrorIntentLocked(ProcessRecord r,
12894            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12895        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12896        if (report == null) {
12897            return null;
12898        }
12899        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12900        result.setComponent(r.errorReportReceiver);
12901        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12902        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12903        return result;
12904    }
12905
12906    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12907            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12908        if (r.errorReportReceiver == null) {
12909            return null;
12910        }
12911
12912        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12913            return null;
12914        }
12915
12916        ApplicationErrorReport report = new ApplicationErrorReport();
12917        report.packageName = r.info.packageName;
12918        report.installerPackageName = r.errorReportReceiver.getPackageName();
12919        report.processName = r.processName;
12920        report.time = timeMillis;
12921        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12922
12923        if (r.crashing || r.forceCrashReport) {
12924            report.type = ApplicationErrorReport.TYPE_CRASH;
12925            report.crashInfo = crashInfo;
12926        } else if (r.notResponding) {
12927            report.type = ApplicationErrorReport.TYPE_ANR;
12928            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12929
12930            report.anrInfo.activity = r.notRespondingReport.tag;
12931            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12932            report.anrInfo.info = r.notRespondingReport.longMsg;
12933        }
12934
12935        return report;
12936    }
12937
12938    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12939        enforceNotIsolatedCaller("getProcessesInErrorState");
12940        // assume our apps are happy - lazy create the list
12941        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12942
12943        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12944                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12945        int userId = UserHandle.getUserId(Binder.getCallingUid());
12946
12947        synchronized (this) {
12948
12949            // iterate across all processes
12950            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12951                ProcessRecord app = mLruProcesses.get(i);
12952                if (!allUsers && app.userId != userId) {
12953                    continue;
12954                }
12955                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12956                    // This one's in trouble, so we'll generate a report for it
12957                    // crashes are higher priority (in case there's a crash *and* an anr)
12958                    ActivityManager.ProcessErrorStateInfo report = null;
12959                    if (app.crashing) {
12960                        report = app.crashingReport;
12961                    } else if (app.notResponding) {
12962                        report = app.notRespondingReport;
12963                    }
12964
12965                    if (report != null) {
12966                        if (errList == null) {
12967                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12968                        }
12969                        errList.add(report);
12970                    } else {
12971                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12972                                " crashing = " + app.crashing +
12973                                " notResponding = " + app.notResponding);
12974                    }
12975                }
12976            }
12977        }
12978
12979        return errList;
12980    }
12981
12982    static int procStateToImportance(int procState, int memAdj,
12983            ActivityManager.RunningAppProcessInfo currApp) {
12984        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12985        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12986            currApp.lru = memAdj;
12987        } else {
12988            currApp.lru = 0;
12989        }
12990        return imp;
12991    }
12992
12993    private void fillInProcMemInfo(ProcessRecord app,
12994            ActivityManager.RunningAppProcessInfo outInfo) {
12995        outInfo.pid = app.pid;
12996        outInfo.uid = app.info.uid;
12997        if (mHeavyWeightProcess == app) {
12998            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12999        }
13000        if (app.persistent) {
13001            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13002        }
13003        if (app.activities.size() > 0) {
13004            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13005        }
13006        outInfo.lastTrimLevel = app.trimMemoryLevel;
13007        int adj = app.curAdj;
13008        int procState = app.curProcState;
13009        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13010        outInfo.importanceReasonCode = app.adjTypeCode;
13011        outInfo.processState = app.curProcState;
13012    }
13013
13014    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13015        enforceNotIsolatedCaller("getRunningAppProcesses");
13016
13017        final int callingUid = Binder.getCallingUid();
13018
13019        // Lazy instantiation of list
13020        List<ActivityManager.RunningAppProcessInfo> runList = null;
13021        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13022                callingUid) == PackageManager.PERMISSION_GRANTED;
13023        final int userId = UserHandle.getUserId(callingUid);
13024        final boolean allUids = isGetTasksAllowed(
13025                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13026
13027        synchronized (this) {
13028            // Iterate across all processes
13029            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13030                ProcessRecord app = mLruProcesses.get(i);
13031                if ((!allUsers && app.userId != userId)
13032                        || (!allUids && app.uid != callingUid)) {
13033                    continue;
13034                }
13035                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13036                    // Generate process state info for running application
13037                    ActivityManager.RunningAppProcessInfo currApp =
13038                        new ActivityManager.RunningAppProcessInfo(app.processName,
13039                                app.pid, app.getPackageList());
13040                    fillInProcMemInfo(app, currApp);
13041                    if (app.adjSource instanceof ProcessRecord) {
13042                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13043                        currApp.importanceReasonImportance =
13044                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13045                                        app.adjSourceProcState);
13046                    } else if (app.adjSource instanceof ActivityRecord) {
13047                        ActivityRecord r = (ActivityRecord)app.adjSource;
13048                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13049                    }
13050                    if (app.adjTarget instanceof ComponentName) {
13051                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13052                    }
13053                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13054                    //        + " lru=" + currApp.lru);
13055                    if (runList == null) {
13056                        runList = new ArrayList<>();
13057                    }
13058                    runList.add(currApp);
13059                }
13060            }
13061        }
13062        return runList;
13063    }
13064
13065    public List<ApplicationInfo> getRunningExternalApplications() {
13066        enforceNotIsolatedCaller("getRunningExternalApplications");
13067        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13068        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13069        if (runningApps != null && runningApps.size() > 0) {
13070            Set<String> extList = new HashSet<String>();
13071            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13072                if (app.pkgList != null) {
13073                    for (String pkg : app.pkgList) {
13074                        extList.add(pkg);
13075                    }
13076                }
13077            }
13078            IPackageManager pm = AppGlobals.getPackageManager();
13079            for (String pkg : extList) {
13080                try {
13081                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13082                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13083                        retList.add(info);
13084                    }
13085                } catch (RemoteException e) {
13086                }
13087            }
13088        }
13089        return retList;
13090    }
13091
13092    @Override
13093    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13094        enforceNotIsolatedCaller("getMyMemoryState");
13095        synchronized (this) {
13096            ProcessRecord proc;
13097            synchronized (mPidsSelfLocked) {
13098                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13099            }
13100            fillInProcMemInfo(proc, outInfo);
13101        }
13102    }
13103
13104    @Override
13105    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13106            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13107        (new ActivityManagerShellCommand(this, false)).exec(
13108                this, in, out, err, args, resultReceiver);
13109    }
13110
13111    @Override
13112    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13113        if (checkCallingPermission(android.Manifest.permission.DUMP)
13114                != PackageManager.PERMISSION_GRANTED) {
13115            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13116                    + Binder.getCallingPid()
13117                    + ", uid=" + Binder.getCallingUid()
13118                    + " without permission "
13119                    + android.Manifest.permission.DUMP);
13120            return;
13121        }
13122
13123        boolean dumpAll = false;
13124        boolean dumpClient = false;
13125        String dumpPackage = null;
13126
13127        int opti = 0;
13128        while (opti < args.length) {
13129            String opt = args[opti];
13130            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13131                break;
13132            }
13133            opti++;
13134            if ("-a".equals(opt)) {
13135                dumpAll = true;
13136            } else if ("-c".equals(opt)) {
13137                dumpClient = true;
13138            } else if ("-p".equals(opt)) {
13139                if (opti < args.length) {
13140                    dumpPackage = args[opti];
13141                    opti++;
13142                } else {
13143                    pw.println("Error: -p option requires package argument");
13144                    return;
13145                }
13146                dumpClient = true;
13147            } else if ("-h".equals(opt)) {
13148                ActivityManagerShellCommand.dumpHelp(pw, true);
13149                return;
13150            } else {
13151                pw.println("Unknown argument: " + opt + "; use -h for help");
13152            }
13153        }
13154
13155        long origId = Binder.clearCallingIdentity();
13156        boolean more = false;
13157        // Is the caller requesting to dump a particular piece of data?
13158        if (opti < args.length) {
13159            String cmd = args[opti];
13160            opti++;
13161            if ("activities".equals(cmd) || "a".equals(cmd)) {
13162                synchronized (this) {
13163                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13164                }
13165            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13166                synchronized (this) {
13167                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13168                }
13169            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13170                String[] newArgs;
13171                String name;
13172                if (opti >= args.length) {
13173                    name = null;
13174                    newArgs = EMPTY_STRING_ARRAY;
13175                } else {
13176                    dumpPackage = args[opti];
13177                    opti++;
13178                    newArgs = new String[args.length - opti];
13179                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13180                            args.length - opti);
13181                }
13182                synchronized (this) {
13183                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13184                }
13185            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13186                String[] newArgs;
13187                String name;
13188                if (opti >= args.length) {
13189                    name = null;
13190                    newArgs = EMPTY_STRING_ARRAY;
13191                } else {
13192                    dumpPackage = args[opti];
13193                    opti++;
13194                    newArgs = new String[args.length - opti];
13195                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13196                            args.length - opti);
13197                }
13198                synchronized (this) {
13199                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13200                }
13201            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13202                String[] newArgs;
13203                String name;
13204                if (opti >= args.length) {
13205                    name = null;
13206                    newArgs = EMPTY_STRING_ARRAY;
13207                } else {
13208                    dumpPackage = args[opti];
13209                    opti++;
13210                    newArgs = new String[args.length - opti];
13211                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13212                            args.length - opti);
13213                }
13214                synchronized (this) {
13215                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13216                }
13217            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13218                synchronized (this) {
13219                    dumpOomLocked(fd, pw, args, opti, true);
13220                }
13221            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13222                synchronized (this) {
13223                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13224                }
13225            } else if ("provider".equals(cmd)) {
13226                String[] newArgs;
13227                String name;
13228                if (opti >= args.length) {
13229                    name = null;
13230                    newArgs = EMPTY_STRING_ARRAY;
13231                } else {
13232                    name = args[opti];
13233                    opti++;
13234                    newArgs = new String[args.length - opti];
13235                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13236                }
13237                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13238                    pw.println("No providers match: " + name);
13239                    pw.println("Use -h for help.");
13240                }
13241            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13242                synchronized (this) {
13243                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13244                }
13245            } else if ("service".equals(cmd)) {
13246                String[] newArgs;
13247                String name;
13248                if (opti >= args.length) {
13249                    name = null;
13250                    newArgs = EMPTY_STRING_ARRAY;
13251                } else {
13252                    name = args[opti];
13253                    opti++;
13254                    newArgs = new String[args.length - opti];
13255                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13256                            args.length - opti);
13257                }
13258                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13259                    pw.println("No services match: " + name);
13260                    pw.println("Use -h for help.");
13261                }
13262            } else if ("package".equals(cmd)) {
13263                String[] newArgs;
13264                if (opti >= args.length) {
13265                    pw.println("package: no package name specified");
13266                    pw.println("Use -h for help.");
13267                } else {
13268                    dumpPackage = args[opti];
13269                    opti++;
13270                    newArgs = new String[args.length - opti];
13271                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13272                            args.length - opti);
13273                    args = newArgs;
13274                    opti = 0;
13275                    more = true;
13276                }
13277            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13278                synchronized (this) {
13279                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13280                }
13281            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13282                synchronized (this) {
13283                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13284                }
13285            } else {
13286                // Dumping a single activity?
13287                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13288                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13289                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13290                    if (res < 0) {
13291                        pw.println("Bad activity command, or no activities match: " + cmd);
13292                        pw.println("Use -h for help.");
13293                    }
13294                }
13295            }
13296            if (!more) {
13297                Binder.restoreCallingIdentity(origId);
13298                return;
13299            }
13300        }
13301
13302        // No piece of data specified, dump everything.
13303        synchronized (this) {
13304            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13305            pw.println();
13306            if (dumpAll) {
13307                pw.println("-------------------------------------------------------------------------------");
13308            }
13309            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13310            pw.println();
13311            if (dumpAll) {
13312                pw.println("-------------------------------------------------------------------------------");
13313            }
13314            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13315            pw.println();
13316            if (dumpAll) {
13317                pw.println("-------------------------------------------------------------------------------");
13318            }
13319            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13320            pw.println();
13321            if (dumpAll) {
13322                pw.println("-------------------------------------------------------------------------------");
13323            }
13324            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13325            pw.println();
13326            if (dumpAll) {
13327                pw.println("-------------------------------------------------------------------------------");
13328            }
13329            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13330            pw.println();
13331            if (dumpAll) {
13332                pw.println("-------------------------------------------------------------------------------");
13333            }
13334            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13335            if (mAssociations.size() > 0) {
13336                pw.println();
13337                if (dumpAll) {
13338                    pw.println("-------------------------------------------------------------------------------");
13339                }
13340                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13341            }
13342            pw.println();
13343            if (dumpAll) {
13344                pw.println("-------------------------------------------------------------------------------");
13345            }
13346            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13347        }
13348        Binder.restoreCallingIdentity(origId);
13349    }
13350
13351    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13352            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13353        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13354
13355        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13356                dumpPackage);
13357        boolean needSep = printedAnything;
13358
13359        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13360                dumpPackage, needSep, "  mFocusedActivity: ");
13361        if (printed) {
13362            printedAnything = true;
13363            needSep = false;
13364        }
13365
13366        if (dumpPackage == null) {
13367            if (needSep) {
13368                pw.println();
13369            }
13370            needSep = true;
13371            printedAnything = true;
13372            mStackSupervisor.dump(pw, "  ");
13373        }
13374
13375        if (!printedAnything) {
13376            pw.println("  (nothing)");
13377        }
13378    }
13379
13380    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13381            int opti, boolean dumpAll, String dumpPackage) {
13382        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13383
13384        boolean printedAnything = false;
13385
13386        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13387            boolean printedHeader = false;
13388
13389            final int N = mRecentTasks.size();
13390            for (int i=0; i<N; i++) {
13391                TaskRecord tr = mRecentTasks.get(i);
13392                if (dumpPackage != null) {
13393                    if (tr.realActivity == null ||
13394                            !dumpPackage.equals(tr.realActivity)) {
13395                        continue;
13396                    }
13397                }
13398                if (!printedHeader) {
13399                    pw.println("  Recent tasks:");
13400                    printedHeader = true;
13401                    printedAnything = true;
13402                }
13403                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13404                        pw.println(tr);
13405                if (dumpAll) {
13406                    mRecentTasks.get(i).dump(pw, "    ");
13407                }
13408            }
13409        }
13410
13411        if (!printedAnything) {
13412            pw.println("  (nothing)");
13413        }
13414    }
13415
13416    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13417            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13418        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13419
13420        int dumpUid = 0;
13421        if (dumpPackage != null) {
13422            IPackageManager pm = AppGlobals.getPackageManager();
13423            try {
13424                dumpUid = pm.getPackageUid(dumpPackage, 0);
13425            } catch (RemoteException e) {
13426            }
13427        }
13428
13429        boolean printedAnything = false;
13430
13431        final long now = SystemClock.uptimeMillis();
13432
13433        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13434            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13435                    = mAssociations.valueAt(i1);
13436            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13437                SparseArray<ArrayMap<String, Association>> sourceUids
13438                        = targetComponents.valueAt(i2);
13439                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13440                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13441                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13442                        Association ass = sourceProcesses.valueAt(i4);
13443                        if (dumpPackage != null) {
13444                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13445                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13446                                continue;
13447                            }
13448                        }
13449                        printedAnything = true;
13450                        pw.print("  ");
13451                        pw.print(ass.mTargetProcess);
13452                        pw.print("/");
13453                        UserHandle.formatUid(pw, ass.mTargetUid);
13454                        pw.print(" <- ");
13455                        pw.print(ass.mSourceProcess);
13456                        pw.print("/");
13457                        UserHandle.formatUid(pw, ass.mSourceUid);
13458                        pw.println();
13459                        pw.print("    via ");
13460                        pw.print(ass.mTargetComponent.flattenToShortString());
13461                        pw.println();
13462                        pw.print("    ");
13463                        long dur = ass.mTime;
13464                        if (ass.mNesting > 0) {
13465                            dur += now - ass.mStartTime;
13466                        }
13467                        TimeUtils.formatDuration(dur, pw);
13468                        pw.print(" (");
13469                        pw.print(ass.mCount);
13470                        pw.println(" times)");
13471                        if (ass.mNesting > 0) {
13472                            pw.print("    ");
13473                            pw.print(" Currently active: ");
13474                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13475                            pw.println();
13476                        }
13477                    }
13478                }
13479            }
13480
13481        }
13482
13483        if (!printedAnything) {
13484            pw.println("  (nothing)");
13485        }
13486    }
13487
13488    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13489            int opti, boolean dumpAll, String dumpPackage) {
13490        boolean needSep = false;
13491        boolean printedAnything = false;
13492        int numPers = 0;
13493
13494        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13495
13496        if (dumpAll) {
13497            final int NP = mProcessNames.getMap().size();
13498            for (int ip=0; ip<NP; ip++) {
13499                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13500                final int NA = procs.size();
13501                for (int ia=0; ia<NA; ia++) {
13502                    ProcessRecord r = procs.valueAt(ia);
13503                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13504                        continue;
13505                    }
13506                    if (!needSep) {
13507                        pw.println("  All known processes:");
13508                        needSep = true;
13509                        printedAnything = true;
13510                    }
13511                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13512                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13513                        pw.print(" "); pw.println(r);
13514                    r.dump(pw, "    ");
13515                    if (r.persistent) {
13516                        numPers++;
13517                    }
13518                }
13519            }
13520        }
13521
13522        if (mIsolatedProcesses.size() > 0) {
13523            boolean printed = false;
13524            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13525                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13526                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13527                    continue;
13528                }
13529                if (!printed) {
13530                    if (needSep) {
13531                        pw.println();
13532                    }
13533                    pw.println("  Isolated process list (sorted by uid):");
13534                    printedAnything = true;
13535                    printed = true;
13536                    needSep = true;
13537                }
13538                pw.println(String.format("%sIsolated #%2d: %s",
13539                        "    ", i, r.toString()));
13540            }
13541        }
13542
13543        if (mActiveUids.size() > 0) {
13544            boolean printed = false;
13545            int whichAppId = -1;
13546            if (dumpPackage != null) {
13547                try {
13548                    ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13549                            dumpPackage, 0);
13550                    whichAppId = UserHandle.getAppId(info.uid);
13551                } catch (NameNotFoundException e) {
13552                    e.printStackTrace();
13553                }
13554            }
13555            for (int i=0; i<mActiveUids.size(); i++) {
13556                UidRecord uidRec = mActiveUids.valueAt(i);
13557                if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13558                    continue;
13559                }
13560                if (!printed) {
13561                    printed = true;
13562                    if (needSep) {
13563                        pw.println();
13564                    }
13565                    pw.println("  UID states:");
13566                    needSep = true;
13567                    printedAnything = true;
13568                }
13569                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13570                pw.print(": "); pw.println(uidRec);
13571            }
13572        }
13573
13574        if (mLruProcesses.size() > 0) {
13575            if (needSep) {
13576                pw.println();
13577            }
13578            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13579                    pw.print(" total, non-act at ");
13580                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13581                    pw.print(", non-svc at ");
13582                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13583                    pw.println("):");
13584            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13585            needSep = true;
13586            printedAnything = true;
13587        }
13588
13589        if (dumpAll || dumpPackage != null) {
13590            synchronized (mPidsSelfLocked) {
13591                boolean printed = false;
13592                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13593                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13594                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13595                        continue;
13596                    }
13597                    if (!printed) {
13598                        if (needSep) pw.println();
13599                        needSep = true;
13600                        pw.println("  PID mappings:");
13601                        printed = true;
13602                        printedAnything = true;
13603                    }
13604                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13605                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13606                }
13607            }
13608        }
13609
13610        if (mForegroundProcesses.size() > 0) {
13611            synchronized (mPidsSelfLocked) {
13612                boolean printed = false;
13613                for (int i=0; i<mForegroundProcesses.size(); i++) {
13614                    ProcessRecord r = mPidsSelfLocked.get(
13615                            mForegroundProcesses.valueAt(i).pid);
13616                    if (dumpPackage != null && (r == null
13617                            || !r.pkgList.containsKey(dumpPackage))) {
13618                        continue;
13619                    }
13620                    if (!printed) {
13621                        if (needSep) pw.println();
13622                        needSep = true;
13623                        pw.println("  Foreground Processes:");
13624                        printed = true;
13625                        printedAnything = true;
13626                    }
13627                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13628                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13629                }
13630            }
13631        }
13632
13633        if (mPersistentStartingProcesses.size() > 0) {
13634            if (needSep) pw.println();
13635            needSep = true;
13636            printedAnything = true;
13637            pw.println("  Persisent processes that are starting:");
13638            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13639                    "Starting Norm", "Restarting PERS", dumpPackage);
13640        }
13641
13642        if (mRemovedProcesses.size() > 0) {
13643            if (needSep) pw.println();
13644            needSep = true;
13645            printedAnything = true;
13646            pw.println("  Processes that are being removed:");
13647            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13648                    "Removed Norm", "Removed PERS", dumpPackage);
13649        }
13650
13651        if (mProcessesOnHold.size() > 0) {
13652            if (needSep) pw.println();
13653            needSep = true;
13654            printedAnything = true;
13655            pw.println("  Processes that are on old until the system is ready:");
13656            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13657                    "OnHold Norm", "OnHold PERS", dumpPackage);
13658        }
13659
13660        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13661
13662        if (mProcessCrashTimes.getMap().size() > 0) {
13663            boolean printed = false;
13664            long now = SystemClock.uptimeMillis();
13665            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13666            final int NP = pmap.size();
13667            for (int ip=0; ip<NP; ip++) {
13668                String pname = pmap.keyAt(ip);
13669                SparseArray<Long> uids = pmap.valueAt(ip);
13670                final int N = uids.size();
13671                for (int i=0; i<N; i++) {
13672                    int puid = uids.keyAt(i);
13673                    ProcessRecord r = mProcessNames.get(pname, puid);
13674                    if (dumpPackage != null && (r == null
13675                            || !r.pkgList.containsKey(dumpPackage))) {
13676                        continue;
13677                    }
13678                    if (!printed) {
13679                        if (needSep) pw.println();
13680                        needSep = true;
13681                        pw.println("  Time since processes crashed:");
13682                        printed = true;
13683                        printedAnything = true;
13684                    }
13685                    pw.print("    Process "); pw.print(pname);
13686                            pw.print(" uid "); pw.print(puid);
13687                            pw.print(": last crashed ");
13688                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13689                            pw.println(" ago");
13690                }
13691            }
13692        }
13693
13694        if (mBadProcesses.getMap().size() > 0) {
13695            boolean printed = false;
13696            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13697            final int NP = pmap.size();
13698            for (int ip=0; ip<NP; ip++) {
13699                String pname = pmap.keyAt(ip);
13700                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13701                final int N = uids.size();
13702                for (int i=0; i<N; i++) {
13703                    int puid = uids.keyAt(i);
13704                    ProcessRecord r = mProcessNames.get(pname, puid);
13705                    if (dumpPackage != null && (r == null
13706                            || !r.pkgList.containsKey(dumpPackage))) {
13707                        continue;
13708                    }
13709                    if (!printed) {
13710                        if (needSep) pw.println();
13711                        needSep = true;
13712                        pw.println("  Bad processes:");
13713                        printedAnything = true;
13714                    }
13715                    BadProcessInfo info = uids.valueAt(i);
13716                    pw.print("    Bad process "); pw.print(pname);
13717                            pw.print(" uid "); pw.print(puid);
13718                            pw.print(": crashed at time "); pw.println(info.time);
13719                    if (info.shortMsg != null) {
13720                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13721                    }
13722                    if (info.longMsg != null) {
13723                        pw.print("      Long msg: "); pw.println(info.longMsg);
13724                    }
13725                    if (info.stack != null) {
13726                        pw.println("      Stack:");
13727                        int lastPos = 0;
13728                        for (int pos=0; pos<info.stack.length(); pos++) {
13729                            if (info.stack.charAt(pos) == '\n') {
13730                                pw.print("        ");
13731                                pw.write(info.stack, lastPos, pos-lastPos);
13732                                pw.println();
13733                                lastPos = pos+1;
13734                            }
13735                        }
13736                        if (lastPos < info.stack.length()) {
13737                            pw.print("        ");
13738                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13739                            pw.println();
13740                        }
13741                    }
13742                }
13743            }
13744        }
13745
13746        if (dumpPackage == null) {
13747            pw.println();
13748            needSep = false;
13749            mUserController.dump(pw, dumpAll);
13750        }
13751        if (mHomeProcess != null && (dumpPackage == null
13752                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13753            if (needSep) {
13754                pw.println();
13755                needSep = false;
13756            }
13757            pw.println("  mHomeProcess: " + mHomeProcess);
13758        }
13759        if (mPreviousProcess != null && (dumpPackage == null
13760                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13761            if (needSep) {
13762                pw.println();
13763                needSep = false;
13764            }
13765            pw.println("  mPreviousProcess: " + mPreviousProcess);
13766        }
13767        if (dumpAll) {
13768            StringBuilder sb = new StringBuilder(128);
13769            sb.append("  mPreviousProcessVisibleTime: ");
13770            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13771            pw.println(sb);
13772        }
13773        if (mHeavyWeightProcess != null && (dumpPackage == null
13774                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13775            if (needSep) {
13776                pw.println();
13777                needSep = false;
13778            }
13779            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13780        }
13781        if (dumpPackage == null) {
13782            pw.println("  mConfiguration: " + mConfiguration);
13783        }
13784        if (dumpAll) {
13785            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13786            if (mCompatModePackages.getPackages().size() > 0) {
13787                boolean printed = false;
13788                for (Map.Entry<String, Integer> entry
13789                        : mCompatModePackages.getPackages().entrySet()) {
13790                    String pkg = entry.getKey();
13791                    int mode = entry.getValue();
13792                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13793                        continue;
13794                    }
13795                    if (!printed) {
13796                        pw.println("  mScreenCompatPackages:");
13797                        printed = true;
13798                    }
13799                    pw.print("    "); pw.print(pkg); pw.print(": ");
13800                            pw.print(mode); pw.println();
13801                }
13802            }
13803        }
13804        if (dumpPackage == null) {
13805            pw.println("  mWakefulness="
13806                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13807            pw.println("  mSleepTokens=" + mSleepTokens);
13808            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13809                    + lockScreenShownToString());
13810            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13811            if (mRunningVoice != null) {
13812                pw.println("  mRunningVoice=" + mRunningVoice);
13813                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13814            }
13815        }
13816        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13817                || mOrigWaitForDebugger) {
13818            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13819                    || dumpPackage.equals(mOrigDebugApp)) {
13820                if (needSep) {
13821                    pw.println();
13822                    needSep = false;
13823                }
13824                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13825                        + " mDebugTransient=" + mDebugTransient
13826                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13827            }
13828        }
13829        if (mCurAppTimeTracker != null) {
13830            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13831        }
13832        if (mMemWatchProcesses.getMap().size() > 0) {
13833            pw.println("  Mem watch processes:");
13834            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13835                    = mMemWatchProcesses.getMap();
13836            for (int i=0; i<procs.size(); i++) {
13837                final String proc = procs.keyAt(i);
13838                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13839                for (int j=0; j<uids.size(); j++) {
13840                    if (needSep) {
13841                        pw.println();
13842                        needSep = false;
13843                    }
13844                    StringBuilder sb = new StringBuilder();
13845                    sb.append("    ").append(proc).append('/');
13846                    UserHandle.formatUid(sb, uids.keyAt(j));
13847                    Pair<Long, String> val = uids.valueAt(j);
13848                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13849                    if (val.second != null) {
13850                        sb.append(", report to ").append(val.second);
13851                    }
13852                    pw.println(sb.toString());
13853                }
13854            }
13855            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13856            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13857            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13858                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13859        }
13860        if (mTrackAllocationApp != null) {
13861            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13862                if (needSep) {
13863                    pw.println();
13864                    needSep = false;
13865                }
13866                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13867            }
13868        }
13869        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13870                || mProfileFd != null) {
13871            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13872                if (needSep) {
13873                    pw.println();
13874                    needSep = false;
13875                }
13876                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13877                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13878                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13879                        + mAutoStopProfiler);
13880                pw.println("  mProfileType=" + mProfileType);
13881            }
13882        }
13883        if (dumpPackage == null) {
13884            if (mAlwaysFinishActivities || mController != null) {
13885                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13886                        + " mController=" + mController);
13887            }
13888            if (dumpAll) {
13889                pw.println("  Total persistent processes: " + numPers);
13890                pw.println("  mProcessesReady=" + mProcessesReady
13891                        + " mSystemReady=" + mSystemReady
13892                        + " mBooted=" + mBooted
13893                        + " mFactoryTest=" + mFactoryTest);
13894                pw.println("  mBooting=" + mBooting
13895                        + " mCallFinishBooting=" + mCallFinishBooting
13896                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13897                pw.print("  mLastPowerCheckRealtime=");
13898                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13899                        pw.println("");
13900                pw.print("  mLastPowerCheckUptime=");
13901                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13902                        pw.println("");
13903                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13904                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13905                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13906                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13907                        + " (" + mLruProcesses.size() + " total)"
13908                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13909                        + " mNumServiceProcs=" + mNumServiceProcs
13910                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13911                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13912                        + " mLastMemoryLevel" + mLastMemoryLevel
13913                        + " mLastNumProcesses" + mLastNumProcesses);
13914                long now = SystemClock.uptimeMillis();
13915                pw.print("  mLastIdleTime=");
13916                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13917                        pw.print(" mLowRamSinceLastIdle=");
13918                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13919                        pw.println();
13920            }
13921        }
13922
13923        if (!printedAnything) {
13924            pw.println("  (nothing)");
13925        }
13926    }
13927
13928    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13929            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13930        if (mProcessesToGc.size() > 0) {
13931            boolean printed = false;
13932            long now = SystemClock.uptimeMillis();
13933            for (int i=0; i<mProcessesToGc.size(); i++) {
13934                ProcessRecord proc = mProcessesToGc.get(i);
13935                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13936                    continue;
13937                }
13938                if (!printed) {
13939                    if (needSep) pw.println();
13940                    needSep = true;
13941                    pw.println("  Processes that are waiting to GC:");
13942                    printed = true;
13943                }
13944                pw.print("    Process "); pw.println(proc);
13945                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13946                        pw.print(", last gced=");
13947                        pw.print(now-proc.lastRequestedGc);
13948                        pw.print(" ms ago, last lowMem=");
13949                        pw.print(now-proc.lastLowMemory);
13950                        pw.println(" ms ago");
13951
13952            }
13953        }
13954        return needSep;
13955    }
13956
13957    void printOomLevel(PrintWriter pw, String name, int adj) {
13958        pw.print("    ");
13959        if (adj >= 0) {
13960            pw.print(' ');
13961            if (adj < 10) pw.print(' ');
13962        } else {
13963            if (adj > -10) pw.print(' ');
13964        }
13965        pw.print(adj);
13966        pw.print(": ");
13967        pw.print(name);
13968        pw.print(" (");
13969        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
13970        pw.println(")");
13971    }
13972
13973    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13974            int opti, boolean dumpAll) {
13975        boolean needSep = false;
13976
13977        if (mLruProcesses.size() > 0) {
13978            if (needSep) pw.println();
13979            needSep = true;
13980            pw.println("  OOM levels:");
13981            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13982            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13983            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13984            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13985            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13986            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13987            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13988            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13989            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13990            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13991            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13992            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13993            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13994            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13995
13996            if (needSep) pw.println();
13997            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13998                    pw.print(" total, non-act at ");
13999                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14000                    pw.print(", non-svc at ");
14001                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14002                    pw.println("):");
14003            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14004            needSep = true;
14005        }
14006
14007        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14008
14009        pw.println();
14010        pw.println("  mHomeProcess: " + mHomeProcess);
14011        pw.println("  mPreviousProcess: " + mPreviousProcess);
14012        if (mHeavyWeightProcess != null) {
14013            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14014        }
14015
14016        return true;
14017    }
14018
14019    /**
14020     * There are three ways to call this:
14021     *  - no provider specified: dump all the providers
14022     *  - a flattened component name that matched an existing provider was specified as the
14023     *    first arg: dump that one provider
14024     *  - the first arg isn't the flattened component name of an existing provider:
14025     *    dump all providers whose component contains the first arg as a substring
14026     */
14027    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14028            int opti, boolean dumpAll) {
14029        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14030    }
14031
14032    static class ItemMatcher {
14033        ArrayList<ComponentName> components;
14034        ArrayList<String> strings;
14035        ArrayList<Integer> objects;
14036        boolean all;
14037
14038        ItemMatcher() {
14039            all = true;
14040        }
14041
14042        void build(String name) {
14043            ComponentName componentName = ComponentName.unflattenFromString(name);
14044            if (componentName != null) {
14045                if (components == null) {
14046                    components = new ArrayList<ComponentName>();
14047                }
14048                components.add(componentName);
14049                all = false;
14050            } else {
14051                int objectId = 0;
14052                // Not a '/' separated full component name; maybe an object ID?
14053                try {
14054                    objectId = Integer.parseInt(name, 16);
14055                    if (objects == null) {
14056                        objects = new ArrayList<Integer>();
14057                    }
14058                    objects.add(objectId);
14059                    all = false;
14060                } catch (RuntimeException e) {
14061                    // Not an integer; just do string match.
14062                    if (strings == null) {
14063                        strings = new ArrayList<String>();
14064                    }
14065                    strings.add(name);
14066                    all = false;
14067                }
14068            }
14069        }
14070
14071        int build(String[] args, int opti) {
14072            for (; opti<args.length; opti++) {
14073                String name = args[opti];
14074                if ("--".equals(name)) {
14075                    return opti+1;
14076                }
14077                build(name);
14078            }
14079            return opti;
14080        }
14081
14082        boolean match(Object object, ComponentName comp) {
14083            if (all) {
14084                return true;
14085            }
14086            if (components != null) {
14087                for (int i=0; i<components.size(); i++) {
14088                    if (components.get(i).equals(comp)) {
14089                        return true;
14090                    }
14091                }
14092            }
14093            if (objects != null) {
14094                for (int i=0; i<objects.size(); i++) {
14095                    if (System.identityHashCode(object) == objects.get(i)) {
14096                        return true;
14097                    }
14098                }
14099            }
14100            if (strings != null) {
14101                String flat = comp.flattenToString();
14102                for (int i=0; i<strings.size(); i++) {
14103                    if (flat.contains(strings.get(i))) {
14104                        return true;
14105                    }
14106                }
14107            }
14108            return false;
14109        }
14110    }
14111
14112    /**
14113     * There are three things that cmd can be:
14114     *  - a flattened component name that matches an existing activity
14115     *  - the cmd arg isn't the flattened component name of an existing activity:
14116     *    dump all activity whose component contains the cmd as a substring
14117     *  - A hex number of the ActivityRecord object instance.
14118     */
14119    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14120            int opti, boolean dumpAll) {
14121        ArrayList<ActivityRecord> activities;
14122
14123        synchronized (this) {
14124            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14125        }
14126
14127        if (activities.size() <= 0) {
14128            return false;
14129        }
14130
14131        String[] newArgs = new String[args.length - opti];
14132        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14133
14134        TaskRecord lastTask = null;
14135        boolean needSep = false;
14136        for (int i=activities.size()-1; i>=0; i--) {
14137            ActivityRecord r = activities.get(i);
14138            if (needSep) {
14139                pw.println();
14140            }
14141            needSep = true;
14142            synchronized (this) {
14143                if (lastTask != r.task) {
14144                    lastTask = r.task;
14145                    pw.print("TASK "); pw.print(lastTask.affinity);
14146                            pw.print(" id="); pw.println(lastTask.taskId);
14147                    if (dumpAll) {
14148                        lastTask.dump(pw, "  ");
14149                    }
14150                }
14151            }
14152            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14153        }
14154        return true;
14155    }
14156
14157    /**
14158     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14159     * there is a thread associated with the activity.
14160     */
14161    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14162            final ActivityRecord r, String[] args, boolean dumpAll) {
14163        String innerPrefix = prefix + "  ";
14164        synchronized (this) {
14165            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14166                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14167                    pw.print(" pid=");
14168                    if (r.app != null) pw.println(r.app.pid);
14169                    else pw.println("(not running)");
14170            if (dumpAll) {
14171                r.dump(pw, innerPrefix);
14172            }
14173        }
14174        if (r.app != null && r.app.thread != null) {
14175            // flush anything that is already in the PrintWriter since the thread is going
14176            // to write to the file descriptor directly
14177            pw.flush();
14178            try {
14179                TransferPipe tp = new TransferPipe();
14180                try {
14181                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14182                            r.appToken, innerPrefix, args);
14183                    tp.go(fd);
14184                } finally {
14185                    tp.kill();
14186                }
14187            } catch (IOException e) {
14188                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14189            } catch (RemoteException e) {
14190                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14191            }
14192        }
14193    }
14194
14195    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14196            int opti, boolean dumpAll, String dumpPackage) {
14197        boolean needSep = false;
14198        boolean onlyHistory = false;
14199        boolean printedAnything = false;
14200
14201        if ("history".equals(dumpPackage)) {
14202            if (opti < args.length && "-s".equals(args[opti])) {
14203                dumpAll = false;
14204            }
14205            onlyHistory = true;
14206            dumpPackage = null;
14207        }
14208
14209        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14210        if (!onlyHistory && dumpAll) {
14211            if (mRegisteredReceivers.size() > 0) {
14212                boolean printed = false;
14213                Iterator it = mRegisteredReceivers.values().iterator();
14214                while (it.hasNext()) {
14215                    ReceiverList r = (ReceiverList)it.next();
14216                    if (dumpPackage != null && (r.app == null ||
14217                            !dumpPackage.equals(r.app.info.packageName))) {
14218                        continue;
14219                    }
14220                    if (!printed) {
14221                        pw.println("  Registered Receivers:");
14222                        needSep = true;
14223                        printed = true;
14224                        printedAnything = true;
14225                    }
14226                    pw.print("  * "); pw.println(r);
14227                    r.dump(pw, "    ");
14228                }
14229            }
14230
14231            if (mReceiverResolver.dump(pw, needSep ?
14232                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14233                    "    ", dumpPackage, false, false)) {
14234                needSep = true;
14235                printedAnything = true;
14236            }
14237        }
14238
14239        for (BroadcastQueue q : mBroadcastQueues) {
14240            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14241            printedAnything |= needSep;
14242        }
14243
14244        needSep = true;
14245
14246        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14247            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14248                if (needSep) {
14249                    pw.println();
14250                }
14251                needSep = true;
14252                printedAnything = true;
14253                pw.print("  Sticky broadcasts for user ");
14254                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14255                StringBuilder sb = new StringBuilder(128);
14256                for (Map.Entry<String, ArrayList<Intent>> ent
14257                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14258                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14259                    if (dumpAll) {
14260                        pw.println(":");
14261                        ArrayList<Intent> intents = ent.getValue();
14262                        final int N = intents.size();
14263                        for (int i=0; i<N; i++) {
14264                            sb.setLength(0);
14265                            sb.append("    Intent: ");
14266                            intents.get(i).toShortString(sb, false, true, false, false);
14267                            pw.println(sb.toString());
14268                            Bundle bundle = intents.get(i).getExtras();
14269                            if (bundle != null) {
14270                                pw.print("      ");
14271                                pw.println(bundle.toString());
14272                            }
14273                        }
14274                    } else {
14275                        pw.println("");
14276                    }
14277                }
14278            }
14279        }
14280
14281        if (!onlyHistory && dumpAll) {
14282            pw.println();
14283            for (BroadcastQueue queue : mBroadcastQueues) {
14284                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14285                        + queue.mBroadcastsScheduled);
14286            }
14287            pw.println("  mHandler:");
14288            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14289            needSep = true;
14290            printedAnything = true;
14291        }
14292
14293        if (!printedAnything) {
14294            pw.println("  (nothing)");
14295        }
14296    }
14297
14298    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14299            int opti, boolean dumpAll, String dumpPackage) {
14300        boolean needSep;
14301        boolean printedAnything = false;
14302
14303        ItemMatcher matcher = new ItemMatcher();
14304        matcher.build(args, opti);
14305
14306        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14307
14308        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14309        printedAnything |= needSep;
14310
14311        if (mLaunchingProviders.size() > 0) {
14312            boolean printed = false;
14313            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14314                ContentProviderRecord r = mLaunchingProviders.get(i);
14315                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14316                    continue;
14317                }
14318                if (!printed) {
14319                    if (needSep) pw.println();
14320                    needSep = true;
14321                    pw.println("  Launching content providers:");
14322                    printed = true;
14323                    printedAnything = true;
14324                }
14325                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14326                        pw.println(r);
14327            }
14328        }
14329
14330        if (!printedAnything) {
14331            pw.println("  (nothing)");
14332        }
14333    }
14334
14335    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14336            int opti, boolean dumpAll, String dumpPackage) {
14337        boolean needSep = false;
14338        boolean printedAnything = false;
14339
14340        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14341
14342        if (mGrantedUriPermissions.size() > 0) {
14343            boolean printed = false;
14344            int dumpUid = -2;
14345            if (dumpPackage != null) {
14346                try {
14347                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14348                } catch (NameNotFoundException e) {
14349                    dumpUid = -1;
14350                }
14351            }
14352            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14353                int uid = mGrantedUriPermissions.keyAt(i);
14354                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14355                    continue;
14356                }
14357                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14358                if (!printed) {
14359                    if (needSep) pw.println();
14360                    needSep = true;
14361                    pw.println("  Granted Uri Permissions:");
14362                    printed = true;
14363                    printedAnything = true;
14364                }
14365                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14366                for (UriPermission perm : perms.values()) {
14367                    pw.print("    "); pw.println(perm);
14368                    if (dumpAll) {
14369                        perm.dump(pw, "      ");
14370                    }
14371                }
14372            }
14373        }
14374
14375        if (!printedAnything) {
14376            pw.println("  (nothing)");
14377        }
14378    }
14379
14380    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14381            int opti, boolean dumpAll, String dumpPackage) {
14382        boolean printed = false;
14383
14384        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14385
14386        if (mIntentSenderRecords.size() > 0) {
14387            Iterator<WeakReference<PendingIntentRecord>> it
14388                    = mIntentSenderRecords.values().iterator();
14389            while (it.hasNext()) {
14390                WeakReference<PendingIntentRecord> ref = it.next();
14391                PendingIntentRecord rec = ref != null ? ref.get(): null;
14392                if (dumpPackage != null && (rec == null
14393                        || !dumpPackage.equals(rec.key.packageName))) {
14394                    continue;
14395                }
14396                printed = true;
14397                if (rec != null) {
14398                    pw.print("  * "); pw.println(rec);
14399                    if (dumpAll) {
14400                        rec.dump(pw, "    ");
14401                    }
14402                } else {
14403                    pw.print("  * "); pw.println(ref);
14404                }
14405            }
14406        }
14407
14408        if (!printed) {
14409            pw.println("  (nothing)");
14410        }
14411    }
14412
14413    private static final int dumpProcessList(PrintWriter pw,
14414            ActivityManagerService service, List list,
14415            String prefix, String normalLabel, String persistentLabel,
14416            String dumpPackage) {
14417        int numPers = 0;
14418        final int N = list.size()-1;
14419        for (int i=N; i>=0; i--) {
14420            ProcessRecord r = (ProcessRecord)list.get(i);
14421            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14422                continue;
14423            }
14424            pw.println(String.format("%s%s #%2d: %s",
14425                    prefix, (r.persistent ? persistentLabel : normalLabel),
14426                    i, r.toString()));
14427            if (r.persistent) {
14428                numPers++;
14429            }
14430        }
14431        return numPers;
14432    }
14433
14434    private static final boolean dumpProcessOomList(PrintWriter pw,
14435            ActivityManagerService service, List<ProcessRecord> origList,
14436            String prefix, String normalLabel, String persistentLabel,
14437            boolean inclDetails, String dumpPackage) {
14438
14439        ArrayList<Pair<ProcessRecord, Integer>> list
14440                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14441        for (int i=0; i<origList.size(); i++) {
14442            ProcessRecord r = origList.get(i);
14443            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14444                continue;
14445            }
14446            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14447        }
14448
14449        if (list.size() <= 0) {
14450            return false;
14451        }
14452
14453        Comparator<Pair<ProcessRecord, Integer>> comparator
14454                = new Comparator<Pair<ProcessRecord, Integer>>() {
14455            @Override
14456            public int compare(Pair<ProcessRecord, Integer> object1,
14457                    Pair<ProcessRecord, Integer> object2) {
14458                if (object1.first.setAdj != object2.first.setAdj) {
14459                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14460                }
14461                if (object1.second.intValue() != object2.second.intValue()) {
14462                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14463                }
14464                return 0;
14465            }
14466        };
14467
14468        Collections.sort(list, comparator);
14469
14470        final long curRealtime = SystemClock.elapsedRealtime();
14471        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14472        final long curUptime = SystemClock.uptimeMillis();
14473        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14474
14475        for (int i=list.size()-1; i>=0; i--) {
14476            ProcessRecord r = list.get(i).first;
14477            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14478            char schedGroup;
14479            switch (r.setSchedGroup) {
14480                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14481                    schedGroup = 'B';
14482                    break;
14483                case Process.THREAD_GROUP_DEFAULT:
14484                    schedGroup = 'F';
14485                    break;
14486                default:
14487                    schedGroup = '?';
14488                    break;
14489            }
14490            char foreground;
14491            if (r.foregroundActivities) {
14492                foreground = 'A';
14493            } else if (r.foregroundServices) {
14494                foreground = 'S';
14495            } else {
14496                foreground = ' ';
14497            }
14498            String procState = ProcessList.makeProcStateString(r.curProcState);
14499            pw.print(prefix);
14500            pw.print(r.persistent ? persistentLabel : normalLabel);
14501            pw.print(" #");
14502            int num = (origList.size()-1)-list.get(i).second;
14503            if (num < 10) pw.print(' ');
14504            pw.print(num);
14505            pw.print(": ");
14506            pw.print(oomAdj);
14507            pw.print(' ');
14508            pw.print(schedGroup);
14509            pw.print('/');
14510            pw.print(foreground);
14511            pw.print('/');
14512            pw.print(procState);
14513            pw.print(" trm:");
14514            if (r.trimMemoryLevel < 10) pw.print(' ');
14515            pw.print(r.trimMemoryLevel);
14516            pw.print(' ');
14517            pw.print(r.toShortString());
14518            pw.print(" (");
14519            pw.print(r.adjType);
14520            pw.println(')');
14521            if (r.adjSource != null || r.adjTarget != null) {
14522                pw.print(prefix);
14523                pw.print("    ");
14524                if (r.adjTarget instanceof ComponentName) {
14525                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14526                } else if (r.adjTarget != null) {
14527                    pw.print(r.adjTarget.toString());
14528                } else {
14529                    pw.print("{null}");
14530                }
14531                pw.print("<=");
14532                if (r.adjSource instanceof ProcessRecord) {
14533                    pw.print("Proc{");
14534                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14535                    pw.println("}");
14536                } else if (r.adjSource != null) {
14537                    pw.println(r.adjSource.toString());
14538                } else {
14539                    pw.println("{null}");
14540                }
14541            }
14542            if (inclDetails) {
14543                pw.print(prefix);
14544                pw.print("    ");
14545                pw.print("oom: max="); pw.print(r.maxAdj);
14546                pw.print(" curRaw="); pw.print(r.curRawAdj);
14547                pw.print(" setRaw="); pw.print(r.setRawAdj);
14548                pw.print(" cur="); pw.print(r.curAdj);
14549                pw.print(" set="); pw.println(r.setAdj);
14550                pw.print(prefix);
14551                pw.print("    ");
14552                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14553                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14554                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14555                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14556                pw.println();
14557                pw.print(prefix);
14558                pw.print("    ");
14559                pw.print("cached="); pw.print(r.cached);
14560                pw.print(" empty="); pw.print(r.empty);
14561                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14562
14563                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14564                    if (r.lastWakeTime != 0) {
14565                        long wtime;
14566                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14567                        synchronized (stats) {
14568                            wtime = stats.getProcessWakeTime(r.info.uid,
14569                                    r.pid, curRealtime);
14570                        }
14571                        long timeUsed = wtime - r.lastWakeTime;
14572                        pw.print(prefix);
14573                        pw.print("    ");
14574                        pw.print("keep awake over ");
14575                        TimeUtils.formatDuration(realtimeSince, pw);
14576                        pw.print(" used ");
14577                        TimeUtils.formatDuration(timeUsed, pw);
14578                        pw.print(" (");
14579                        pw.print((timeUsed*100)/realtimeSince);
14580                        pw.println("%)");
14581                    }
14582                    if (r.lastCpuTime != 0) {
14583                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14584                        pw.print(prefix);
14585                        pw.print("    ");
14586                        pw.print("run cpu over ");
14587                        TimeUtils.formatDuration(uptimeSince, pw);
14588                        pw.print(" used ");
14589                        TimeUtils.formatDuration(timeUsed, pw);
14590                        pw.print(" (");
14591                        pw.print((timeUsed*100)/uptimeSince);
14592                        pw.println("%)");
14593                    }
14594                }
14595            }
14596        }
14597        return true;
14598    }
14599
14600    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14601            String[] args) {
14602        ArrayList<ProcessRecord> procs;
14603        synchronized (this) {
14604            if (args != null && args.length > start
14605                    && args[start].charAt(0) != '-') {
14606                procs = new ArrayList<ProcessRecord>();
14607                int pid = -1;
14608                try {
14609                    pid = Integer.parseInt(args[start]);
14610                } catch (NumberFormatException e) {
14611                }
14612                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14613                    ProcessRecord proc = mLruProcesses.get(i);
14614                    if (proc.pid == pid) {
14615                        procs.add(proc);
14616                    } else if (allPkgs && proc.pkgList != null
14617                            && proc.pkgList.containsKey(args[start])) {
14618                        procs.add(proc);
14619                    } else if (proc.processName.equals(args[start])) {
14620                        procs.add(proc);
14621                    }
14622                }
14623                if (procs.size() <= 0) {
14624                    return null;
14625                }
14626            } else {
14627                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14628            }
14629        }
14630        return procs;
14631    }
14632
14633    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14634            PrintWriter pw, String[] args) {
14635        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14636        if (procs == null) {
14637            pw.println("No process found for: " + args[0]);
14638            return;
14639        }
14640
14641        long uptime = SystemClock.uptimeMillis();
14642        long realtime = SystemClock.elapsedRealtime();
14643        pw.println("Applications Graphics Acceleration Info:");
14644        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14645
14646        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14647            ProcessRecord r = procs.get(i);
14648            if (r.thread != null) {
14649                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14650                pw.flush();
14651                try {
14652                    TransferPipe tp = new TransferPipe();
14653                    try {
14654                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14655                        tp.go(fd);
14656                    } finally {
14657                        tp.kill();
14658                    }
14659                } catch (IOException e) {
14660                    pw.println("Failure while dumping the app: " + r);
14661                    pw.flush();
14662                } catch (RemoteException e) {
14663                    pw.println("Got a RemoteException while dumping the app " + r);
14664                    pw.flush();
14665                }
14666            }
14667        }
14668    }
14669
14670    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14671        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14672        if (procs == null) {
14673            pw.println("No process found for: " + args[0]);
14674            return;
14675        }
14676
14677        pw.println("Applications Database Info:");
14678
14679        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14680            ProcessRecord r = procs.get(i);
14681            if (r.thread != null) {
14682                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14683                pw.flush();
14684                try {
14685                    TransferPipe tp = new TransferPipe();
14686                    try {
14687                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14688                        tp.go(fd);
14689                    } finally {
14690                        tp.kill();
14691                    }
14692                } catch (IOException e) {
14693                    pw.println("Failure while dumping the app: " + r);
14694                    pw.flush();
14695                } catch (RemoteException e) {
14696                    pw.println("Got a RemoteException while dumping the app " + r);
14697                    pw.flush();
14698                }
14699            }
14700        }
14701    }
14702
14703    final static class MemItem {
14704        final boolean isProc;
14705        final String label;
14706        final String shortLabel;
14707        final long pss;
14708        final int id;
14709        final boolean hasActivities;
14710        ArrayList<MemItem> subitems;
14711
14712        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14713                boolean _hasActivities) {
14714            isProc = true;
14715            label = _label;
14716            shortLabel = _shortLabel;
14717            pss = _pss;
14718            id = _id;
14719            hasActivities = _hasActivities;
14720        }
14721
14722        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14723            isProc = false;
14724            label = _label;
14725            shortLabel = _shortLabel;
14726            pss = _pss;
14727            id = _id;
14728            hasActivities = false;
14729        }
14730    }
14731
14732    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14733            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14734        if (sort && !isCompact) {
14735            Collections.sort(items, new Comparator<MemItem>() {
14736                @Override
14737                public int compare(MemItem lhs, MemItem rhs) {
14738                    if (lhs.pss < rhs.pss) {
14739                        return 1;
14740                    } else if (lhs.pss > rhs.pss) {
14741                        return -1;
14742                    }
14743                    return 0;
14744                }
14745            });
14746        }
14747
14748        for (int i=0; i<items.size(); i++) {
14749            MemItem mi = items.get(i);
14750            if (!isCompact) {
14751                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14752            } else if (mi.isProc) {
14753                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14754                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14755                pw.println(mi.hasActivities ? ",a" : ",e");
14756            } else {
14757                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14758                pw.println(mi.pss);
14759            }
14760            if (mi.subitems != null) {
14761                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14762                        true, isCompact);
14763            }
14764        }
14765    }
14766
14767    // These are in KB.
14768    static final long[] DUMP_MEM_BUCKETS = new long[] {
14769        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14770        120*1024, 160*1024, 200*1024,
14771        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14772        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14773    };
14774
14775    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14776            boolean stackLike) {
14777        int start = label.lastIndexOf('.');
14778        if (start >= 0) start++;
14779        else start = 0;
14780        int end = label.length();
14781        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14782            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14783                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14784                out.append(bucket);
14785                out.append(stackLike ? "MB." : "MB ");
14786                out.append(label, start, end);
14787                return;
14788            }
14789        }
14790        out.append(memKB/1024);
14791        out.append(stackLike ? "MB." : "MB ");
14792        out.append(label, start, end);
14793    }
14794
14795    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14796            ProcessList.NATIVE_ADJ,
14797            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14798            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14799            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14800            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14801            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14802            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14803    };
14804    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14805            "Native",
14806            "System", "Persistent", "Persistent Service", "Foreground",
14807            "Visible", "Perceptible",
14808            "Heavy Weight", "Backup",
14809            "A Services", "Home",
14810            "Previous", "B Services", "Cached"
14811    };
14812    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14813            "native",
14814            "sys", "pers", "persvc", "fore",
14815            "vis", "percept",
14816            "heavy", "backup",
14817            "servicea", "home",
14818            "prev", "serviceb", "cached"
14819    };
14820
14821    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14822            long realtime, boolean isCheckinRequest, boolean isCompact) {
14823        if (isCheckinRequest || isCompact) {
14824            // short checkin version
14825            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14826        } else {
14827            pw.println("Applications Memory Usage (in Kilobytes):");
14828            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14829        }
14830    }
14831
14832    private static final int KSM_SHARED = 0;
14833    private static final int KSM_SHARING = 1;
14834    private static final int KSM_UNSHARED = 2;
14835    private static final int KSM_VOLATILE = 3;
14836
14837    private final long[] getKsmInfo() {
14838        long[] longOut = new long[4];
14839        final int[] SINGLE_LONG_FORMAT = new int[] {
14840            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14841        };
14842        long[] longTmp = new long[1];
14843        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14844                SINGLE_LONG_FORMAT, null, longTmp, null);
14845        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14846        longTmp[0] = 0;
14847        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14848                SINGLE_LONG_FORMAT, null, longTmp, null);
14849        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14850        longTmp[0] = 0;
14851        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14852                SINGLE_LONG_FORMAT, null, longTmp, null);
14853        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14854        longTmp[0] = 0;
14855        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14856                SINGLE_LONG_FORMAT, null, longTmp, null);
14857        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14858        return longOut;
14859    }
14860
14861    private static String stringifySize(long size, int order) {
14862        Locale locale = Locale.US;
14863        switch (order) {
14864            case 1:
14865                return String.format(locale, "%,13d", size);
14866            case 1024:
14867                return String.format(locale, "%,9dK", size / 1024);
14868            case 1024 * 1024:
14869                return String.format(locale, "%,5dM", size / 1024 / 1024);
14870            case 1024 * 1024 * 1024:
14871                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
14872            default:
14873                throw new IllegalArgumentException("Invalid size order");
14874        }
14875    }
14876
14877    private static String stringifyKBSize(long size) {
14878        return stringifySize(size * 1024, 1024);
14879    }
14880
14881    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14882            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14883        boolean dumpDetails = false;
14884        boolean dumpFullDetails = false;
14885        boolean dumpDalvik = false;
14886        boolean dumpSummaryOnly = false;
14887        boolean oomOnly = false;
14888        boolean isCompact = false;
14889        boolean localOnly = false;
14890        boolean packages = false;
14891
14892        int opti = 0;
14893        while (opti < args.length) {
14894            String opt = args[opti];
14895            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14896                break;
14897            }
14898            opti++;
14899            if ("-a".equals(opt)) {
14900                dumpDetails = true;
14901                dumpFullDetails = true;
14902                dumpDalvik = true;
14903            } else if ("-d".equals(opt)) {
14904                dumpDalvik = true;
14905            } else if ("-c".equals(opt)) {
14906                isCompact = true;
14907            } else if ("-s".equals(opt)) {
14908                dumpDetails = true;
14909                dumpSummaryOnly = true;
14910            } else if ("--oom".equals(opt)) {
14911                oomOnly = true;
14912            } else if ("--local".equals(opt)) {
14913                localOnly = true;
14914            } else if ("--package".equals(opt)) {
14915                packages = true;
14916            } else if ("-h".equals(opt)) {
14917                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14918                pw.println("  -a: include all available information for each process.");
14919                pw.println("  -d: include dalvik details.");
14920                pw.println("  -c: dump in a compact machine-parseable representation.");
14921                pw.println("  -s: dump only summary of application memory usage.");
14922                pw.println("  --oom: only show processes organized by oom adj.");
14923                pw.println("  --local: only collect details locally, don't call process.");
14924                pw.println("  --package: interpret process arg as package, dumping all");
14925                pw.println("             processes that have loaded that package.");
14926                pw.println("If [process] is specified it can be the name or ");
14927                pw.println("pid of a specific process to dump.");
14928                return;
14929            } else {
14930                pw.println("Unknown argument: " + opt + "; use -h for help");
14931            }
14932        }
14933
14934        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14935        long uptime = SystemClock.uptimeMillis();
14936        long realtime = SystemClock.elapsedRealtime();
14937        final long[] tmpLong = new long[1];
14938
14939        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14940        if (procs == null) {
14941            // No Java processes.  Maybe they want to print a native process.
14942            if (args != null && args.length > opti
14943                    && args[opti].charAt(0) != '-') {
14944                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14945                        = new ArrayList<ProcessCpuTracker.Stats>();
14946                updateCpuStatsNow();
14947                int findPid = -1;
14948                try {
14949                    findPid = Integer.parseInt(args[opti]);
14950                } catch (NumberFormatException e) {
14951                }
14952                synchronized (mProcessCpuTracker) {
14953                    final int N = mProcessCpuTracker.countStats();
14954                    for (int i=0; i<N; i++) {
14955                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14956                        if (st.pid == findPid || (st.baseName != null
14957                                && st.baseName.equals(args[opti]))) {
14958                            nativeProcs.add(st);
14959                        }
14960                    }
14961                }
14962                if (nativeProcs.size() > 0) {
14963                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14964                            isCompact);
14965                    Debug.MemoryInfo mi = null;
14966                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14967                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14968                        final int pid = r.pid;
14969                        if (!isCheckinRequest && dumpDetails) {
14970                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14971                        }
14972                        if (mi == null) {
14973                            mi = new Debug.MemoryInfo();
14974                        }
14975                        if (dumpDetails || (!brief && !oomOnly)) {
14976                            Debug.getMemoryInfo(pid, mi);
14977                        } else {
14978                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14979                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14980                        }
14981                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14982                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14983                        if (isCheckinRequest) {
14984                            pw.println();
14985                        }
14986                    }
14987                    return;
14988                }
14989            }
14990            pw.println("No process found for: " + args[opti]);
14991            return;
14992        }
14993
14994        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14995            dumpDetails = true;
14996        }
14997
14998        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14999
15000        String[] innerArgs = new String[args.length-opti];
15001        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15002
15003        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15004        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15005        long nativePss = 0;
15006        long dalvikPss = 0;
15007        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15008                EmptyArray.LONG;
15009        long otherPss = 0;
15010        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15011
15012        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15013        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15014                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15015
15016        long totalPss = 0;
15017        long cachedPss = 0;
15018
15019        Debug.MemoryInfo mi = null;
15020        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15021            final ProcessRecord r = procs.get(i);
15022            final IApplicationThread thread;
15023            final int pid;
15024            final int oomAdj;
15025            final boolean hasActivities;
15026            synchronized (this) {
15027                thread = r.thread;
15028                pid = r.pid;
15029                oomAdj = r.getSetAdjWithServices();
15030                hasActivities = r.activities.size() > 0;
15031            }
15032            if (thread != null) {
15033                if (!isCheckinRequest && dumpDetails) {
15034                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15035                }
15036                if (mi == null) {
15037                    mi = new Debug.MemoryInfo();
15038                }
15039                if (dumpDetails || (!brief && !oomOnly)) {
15040                    Debug.getMemoryInfo(pid, mi);
15041                } else {
15042                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15043                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15044                }
15045                if (dumpDetails) {
15046                    if (localOnly) {
15047                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15048                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15049                        if (isCheckinRequest) {
15050                            pw.println();
15051                        }
15052                    } else {
15053                        try {
15054                            pw.flush();
15055                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15056                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15057                        } catch (RemoteException e) {
15058                            if (!isCheckinRequest) {
15059                                pw.println("Got RemoteException!");
15060                                pw.flush();
15061                            }
15062                        }
15063                    }
15064                }
15065
15066                final long myTotalPss = mi.getTotalPss();
15067                final long myTotalUss = mi.getTotalUss();
15068
15069                synchronized (this) {
15070                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15071                        // Record this for posterity if the process has been stable.
15072                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15073                    }
15074                }
15075
15076                if (!isCheckinRequest && mi != null) {
15077                    totalPss += myTotalPss;
15078                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15079                            (hasActivities ? " / activities)" : ")"),
15080                            r.processName, myTotalPss, pid, hasActivities);
15081                    procMems.add(pssItem);
15082                    procMemsMap.put(pid, pssItem);
15083
15084                    nativePss += mi.nativePss;
15085                    dalvikPss += mi.dalvikPss;
15086                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15087                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15088                    }
15089                    otherPss += mi.otherPss;
15090                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15091                        long mem = mi.getOtherPss(j);
15092                        miscPss[j] += mem;
15093                        otherPss -= mem;
15094                    }
15095
15096                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15097                        cachedPss += myTotalPss;
15098                    }
15099
15100                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15101                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15102                                || oomIndex == (oomPss.length-1)) {
15103                            oomPss[oomIndex] += myTotalPss;
15104                            if (oomProcs[oomIndex] == null) {
15105                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15106                            }
15107                            oomProcs[oomIndex].add(pssItem);
15108                            break;
15109                        }
15110                    }
15111                }
15112            }
15113        }
15114
15115        long nativeProcTotalPss = 0;
15116
15117        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15118            // If we are showing aggregations, also look for native processes to
15119            // include so that our aggregations are more accurate.
15120            updateCpuStatsNow();
15121            mi = null;
15122            synchronized (mProcessCpuTracker) {
15123                final int N = mProcessCpuTracker.countStats();
15124                for (int i=0; i<N; i++) {
15125                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15126                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15127                        if (mi == null) {
15128                            mi = new Debug.MemoryInfo();
15129                        }
15130                        if (!brief && !oomOnly) {
15131                            Debug.getMemoryInfo(st.pid, mi);
15132                        } else {
15133                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15134                            mi.nativePrivateDirty = (int)tmpLong[0];
15135                        }
15136
15137                        final long myTotalPss = mi.getTotalPss();
15138                        totalPss += myTotalPss;
15139                        nativeProcTotalPss += myTotalPss;
15140
15141                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15142                                st.name, myTotalPss, st.pid, false);
15143                        procMems.add(pssItem);
15144
15145                        nativePss += mi.nativePss;
15146                        dalvikPss += mi.dalvikPss;
15147                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15148                            dalvikSubitemPss[j] += mi.getOtherPss(
15149                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15150                        }
15151                        otherPss += mi.otherPss;
15152                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15153                            long mem = mi.getOtherPss(j);
15154                            miscPss[j] += mem;
15155                            otherPss -= mem;
15156                        }
15157                        oomPss[0] += myTotalPss;
15158                        if (oomProcs[0] == null) {
15159                            oomProcs[0] = new ArrayList<MemItem>();
15160                        }
15161                        oomProcs[0].add(pssItem);
15162                    }
15163                }
15164            }
15165
15166            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15167
15168            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15169            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15170            if (dalvikSubitemPss.length > 0) {
15171                dalvikItem.subitems = new ArrayList<MemItem>();
15172                for (int j=0; j<dalvikSubitemPss.length; j++) {
15173                    final String name = Debug.MemoryInfo.getOtherLabel(
15174                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15175                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15176                }
15177            }
15178            catMems.add(dalvikItem);
15179            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15180            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15181                String label = Debug.MemoryInfo.getOtherLabel(j);
15182                catMems.add(new MemItem(label, label, miscPss[j], j));
15183            }
15184
15185            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15186            for (int j=0; j<oomPss.length; j++) {
15187                if (oomPss[j] != 0) {
15188                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15189                            : DUMP_MEM_OOM_LABEL[j];
15190                    MemItem item = new MemItem(label, label, oomPss[j],
15191                            DUMP_MEM_OOM_ADJ[j]);
15192                    item.subitems = oomProcs[j];
15193                    oomMems.add(item);
15194                }
15195            }
15196
15197            if (!brief && !oomOnly && !isCompact) {
15198                pw.println();
15199                pw.println("Total PSS by process:");
15200                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15201                pw.println();
15202            }
15203            if (!isCompact) {
15204                pw.println("Total PSS by OOM adjustment:");
15205            }
15206            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15207            if (!brief && !oomOnly) {
15208                PrintWriter out = categoryPw != null ? categoryPw : pw;
15209                if (!isCompact) {
15210                    out.println();
15211                    out.println("Total PSS by category:");
15212                }
15213                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15214            }
15215            if (!isCompact) {
15216                pw.println();
15217            }
15218            MemInfoReader memInfo = new MemInfoReader();
15219            memInfo.readMemInfo();
15220            if (nativeProcTotalPss > 0) {
15221                synchronized (this) {
15222                    final long cachedKb = memInfo.getCachedSizeKb();
15223                    final long freeKb = memInfo.getFreeSizeKb();
15224                    final long zramKb = memInfo.getZramTotalSizeKb();
15225                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15226                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15227                            kernelKb*1024, nativeProcTotalPss*1024);
15228                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15229                            nativeProcTotalPss);
15230                }
15231            }
15232            if (!brief) {
15233                if (!isCompact) {
15234                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15235                    pw.print(" (status ");
15236                    switch (mLastMemoryLevel) {
15237                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15238                            pw.println("normal)");
15239                            break;
15240                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15241                            pw.println("moderate)");
15242                            break;
15243                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15244                            pw.println("low)");
15245                            break;
15246                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15247                            pw.println("critical)");
15248                            break;
15249                        default:
15250                            pw.print(mLastMemoryLevel);
15251                            pw.println(")");
15252                            break;
15253                    }
15254                    pw.print(" Free RAM: ");
15255                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15256                            + memInfo.getFreeSizeKb()));
15257                    pw.print(" (");
15258                    pw.print(stringifyKBSize(cachedPss));
15259                    pw.print(" cached pss + ");
15260                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15261                    pw.print(" cached kernel + ");
15262                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15263                    pw.println(" free)");
15264                } else {
15265                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15266                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15267                            + memInfo.getFreeSizeKb()); pw.print(",");
15268                    pw.println(totalPss - cachedPss);
15269                }
15270            }
15271            if (!isCompact) {
15272                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15273                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15274                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15275                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15276                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15277                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15278                        - memInfo.getKernelUsedSizeKb()));
15279            }
15280            if (!brief) {
15281                if (memInfo.getZramTotalSizeKb() != 0) {
15282                    if (!isCompact) {
15283                        pw.print("     ZRAM: ");
15284                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15285                                pw.print(" physical used for ");
15286                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15287                                        - memInfo.getSwapFreeSizeKb()));
15288                                pw.print(" in swap (");
15289                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15290                                pw.println(" total swap)");
15291                    } else {
15292                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15293                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15294                                pw.println(memInfo.getSwapFreeSizeKb());
15295                    }
15296                }
15297                final long[] ksm = getKsmInfo();
15298                if (!isCompact) {
15299                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15300                            || ksm[KSM_VOLATILE] != 0) {
15301                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15302                                pw.print(" saved from shared ");
15303                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15304                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15305                                pw.print(" unshared; ");
15306                                pw.print(stringifyKBSize(
15307                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15308                    }
15309                    pw.print("   Tuning: ");
15310                    pw.print(ActivityManager.staticGetMemoryClass());
15311                    pw.print(" (large ");
15312                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15313                    pw.print("), oom ");
15314                    pw.print(stringifySize(
15315                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15316                    pw.print(", restore limit ");
15317                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15318                    if (ActivityManager.isLowRamDeviceStatic()) {
15319                        pw.print(" (low-ram)");
15320                    }
15321                    if (ActivityManager.isHighEndGfx()) {
15322                        pw.print(" (high-end-gfx)");
15323                    }
15324                    pw.println();
15325                } else {
15326                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15327                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15328                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15329                    pw.print("tuning,");
15330                    pw.print(ActivityManager.staticGetMemoryClass());
15331                    pw.print(',');
15332                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15333                    pw.print(',');
15334                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15335                    if (ActivityManager.isLowRamDeviceStatic()) {
15336                        pw.print(",low-ram");
15337                    }
15338                    if (ActivityManager.isHighEndGfx()) {
15339                        pw.print(",high-end-gfx");
15340                    }
15341                    pw.println();
15342                }
15343            }
15344        }
15345    }
15346
15347    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15348            long memtrack, String name) {
15349        sb.append("  ");
15350        sb.append(ProcessList.makeOomAdjString(oomAdj));
15351        sb.append(' ');
15352        sb.append(ProcessList.makeProcStateString(procState));
15353        sb.append(' ');
15354        ProcessList.appendRamKb(sb, pss);
15355        sb.append(": ");
15356        sb.append(name);
15357        if (memtrack > 0) {
15358            sb.append(" (");
15359            sb.append(stringifyKBSize(memtrack));
15360            sb.append(" memtrack)");
15361        }
15362    }
15363
15364    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15365        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15366        sb.append(" (pid ");
15367        sb.append(mi.pid);
15368        sb.append(") ");
15369        sb.append(mi.adjType);
15370        sb.append('\n');
15371        if (mi.adjReason != null) {
15372            sb.append("                      ");
15373            sb.append(mi.adjReason);
15374            sb.append('\n');
15375        }
15376    }
15377
15378    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15379        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15380        for (int i=0, N=memInfos.size(); i<N; i++) {
15381            ProcessMemInfo mi = memInfos.get(i);
15382            infoMap.put(mi.pid, mi);
15383        }
15384        updateCpuStatsNow();
15385        long[] memtrackTmp = new long[1];
15386        synchronized (mProcessCpuTracker) {
15387            final int N = mProcessCpuTracker.countStats();
15388            for (int i=0; i<N; i++) {
15389                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15390                if (st.vsize > 0) {
15391                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15392                    if (pss > 0) {
15393                        if (infoMap.indexOfKey(st.pid) < 0) {
15394                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15395                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15396                            mi.pss = pss;
15397                            mi.memtrack = memtrackTmp[0];
15398                            memInfos.add(mi);
15399                        }
15400                    }
15401                }
15402            }
15403        }
15404
15405        long totalPss = 0;
15406        long totalMemtrack = 0;
15407        for (int i=0, N=memInfos.size(); i<N; i++) {
15408            ProcessMemInfo mi = memInfos.get(i);
15409            if (mi.pss == 0) {
15410                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15411                mi.memtrack = memtrackTmp[0];
15412            }
15413            totalPss += mi.pss;
15414            totalMemtrack += mi.memtrack;
15415        }
15416        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15417            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15418                if (lhs.oomAdj != rhs.oomAdj) {
15419                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15420                }
15421                if (lhs.pss != rhs.pss) {
15422                    return lhs.pss < rhs.pss ? 1 : -1;
15423                }
15424                return 0;
15425            }
15426        });
15427
15428        StringBuilder tag = new StringBuilder(128);
15429        StringBuilder stack = new StringBuilder(128);
15430        tag.append("Low on memory -- ");
15431        appendMemBucket(tag, totalPss, "total", false);
15432        appendMemBucket(stack, totalPss, "total", true);
15433
15434        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15435        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15436        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15437
15438        boolean firstLine = true;
15439        int lastOomAdj = Integer.MIN_VALUE;
15440        long extraNativeRam = 0;
15441        long extraNativeMemtrack = 0;
15442        long cachedPss = 0;
15443        for (int i=0, N=memInfos.size(); i<N; i++) {
15444            ProcessMemInfo mi = memInfos.get(i);
15445
15446            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15447                cachedPss += mi.pss;
15448            }
15449
15450            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15451                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15452                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15453                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15454                if (lastOomAdj != mi.oomAdj) {
15455                    lastOomAdj = mi.oomAdj;
15456                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15457                        tag.append(" / ");
15458                    }
15459                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15460                        if (firstLine) {
15461                            stack.append(":");
15462                            firstLine = false;
15463                        }
15464                        stack.append("\n\t at ");
15465                    } else {
15466                        stack.append("$");
15467                    }
15468                } else {
15469                    tag.append(" ");
15470                    stack.append("$");
15471                }
15472                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15473                    appendMemBucket(tag, mi.pss, mi.name, false);
15474                }
15475                appendMemBucket(stack, mi.pss, mi.name, true);
15476                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15477                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15478                    stack.append("(");
15479                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15480                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15481                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15482                            stack.append(":");
15483                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15484                        }
15485                    }
15486                    stack.append(")");
15487                }
15488            }
15489
15490            appendMemInfo(fullNativeBuilder, mi);
15491            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15492                // The short form only has native processes that are >= 512K.
15493                if (mi.pss >= 512) {
15494                    appendMemInfo(shortNativeBuilder, mi);
15495                } else {
15496                    extraNativeRam += mi.pss;
15497                    extraNativeMemtrack += mi.memtrack;
15498                }
15499            } else {
15500                // Short form has all other details, but if we have collected RAM
15501                // from smaller native processes let's dump a summary of that.
15502                if (extraNativeRam > 0) {
15503                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15504                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15505                    shortNativeBuilder.append('\n');
15506                    extraNativeRam = 0;
15507                }
15508                appendMemInfo(fullJavaBuilder, mi);
15509            }
15510        }
15511
15512        fullJavaBuilder.append("           ");
15513        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15514        fullJavaBuilder.append(": TOTAL");
15515        if (totalMemtrack > 0) {
15516            fullJavaBuilder.append(" (");
15517            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15518            fullJavaBuilder.append(" memtrack)");
15519        } else {
15520        }
15521        fullJavaBuilder.append("\n");
15522
15523        MemInfoReader memInfo = new MemInfoReader();
15524        memInfo.readMemInfo();
15525        final long[] infos = memInfo.getRawInfo();
15526
15527        StringBuilder memInfoBuilder = new StringBuilder(1024);
15528        Debug.getMemInfo(infos);
15529        memInfoBuilder.append("  MemInfo: ");
15530        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15531        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15532        memInfoBuilder.append(stringifyKBSize(
15533                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15534        memInfoBuilder.append(stringifyKBSize(
15535                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15536        memInfoBuilder.append(stringifyKBSize(
15537                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15538        memInfoBuilder.append("           ");
15539        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15540        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15541        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15542        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15543        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15544            memInfoBuilder.append("  ZRAM: ");
15545            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15546            memInfoBuilder.append(" RAM, ");
15547            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15548            memInfoBuilder.append(" swap total, ");
15549            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15550            memInfoBuilder.append(" swap free\n");
15551        }
15552        final long[] ksm = getKsmInfo();
15553        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15554                || ksm[KSM_VOLATILE] != 0) {
15555            memInfoBuilder.append("  KSM: ");
15556            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15557            memInfoBuilder.append(" saved from shared ");
15558            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15559            memInfoBuilder.append("\n       ");
15560            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15561            memInfoBuilder.append(" unshared; ");
15562            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15563            memInfoBuilder.append(" volatile\n");
15564        }
15565        memInfoBuilder.append("  Free RAM: ");
15566        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15567                + memInfo.getFreeSizeKb()));
15568        memInfoBuilder.append("\n");
15569        memInfoBuilder.append("  Used RAM: ");
15570        memInfoBuilder.append(stringifyKBSize(
15571                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15572        memInfoBuilder.append("\n");
15573        memInfoBuilder.append("  Lost RAM: ");
15574        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15575                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15576                - memInfo.getKernelUsedSizeKb()));
15577        memInfoBuilder.append("\n");
15578        Slog.i(TAG, "Low on memory:");
15579        Slog.i(TAG, shortNativeBuilder.toString());
15580        Slog.i(TAG, fullJavaBuilder.toString());
15581        Slog.i(TAG, memInfoBuilder.toString());
15582
15583        StringBuilder dropBuilder = new StringBuilder(1024);
15584        /*
15585        StringWriter oomSw = new StringWriter();
15586        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15587        StringWriter catSw = new StringWriter();
15588        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15589        String[] emptyArgs = new String[] { };
15590        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15591        oomPw.flush();
15592        String oomString = oomSw.toString();
15593        */
15594        dropBuilder.append("Low on memory:");
15595        dropBuilder.append(stack);
15596        dropBuilder.append('\n');
15597        dropBuilder.append(fullNativeBuilder);
15598        dropBuilder.append(fullJavaBuilder);
15599        dropBuilder.append('\n');
15600        dropBuilder.append(memInfoBuilder);
15601        dropBuilder.append('\n');
15602        /*
15603        dropBuilder.append(oomString);
15604        dropBuilder.append('\n');
15605        */
15606        StringWriter catSw = new StringWriter();
15607        synchronized (ActivityManagerService.this) {
15608            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15609            String[] emptyArgs = new String[] { };
15610            catPw.println();
15611            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15612            catPw.println();
15613            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15614                    false, false, null);
15615            catPw.println();
15616            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15617            catPw.flush();
15618        }
15619        dropBuilder.append(catSw.toString());
15620        addErrorToDropBox("lowmem", null, "system_server", null,
15621                null, tag.toString(), dropBuilder.toString(), null, null);
15622        //Slog.i(TAG, "Sent to dropbox:");
15623        //Slog.i(TAG, dropBuilder.toString());
15624        synchronized (ActivityManagerService.this) {
15625            long now = SystemClock.uptimeMillis();
15626            if (mLastMemUsageReportTime < now) {
15627                mLastMemUsageReportTime = now;
15628            }
15629        }
15630    }
15631
15632    /**
15633     * Searches array of arguments for the specified string
15634     * @param args array of argument strings
15635     * @param value value to search for
15636     * @return true if the value is contained in the array
15637     */
15638    private static boolean scanArgs(String[] args, String value) {
15639        if (args != null) {
15640            for (String arg : args) {
15641                if (value.equals(arg)) {
15642                    return true;
15643                }
15644            }
15645        }
15646        return false;
15647    }
15648
15649    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15650            ContentProviderRecord cpr, boolean always) {
15651        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15652
15653        if (!inLaunching || always) {
15654            synchronized (cpr) {
15655                cpr.launchingApp = null;
15656                cpr.notifyAll();
15657            }
15658            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15659            String names[] = cpr.info.authority.split(";");
15660            for (int j = 0; j < names.length; j++) {
15661                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15662            }
15663        }
15664
15665        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15666            ContentProviderConnection conn = cpr.connections.get(i);
15667            if (conn.waiting) {
15668                // If this connection is waiting for the provider, then we don't
15669                // need to mess with its process unless we are always removing
15670                // or for some reason the provider is not currently launching.
15671                if (inLaunching && !always) {
15672                    continue;
15673                }
15674            }
15675            ProcessRecord capp = conn.client;
15676            conn.dead = true;
15677            if (conn.stableCount > 0) {
15678                if (!capp.persistent && capp.thread != null
15679                        && capp.pid != 0
15680                        && capp.pid != MY_PID) {
15681                    capp.kill("depends on provider "
15682                            + cpr.name.flattenToShortString()
15683                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15684                }
15685            } else if (capp.thread != null && conn.provider.provider != null) {
15686                try {
15687                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15688                } catch (RemoteException e) {
15689                }
15690                // In the protocol here, we don't expect the client to correctly
15691                // clean up this connection, we'll just remove it.
15692                cpr.connections.remove(i);
15693                if (conn.client.conProviders.remove(conn)) {
15694                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15695                }
15696            }
15697        }
15698
15699        if (inLaunching && always) {
15700            mLaunchingProviders.remove(cpr);
15701        }
15702        return inLaunching;
15703    }
15704
15705    /**
15706     * Main code for cleaning up a process when it has gone away.  This is
15707     * called both as a result of the process dying, or directly when stopping
15708     * a process when running in single process mode.
15709     *
15710     * @return Returns true if the given process has been restarted, so the
15711     * app that was passed in must remain on the process lists.
15712     */
15713    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15714            boolean restarting, boolean allowRestart, int index) {
15715        if (index >= 0) {
15716            removeLruProcessLocked(app);
15717            ProcessList.remove(app.pid);
15718        }
15719
15720        mProcessesToGc.remove(app);
15721        mPendingPssProcesses.remove(app);
15722
15723        // Dismiss any open dialogs.
15724        if (app.crashDialog != null && !app.forceCrashReport) {
15725            app.crashDialog.dismiss();
15726            app.crashDialog = null;
15727        }
15728        if (app.anrDialog != null) {
15729            app.anrDialog.dismiss();
15730            app.anrDialog = null;
15731        }
15732        if (app.waitDialog != null) {
15733            app.waitDialog.dismiss();
15734            app.waitDialog = null;
15735        }
15736
15737        app.crashing = false;
15738        app.notResponding = false;
15739
15740        app.resetPackageList(mProcessStats);
15741        app.unlinkDeathRecipient();
15742        app.makeInactive(mProcessStats);
15743        app.waitingToKill = null;
15744        app.forcingToForeground = null;
15745        updateProcessForegroundLocked(app, false, false);
15746        app.foregroundActivities = false;
15747        app.hasShownUi = false;
15748        app.treatLikeActivity = false;
15749        app.hasAboveClient = false;
15750        app.hasClientActivities = false;
15751
15752        mServices.killServicesLocked(app, allowRestart);
15753
15754        boolean restart = false;
15755
15756        // Remove published content providers.
15757        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15758            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15759            final boolean always = app.bad || !allowRestart;
15760            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15761            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15762                // We left the provider in the launching list, need to
15763                // restart it.
15764                restart = true;
15765            }
15766
15767            cpr.provider = null;
15768            cpr.proc = null;
15769        }
15770        app.pubProviders.clear();
15771
15772        // Take care of any launching providers waiting for this process.
15773        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15774            restart = true;
15775        }
15776
15777        // Unregister from connected content providers.
15778        if (!app.conProviders.isEmpty()) {
15779            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15780                ContentProviderConnection conn = app.conProviders.get(i);
15781                conn.provider.connections.remove(conn);
15782                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15783                        conn.provider.name);
15784            }
15785            app.conProviders.clear();
15786        }
15787
15788        // At this point there may be remaining entries in mLaunchingProviders
15789        // where we were the only one waiting, so they are no longer of use.
15790        // Look for these and clean up if found.
15791        // XXX Commented out for now.  Trying to figure out a way to reproduce
15792        // the actual situation to identify what is actually going on.
15793        if (false) {
15794            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15795                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15796                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15797                    synchronized (cpr) {
15798                        cpr.launchingApp = null;
15799                        cpr.notifyAll();
15800                    }
15801                }
15802            }
15803        }
15804
15805        skipCurrentReceiverLocked(app);
15806
15807        // Unregister any receivers.
15808        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15809            removeReceiverLocked(app.receivers.valueAt(i));
15810        }
15811        app.receivers.clear();
15812
15813        // If the app is undergoing backup, tell the backup manager about it
15814        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15815            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15816                    + mBackupTarget.appInfo + " died during backup");
15817            try {
15818                IBackupManager bm = IBackupManager.Stub.asInterface(
15819                        ServiceManager.getService(Context.BACKUP_SERVICE));
15820                bm.agentDisconnected(app.info.packageName);
15821            } catch (RemoteException e) {
15822                // can't happen; backup manager is local
15823            }
15824        }
15825
15826        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15827            ProcessChangeItem item = mPendingProcessChanges.get(i);
15828            if (item.pid == app.pid) {
15829                mPendingProcessChanges.remove(i);
15830                mAvailProcessChanges.add(item);
15831            }
15832        }
15833        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15834
15835        // If the caller is restarting this app, then leave it in its
15836        // current lists and let the caller take care of it.
15837        if (restarting) {
15838            return false;
15839        }
15840
15841        if (!app.persistent || app.isolated) {
15842            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15843                    "Removing non-persistent process during cleanup: " + app);
15844            removeProcessNameLocked(app.processName, app.uid);
15845            if (mHeavyWeightProcess == app) {
15846                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15847                        mHeavyWeightProcess.userId, 0));
15848                mHeavyWeightProcess = null;
15849            }
15850        } else if (!app.removed) {
15851            // This app is persistent, so we need to keep its record around.
15852            // If it is not already on the pending app list, add it there
15853            // and start a new process for it.
15854            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15855                mPersistentStartingProcesses.add(app);
15856                restart = true;
15857            }
15858        }
15859        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15860                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15861        mProcessesOnHold.remove(app);
15862
15863        if (app == mHomeProcess) {
15864            mHomeProcess = null;
15865        }
15866        if (app == mPreviousProcess) {
15867            mPreviousProcess = null;
15868        }
15869
15870        if (restart && !app.isolated) {
15871            // We have components that still need to be running in the
15872            // process, so re-launch it.
15873            if (index < 0) {
15874                ProcessList.remove(app.pid);
15875            }
15876            addProcessNameLocked(app);
15877            startProcessLocked(app, "restart", app.processName);
15878            return true;
15879        } else if (app.pid > 0 && app.pid != MY_PID) {
15880            // Goodbye!
15881            boolean removed;
15882            synchronized (mPidsSelfLocked) {
15883                mPidsSelfLocked.remove(app.pid);
15884                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15885            }
15886            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15887            if (app.isolated) {
15888                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15889            }
15890            app.setPid(0);
15891        }
15892        return false;
15893    }
15894
15895    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15896        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15897            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15898            if (cpr.launchingApp == app) {
15899                return true;
15900            }
15901        }
15902        return false;
15903    }
15904
15905    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15906        // Look through the content providers we are waiting to have launched,
15907        // and if any run in this process then either schedule a restart of
15908        // the process or kill the client waiting for it if this process has
15909        // gone bad.
15910        boolean restart = false;
15911        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15912            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15913            if (cpr.launchingApp == app) {
15914                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15915                    restart = true;
15916                } else {
15917                    removeDyingProviderLocked(app, cpr, true);
15918                }
15919            }
15920        }
15921        return restart;
15922    }
15923
15924    // =========================================================
15925    // SERVICES
15926    // =========================================================
15927
15928    @Override
15929    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15930            int flags) {
15931        enforceNotIsolatedCaller("getServices");
15932        synchronized (this) {
15933            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15934        }
15935    }
15936
15937    @Override
15938    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15939        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15940        synchronized (this) {
15941            return mServices.getRunningServiceControlPanelLocked(name);
15942        }
15943    }
15944
15945    @Override
15946    public ComponentName startService(IApplicationThread caller, Intent service,
15947            String resolvedType, String callingPackage, int userId)
15948            throws TransactionTooLargeException {
15949        enforceNotIsolatedCaller("startService");
15950        // Refuse possible leaked file descriptors
15951        if (service != null && service.hasFileDescriptors() == true) {
15952            throw new IllegalArgumentException("File descriptors passed in Intent");
15953        }
15954
15955        if (callingPackage == null) {
15956            throw new IllegalArgumentException("callingPackage cannot be null");
15957        }
15958
15959        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15960                "startService: " + service + " type=" + resolvedType);
15961        synchronized(this) {
15962            final int callingPid = Binder.getCallingPid();
15963            final int callingUid = Binder.getCallingUid();
15964            final long origId = Binder.clearCallingIdentity();
15965            ComponentName res = mServices.startServiceLocked(caller, service,
15966                    resolvedType, callingPid, callingUid, callingPackage, userId);
15967            Binder.restoreCallingIdentity(origId);
15968            return res;
15969        }
15970    }
15971
15972    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15973            String callingPackage, int userId)
15974            throws TransactionTooLargeException {
15975        synchronized(this) {
15976            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15977                    "startServiceInPackage: " + service + " type=" + resolvedType);
15978            final long origId = Binder.clearCallingIdentity();
15979            ComponentName res = mServices.startServiceLocked(null, service,
15980                    resolvedType, -1, uid, callingPackage, userId);
15981            Binder.restoreCallingIdentity(origId);
15982            return res;
15983        }
15984    }
15985
15986    @Override
15987    public int stopService(IApplicationThread caller, Intent service,
15988            String resolvedType, int userId) {
15989        enforceNotIsolatedCaller("stopService");
15990        // Refuse possible leaked file descriptors
15991        if (service != null && service.hasFileDescriptors() == true) {
15992            throw new IllegalArgumentException("File descriptors passed in Intent");
15993        }
15994
15995        synchronized(this) {
15996            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15997        }
15998    }
15999
16000    @Override
16001    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16002        enforceNotIsolatedCaller("peekService");
16003        // Refuse possible leaked file descriptors
16004        if (service != null && service.hasFileDescriptors() == true) {
16005            throw new IllegalArgumentException("File descriptors passed in Intent");
16006        }
16007
16008        if (callingPackage == null) {
16009            throw new IllegalArgumentException("callingPackage cannot be null");
16010        }
16011
16012        synchronized(this) {
16013            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16014        }
16015    }
16016
16017    @Override
16018    public boolean stopServiceToken(ComponentName className, IBinder token,
16019            int startId) {
16020        synchronized(this) {
16021            return mServices.stopServiceTokenLocked(className, token, startId);
16022        }
16023    }
16024
16025    @Override
16026    public void setServiceForeground(ComponentName className, IBinder token,
16027            int id, Notification notification, boolean removeNotification) {
16028        synchronized(this) {
16029            mServices.setServiceForegroundLocked(className, token, id, notification,
16030                    removeNotification);
16031        }
16032    }
16033
16034    @Override
16035    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16036            boolean requireFull, String name, String callerPackage) {
16037        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16038                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16039    }
16040
16041    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16042            String className, int flags) {
16043        boolean result = false;
16044        // For apps that don't have pre-defined UIDs, check for permission
16045        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16046            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16047                if (ActivityManager.checkUidPermission(
16048                        INTERACT_ACROSS_USERS,
16049                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16050                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16051                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16052                            + " requests FLAG_SINGLE_USER, but app does not hold "
16053                            + INTERACT_ACROSS_USERS;
16054                    Slog.w(TAG, msg);
16055                    throw new SecurityException(msg);
16056                }
16057                // Permission passed
16058                result = true;
16059            }
16060        } else if ("system".equals(componentProcessName)) {
16061            result = true;
16062        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16063            // Phone app and persistent apps are allowed to export singleuser providers.
16064            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16065                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16066        }
16067        if (DEBUG_MU) Slog.v(TAG_MU,
16068                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16069                + Integer.toHexString(flags) + ") = " + result);
16070        return result;
16071    }
16072
16073    /**
16074     * Checks to see if the caller is in the same app as the singleton
16075     * component, or the component is in a special app. It allows special apps
16076     * to export singleton components but prevents exporting singleton
16077     * components for regular apps.
16078     */
16079    boolean isValidSingletonCall(int callingUid, int componentUid) {
16080        int componentAppId = UserHandle.getAppId(componentUid);
16081        return UserHandle.isSameApp(callingUid, componentUid)
16082                || componentAppId == Process.SYSTEM_UID
16083                || componentAppId == Process.PHONE_UID
16084                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16085                        == PackageManager.PERMISSION_GRANTED;
16086    }
16087
16088    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16089            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16090            int userId) throws TransactionTooLargeException {
16091        enforceNotIsolatedCaller("bindService");
16092
16093        // Refuse possible leaked file descriptors
16094        if (service != null && service.hasFileDescriptors() == true) {
16095            throw new IllegalArgumentException("File descriptors passed in Intent");
16096        }
16097
16098        if (callingPackage == null) {
16099            throw new IllegalArgumentException("callingPackage cannot be null");
16100        }
16101
16102        synchronized(this) {
16103            return mServices.bindServiceLocked(caller, token, service,
16104                    resolvedType, connection, flags, callingPackage, userId);
16105        }
16106    }
16107
16108    public boolean unbindService(IServiceConnection connection) {
16109        synchronized (this) {
16110            return mServices.unbindServiceLocked(connection);
16111        }
16112    }
16113
16114    public void publishService(IBinder token, Intent intent, IBinder service) {
16115        // Refuse possible leaked file descriptors
16116        if (intent != null && intent.hasFileDescriptors() == true) {
16117            throw new IllegalArgumentException("File descriptors passed in Intent");
16118        }
16119
16120        synchronized(this) {
16121            if (!(token instanceof ServiceRecord)) {
16122                throw new IllegalArgumentException("Invalid service token");
16123            }
16124            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16125        }
16126    }
16127
16128    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16129        // Refuse possible leaked file descriptors
16130        if (intent != null && intent.hasFileDescriptors() == true) {
16131            throw new IllegalArgumentException("File descriptors passed in Intent");
16132        }
16133
16134        synchronized(this) {
16135            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16136        }
16137    }
16138
16139    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16140        synchronized(this) {
16141            if (!(token instanceof ServiceRecord)) {
16142                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16143                throw new IllegalArgumentException("Invalid service token");
16144            }
16145            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16146        }
16147    }
16148
16149    // =========================================================
16150    // BACKUP AND RESTORE
16151    // =========================================================
16152
16153    // Cause the target app to be launched if necessary and its backup agent
16154    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16155    // activity manager to announce its creation.
16156    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16157        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16158                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16159        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16160
16161        synchronized(this) {
16162            // !!! TODO: currently no check here that we're already bound
16163            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16164            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16165            synchronized (stats) {
16166                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16167            }
16168
16169            // Backup agent is now in use, its package can't be stopped.
16170            try {
16171                AppGlobals.getPackageManager().setPackageStoppedState(
16172                        app.packageName, false, UserHandle.getUserId(app.uid));
16173            } catch (RemoteException e) {
16174            } catch (IllegalArgumentException e) {
16175                Slog.w(TAG, "Failed trying to unstop package "
16176                        + app.packageName + ": " + e);
16177            }
16178
16179            BackupRecord r = new BackupRecord(ss, app, backupMode);
16180            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16181                    ? new ComponentName(app.packageName, app.backupAgentName)
16182                    : new ComponentName("android", "FullBackupAgent");
16183            // startProcessLocked() returns existing proc's record if it's already running
16184            ProcessRecord proc = startProcessLocked(app.processName, app,
16185                    false, 0, "backup", hostingName, false, false, false);
16186            if (proc == null) {
16187                Slog.e(TAG, "Unable to start backup agent process " + r);
16188                return false;
16189            }
16190
16191            r.app = proc;
16192            mBackupTarget = r;
16193            mBackupAppName = app.packageName;
16194
16195            // Try not to kill the process during backup
16196            updateOomAdjLocked(proc);
16197
16198            // If the process is already attached, schedule the creation of the backup agent now.
16199            // If it is not yet live, this will be done when it attaches to the framework.
16200            if (proc.thread != null) {
16201                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16202                try {
16203                    proc.thread.scheduleCreateBackupAgent(app,
16204                            compatibilityInfoForPackageLocked(app), backupMode);
16205                } catch (RemoteException e) {
16206                    // Will time out on the backup manager side
16207                }
16208            } else {
16209                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16210            }
16211            // Invariants: at this point, the target app process exists and the application
16212            // is either already running or in the process of coming up.  mBackupTarget and
16213            // mBackupAppName describe the app, so that when it binds back to the AM we
16214            // know that it's scheduled for a backup-agent operation.
16215        }
16216
16217        return true;
16218    }
16219
16220    @Override
16221    public void clearPendingBackup() {
16222        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16223        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16224
16225        synchronized (this) {
16226            mBackupTarget = null;
16227            mBackupAppName = null;
16228        }
16229    }
16230
16231    // A backup agent has just come up
16232    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16233        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16234                + " = " + agent);
16235
16236        synchronized(this) {
16237            if (!agentPackageName.equals(mBackupAppName)) {
16238                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16239                return;
16240            }
16241        }
16242
16243        long oldIdent = Binder.clearCallingIdentity();
16244        try {
16245            IBackupManager bm = IBackupManager.Stub.asInterface(
16246                    ServiceManager.getService(Context.BACKUP_SERVICE));
16247            bm.agentConnected(agentPackageName, agent);
16248        } catch (RemoteException e) {
16249            // can't happen; the backup manager service is local
16250        } catch (Exception e) {
16251            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16252            e.printStackTrace();
16253        } finally {
16254            Binder.restoreCallingIdentity(oldIdent);
16255        }
16256    }
16257
16258    // done with this agent
16259    public void unbindBackupAgent(ApplicationInfo appInfo) {
16260        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16261        if (appInfo == null) {
16262            Slog.w(TAG, "unbind backup agent for null app");
16263            return;
16264        }
16265
16266        synchronized(this) {
16267            try {
16268                if (mBackupAppName == null) {
16269                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16270                    return;
16271                }
16272
16273                if (!mBackupAppName.equals(appInfo.packageName)) {
16274                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16275                    return;
16276                }
16277
16278                // Not backing this app up any more; reset its OOM adjustment
16279                final ProcessRecord proc = mBackupTarget.app;
16280                updateOomAdjLocked(proc);
16281
16282                // If the app crashed during backup, 'thread' will be null here
16283                if (proc.thread != null) {
16284                    try {
16285                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16286                                compatibilityInfoForPackageLocked(appInfo));
16287                    } catch (Exception e) {
16288                        Slog.e(TAG, "Exception when unbinding backup agent:");
16289                        e.printStackTrace();
16290                    }
16291                }
16292            } finally {
16293                mBackupTarget = null;
16294                mBackupAppName = null;
16295            }
16296        }
16297    }
16298    // =========================================================
16299    // BROADCASTS
16300    // =========================================================
16301
16302    boolean isPendingBroadcastProcessLocked(int pid) {
16303        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16304                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16305    }
16306
16307    void skipPendingBroadcastLocked(int pid) {
16308            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16309            for (BroadcastQueue queue : mBroadcastQueues) {
16310                queue.skipPendingBroadcastLocked(pid);
16311            }
16312    }
16313
16314    // The app just attached; send any pending broadcasts that it should receive
16315    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16316        boolean didSomething = false;
16317        for (BroadcastQueue queue : mBroadcastQueues) {
16318            didSomething |= queue.sendPendingBroadcastsLocked(app);
16319        }
16320        return didSomething;
16321    }
16322
16323    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16324            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16325        enforceNotIsolatedCaller("registerReceiver");
16326        ArrayList<Intent> stickyIntents = null;
16327        ProcessRecord callerApp = null;
16328        int callingUid;
16329        int callingPid;
16330        synchronized(this) {
16331            if (caller != null) {
16332                callerApp = getRecordForAppLocked(caller);
16333                if (callerApp == null) {
16334                    throw new SecurityException(
16335                            "Unable to find app for caller " + caller
16336                            + " (pid=" + Binder.getCallingPid()
16337                            + ") when registering receiver " + receiver);
16338                }
16339                if (callerApp.info.uid != Process.SYSTEM_UID &&
16340                        !callerApp.pkgList.containsKey(callerPackage) &&
16341                        !"android".equals(callerPackage)) {
16342                    throw new SecurityException("Given caller package " + callerPackage
16343                            + " is not running in process " + callerApp);
16344                }
16345                callingUid = callerApp.info.uid;
16346                callingPid = callerApp.pid;
16347            } else {
16348                callerPackage = null;
16349                callingUid = Binder.getCallingUid();
16350                callingPid = Binder.getCallingPid();
16351            }
16352
16353            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16354                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16355
16356            Iterator<String> actions = filter.actionsIterator();
16357            if (actions == null) {
16358                ArrayList<String> noAction = new ArrayList<String>(1);
16359                noAction.add(null);
16360                actions = noAction.iterator();
16361            }
16362
16363            // Collect stickies of users
16364            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16365            while (actions.hasNext()) {
16366                String action = actions.next();
16367                for (int id : userIds) {
16368                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16369                    if (stickies != null) {
16370                        ArrayList<Intent> intents = stickies.get(action);
16371                        if (intents != null) {
16372                            if (stickyIntents == null) {
16373                                stickyIntents = new ArrayList<Intent>();
16374                            }
16375                            stickyIntents.addAll(intents);
16376                        }
16377                    }
16378                }
16379            }
16380        }
16381
16382        ArrayList<Intent> allSticky = null;
16383        if (stickyIntents != null) {
16384            final ContentResolver resolver = mContext.getContentResolver();
16385            // Look for any matching sticky broadcasts...
16386            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16387                Intent intent = stickyIntents.get(i);
16388                // If intent has scheme "content", it will need to acccess
16389                // provider that needs to lock mProviderMap in ActivityThread
16390                // and also it may need to wait application response, so we
16391                // cannot lock ActivityManagerService here.
16392                if (filter.match(resolver, intent, true, TAG) >= 0) {
16393                    if (allSticky == null) {
16394                        allSticky = new ArrayList<Intent>();
16395                    }
16396                    allSticky.add(intent);
16397                }
16398            }
16399        }
16400
16401        // The first sticky in the list is returned directly back to the client.
16402        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16403        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16404        if (receiver == null) {
16405            return sticky;
16406        }
16407
16408        synchronized (this) {
16409            if (callerApp != null && (callerApp.thread == null
16410                    || callerApp.thread.asBinder() != caller.asBinder())) {
16411                // Original caller already died
16412                return null;
16413            }
16414            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16415            if (rl == null) {
16416                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16417                        userId, receiver);
16418                if (rl.app != null) {
16419                    rl.app.receivers.add(rl);
16420                } else {
16421                    try {
16422                        receiver.asBinder().linkToDeath(rl, 0);
16423                    } catch (RemoteException e) {
16424                        return sticky;
16425                    }
16426                    rl.linkedToDeath = true;
16427                }
16428                mRegisteredReceivers.put(receiver.asBinder(), rl);
16429            } else if (rl.uid != callingUid) {
16430                throw new IllegalArgumentException(
16431                        "Receiver requested to register for uid " + callingUid
16432                        + " was previously registered for uid " + rl.uid);
16433            } else if (rl.pid != callingPid) {
16434                throw new IllegalArgumentException(
16435                        "Receiver requested to register for pid " + callingPid
16436                        + " was previously registered for pid " + rl.pid);
16437            } else if (rl.userId != userId) {
16438                throw new IllegalArgumentException(
16439                        "Receiver requested to register for user " + userId
16440                        + " was previously registered for user " + rl.userId);
16441            }
16442            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16443                    permission, callingUid, userId);
16444            rl.add(bf);
16445            if (!bf.debugCheck()) {
16446                Slog.w(TAG, "==> For Dynamic broadcast");
16447            }
16448            mReceiverResolver.addFilter(bf);
16449
16450            // Enqueue broadcasts for all existing stickies that match
16451            // this filter.
16452            if (allSticky != null) {
16453                ArrayList receivers = new ArrayList();
16454                receivers.add(bf);
16455
16456                final int stickyCount = allSticky.size();
16457                for (int i = 0; i < stickyCount; i++) {
16458                    Intent intent = allSticky.get(i);
16459                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16460                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16461                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16462                            null, 0, null, null, false, true, true, -1);
16463                    queue.enqueueParallelBroadcastLocked(r);
16464                    queue.scheduleBroadcastsLocked();
16465                }
16466            }
16467
16468            return sticky;
16469        }
16470    }
16471
16472    public void unregisterReceiver(IIntentReceiver receiver) {
16473        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16474
16475        final long origId = Binder.clearCallingIdentity();
16476        try {
16477            boolean doTrim = false;
16478
16479            synchronized(this) {
16480                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16481                if (rl != null) {
16482                    final BroadcastRecord r = rl.curBroadcast;
16483                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16484                        final boolean doNext = r.queue.finishReceiverLocked(
16485                                r, r.resultCode, r.resultData, r.resultExtras,
16486                                r.resultAbort, false);
16487                        if (doNext) {
16488                            doTrim = true;
16489                            r.queue.processNextBroadcast(false);
16490                        }
16491                    }
16492
16493                    if (rl.app != null) {
16494                        rl.app.receivers.remove(rl);
16495                    }
16496                    removeReceiverLocked(rl);
16497                    if (rl.linkedToDeath) {
16498                        rl.linkedToDeath = false;
16499                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16500                    }
16501                }
16502            }
16503
16504            // If we actually concluded any broadcasts, we might now be able
16505            // to trim the recipients' apps from our working set
16506            if (doTrim) {
16507                trimApplications();
16508                return;
16509            }
16510
16511        } finally {
16512            Binder.restoreCallingIdentity(origId);
16513        }
16514    }
16515
16516    void removeReceiverLocked(ReceiverList rl) {
16517        mRegisteredReceivers.remove(rl.receiver.asBinder());
16518        for (int i = rl.size() - 1; i >= 0; i--) {
16519            mReceiverResolver.removeFilter(rl.get(i));
16520        }
16521    }
16522
16523    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16524        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16525            ProcessRecord r = mLruProcesses.get(i);
16526            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16527                try {
16528                    r.thread.dispatchPackageBroadcast(cmd, packages);
16529                } catch (RemoteException ex) {
16530                }
16531            }
16532        }
16533    }
16534
16535    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16536            int callingUid, int[] users) {
16537        List<ResolveInfo> receivers = null;
16538        try {
16539            HashSet<ComponentName> singleUserReceivers = null;
16540            boolean scannedFirstReceivers = false;
16541            for (int user : users) {
16542                // Skip users that have Shell restrictions
16543                if (callingUid == Process.SHELL_UID
16544                        && mUserController.hasUserRestriction(
16545                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16546                    continue;
16547                }
16548                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16549                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16550                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16551                    // If this is not the system user, we need to check for
16552                    // any receivers that should be filtered out.
16553                    for (int i=0; i<newReceivers.size(); i++) {
16554                        ResolveInfo ri = newReceivers.get(i);
16555                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16556                            newReceivers.remove(i);
16557                            i--;
16558                        }
16559                    }
16560                }
16561                if (newReceivers != null && newReceivers.size() == 0) {
16562                    newReceivers = null;
16563                }
16564                if (receivers == null) {
16565                    receivers = newReceivers;
16566                } else if (newReceivers != null) {
16567                    // We need to concatenate the additional receivers
16568                    // found with what we have do far.  This would be easy,
16569                    // but we also need to de-dup any receivers that are
16570                    // singleUser.
16571                    if (!scannedFirstReceivers) {
16572                        // Collect any single user receivers we had already retrieved.
16573                        scannedFirstReceivers = true;
16574                        for (int i=0; i<receivers.size(); i++) {
16575                            ResolveInfo ri = receivers.get(i);
16576                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16577                                ComponentName cn = new ComponentName(
16578                                        ri.activityInfo.packageName, ri.activityInfo.name);
16579                                if (singleUserReceivers == null) {
16580                                    singleUserReceivers = new HashSet<ComponentName>();
16581                                }
16582                                singleUserReceivers.add(cn);
16583                            }
16584                        }
16585                    }
16586                    // Add the new results to the existing results, tracking
16587                    // and de-dupping single user receivers.
16588                    for (int i=0; i<newReceivers.size(); i++) {
16589                        ResolveInfo ri = newReceivers.get(i);
16590                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16591                            ComponentName cn = new ComponentName(
16592                                    ri.activityInfo.packageName, ri.activityInfo.name);
16593                            if (singleUserReceivers == null) {
16594                                singleUserReceivers = new HashSet<ComponentName>();
16595                            }
16596                            if (!singleUserReceivers.contains(cn)) {
16597                                singleUserReceivers.add(cn);
16598                                receivers.add(ri);
16599                            }
16600                        } else {
16601                            receivers.add(ri);
16602                        }
16603                    }
16604                }
16605            }
16606        } catch (RemoteException ex) {
16607            // pm is in same process, this will never happen.
16608        }
16609        return receivers;
16610    }
16611
16612    final int broadcastIntentLocked(ProcessRecord callerApp,
16613            String callerPackage, Intent intent, String resolvedType,
16614            IIntentReceiver resultTo, int resultCode, String resultData,
16615            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16616            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16617        intent = new Intent(intent);
16618
16619        // By default broadcasts do not go to stopped apps.
16620        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16621
16622        // If we have not finished booting, don't allow this to launch new processes.
16623        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16624            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16625        }
16626
16627        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16628                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16629                + " ordered=" + ordered + " userid=" + userId);
16630        if ((resultTo != null) && !ordered) {
16631            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16632        }
16633
16634        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16635                ALLOW_NON_FULL, "broadcast", callerPackage);
16636
16637        // Make sure that the user who is receiving this broadcast is running.
16638        // If not, we will just skip it. Make an exception for shutdown broadcasts
16639        // and upgrade steps.
16640
16641        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, false)) {
16642            if ((callingUid != Process.SYSTEM_UID
16643                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16644                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16645                Slog.w(TAG, "Skipping broadcast of " + intent
16646                        + ": user " + userId + " is stopped");
16647                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16648            }
16649        }
16650
16651        BroadcastOptions brOptions = null;
16652        if (bOptions != null) {
16653            brOptions = new BroadcastOptions(bOptions);
16654            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16655                // See if the caller is allowed to do this.  Note we are checking against
16656                // the actual real caller (not whoever provided the operation as say a
16657                // PendingIntent), because that who is actually supplied the arguments.
16658                if (checkComponentPermission(
16659                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16660                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16661                        != PackageManager.PERMISSION_GRANTED) {
16662                    String msg = "Permission Denial: " + intent.getAction()
16663                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16664                            + ", uid=" + callingUid + ")"
16665                            + " requires "
16666                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16667                    Slog.w(TAG, msg);
16668                    throw new SecurityException(msg);
16669                }
16670            }
16671        }
16672
16673        /*
16674         * Prevent non-system code (defined here to be non-persistent
16675         * processes) from sending protected broadcasts.
16676         */
16677        int callingAppId = UserHandle.getAppId(callingUid);
16678        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16679            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16680            || callingAppId == Process.NFC_UID || callingUid == 0) {
16681            // Always okay.
16682        } else if (callerApp == null || !callerApp.persistent) {
16683            try {
16684                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16685                        intent.getAction())) {
16686                    String msg = "Permission Denial: not allowed to send broadcast "
16687                            + intent.getAction() + " from pid="
16688                            + callingPid + ", uid=" + callingUid;
16689                    Slog.w(TAG, msg);
16690                    throw new SecurityException(msg);
16691                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16692                    // Special case for compatibility: we don't want apps to send this,
16693                    // but historically it has not been protected and apps may be using it
16694                    // to poke their own app widget.  So, instead of making it protected,
16695                    // just limit it to the caller.
16696                    if (callerApp == null) {
16697                        String msg = "Permission Denial: not allowed to send broadcast "
16698                                + intent.getAction() + " from unknown caller.";
16699                        Slog.w(TAG, msg);
16700                        throw new SecurityException(msg);
16701                    } else if (intent.getComponent() != null) {
16702                        // They are good enough to send to an explicit component...  verify
16703                        // it is being sent to the calling app.
16704                        if (!intent.getComponent().getPackageName().equals(
16705                                callerApp.info.packageName)) {
16706                            String msg = "Permission Denial: not allowed to send broadcast "
16707                                    + intent.getAction() + " to "
16708                                    + intent.getComponent().getPackageName() + " from "
16709                                    + callerApp.info.packageName;
16710                            Slog.w(TAG, msg);
16711                            throw new SecurityException(msg);
16712                        }
16713                    } else {
16714                        // Limit broadcast to their own package.
16715                        intent.setPackage(callerApp.info.packageName);
16716                    }
16717                }
16718            } catch (RemoteException e) {
16719                Slog.w(TAG, "Remote exception", e);
16720                return ActivityManager.BROADCAST_SUCCESS;
16721            }
16722        }
16723
16724        final String action = intent.getAction();
16725        if (action != null) {
16726            switch (action) {
16727                case Intent.ACTION_UID_REMOVED:
16728                case Intent.ACTION_PACKAGE_REMOVED:
16729                case Intent.ACTION_PACKAGE_CHANGED:
16730                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16731                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16732                    // Handle special intents: if this broadcast is from the package
16733                    // manager about a package being removed, we need to remove all of
16734                    // its activities from the history stack.
16735                    if (checkComponentPermission(
16736                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16737                            callingPid, callingUid, -1, true)
16738                            != PackageManager.PERMISSION_GRANTED) {
16739                        String msg = "Permission Denial: " + intent.getAction()
16740                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16741                                + ", uid=" + callingUid + ")"
16742                                + " requires "
16743                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16744                        Slog.w(TAG, msg);
16745                        throw new SecurityException(msg);
16746                    }
16747                    switch (action) {
16748                        case Intent.ACTION_UID_REMOVED:
16749                            final Bundle intentExtras = intent.getExtras();
16750                            final int uid = intentExtras != null
16751                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16752                            if (uid >= 0) {
16753                                mBatteryStatsService.removeUid(uid);
16754                                mAppOpsService.uidRemoved(uid);
16755                            }
16756                            break;
16757                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16758                            // If resources are unavailable just force stop all those packages
16759                            // and flush the attribute cache as well.
16760                            String list[] =
16761                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16762                            if (list != null && list.length > 0) {
16763                                for (int i = 0; i < list.length; i++) {
16764                                    forceStopPackageLocked(list[i], -1, false, true, true,
16765                                            false, false, userId, "storage unmount");
16766                                }
16767                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16768                                sendPackageBroadcastLocked(
16769                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16770                                        userId);
16771                            }
16772                            break;
16773                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16774                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16775                            break;
16776                        case Intent.ACTION_PACKAGE_REMOVED:
16777                        case Intent.ACTION_PACKAGE_CHANGED:
16778                            Uri data = intent.getData();
16779                            String ssp;
16780                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16781                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16782                                boolean fullUninstall = removed &&
16783                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16784                                final boolean killProcess =
16785                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16786                                if (killProcess) {
16787                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16788                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16789                                            false, true, true, false, fullUninstall, userId,
16790                                            removed ? "pkg removed" : "pkg changed");
16791                                }
16792                                if (removed) {
16793                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16794                                            new String[] {ssp}, userId);
16795                                    if (fullUninstall) {
16796                                        mAppOpsService.packageRemoved(
16797                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16798
16799                                        // Remove all permissions granted from/to this package
16800                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16801
16802                                        removeTasksByPackageNameLocked(ssp, userId);
16803                                        mBatteryStatsService.notePackageUninstalled(ssp);
16804                                    }
16805                                } else {
16806                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16807                                            intent.getStringArrayExtra(
16808                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16809                                }
16810                            }
16811                            break;
16812                    }
16813                    break;
16814                case Intent.ACTION_PACKAGE_ADDED:
16815                    // Special case for adding a package: by default turn on compatibility mode.
16816                    Uri data = intent.getData();
16817                    String ssp;
16818                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16819                        final boolean replacing =
16820                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16821                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16822
16823                        try {
16824                            ApplicationInfo ai = AppGlobals.getPackageManager().
16825                                    getApplicationInfo(ssp, 0, 0);
16826                            mBatteryStatsService.notePackageInstalled(ssp,
16827                                    ai != null ? ai.versionCode : 0);
16828                        } catch (RemoteException e) {
16829                        }
16830                    }
16831                    break;
16832                case Intent.ACTION_TIMEZONE_CHANGED:
16833                    // If this is the time zone changed action, queue up a message that will reset
16834                    // the timezone of all currently running processes. This message will get
16835                    // queued up before the broadcast happens.
16836                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16837                    break;
16838                case Intent.ACTION_TIME_CHANGED:
16839                    // If the user set the time, let all running processes know.
16840                    final int is24Hour =
16841                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16842                                    : 0;
16843                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16844                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16845                    synchronized (stats) {
16846                        stats.noteCurrentTimeChangedLocked();
16847                    }
16848                    break;
16849                case Intent.ACTION_CLEAR_DNS_CACHE:
16850                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16851                    break;
16852                case Proxy.PROXY_CHANGE_ACTION:
16853                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16854                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16855                    break;
16856            }
16857        }
16858
16859        // Add to the sticky list if requested.
16860        if (sticky) {
16861            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16862                    callingPid, callingUid)
16863                    != PackageManager.PERMISSION_GRANTED) {
16864                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16865                        + callingPid + ", uid=" + callingUid
16866                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16867                Slog.w(TAG, msg);
16868                throw new SecurityException(msg);
16869            }
16870            if (requiredPermissions != null && requiredPermissions.length > 0) {
16871                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16872                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16873                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16874            }
16875            if (intent.getComponent() != null) {
16876                throw new SecurityException(
16877                        "Sticky broadcasts can't target a specific component");
16878            }
16879            // We use userId directly here, since the "all" target is maintained
16880            // as a separate set of sticky broadcasts.
16881            if (userId != UserHandle.USER_ALL) {
16882                // But first, if this is not a broadcast to all users, then
16883                // make sure it doesn't conflict with an existing broadcast to
16884                // all users.
16885                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16886                        UserHandle.USER_ALL);
16887                if (stickies != null) {
16888                    ArrayList<Intent> list = stickies.get(intent.getAction());
16889                    if (list != null) {
16890                        int N = list.size();
16891                        int i;
16892                        for (i=0; i<N; i++) {
16893                            if (intent.filterEquals(list.get(i))) {
16894                                throw new IllegalArgumentException(
16895                                        "Sticky broadcast " + intent + " for user "
16896                                        + userId + " conflicts with existing global broadcast");
16897                            }
16898                        }
16899                    }
16900                }
16901            }
16902            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16903            if (stickies == null) {
16904                stickies = new ArrayMap<>();
16905                mStickyBroadcasts.put(userId, stickies);
16906            }
16907            ArrayList<Intent> list = stickies.get(intent.getAction());
16908            if (list == null) {
16909                list = new ArrayList<>();
16910                stickies.put(intent.getAction(), list);
16911            }
16912            final int stickiesCount = list.size();
16913            int i;
16914            for (i = 0; i < stickiesCount; i++) {
16915                if (intent.filterEquals(list.get(i))) {
16916                    // This sticky already exists, replace it.
16917                    list.set(i, new Intent(intent));
16918                    break;
16919                }
16920            }
16921            if (i >= stickiesCount) {
16922                list.add(new Intent(intent));
16923            }
16924        }
16925
16926        int[] users;
16927        if (userId == UserHandle.USER_ALL) {
16928            // Caller wants broadcast to go to all started users.
16929            users = mUserController.getStartedUserArrayLocked();
16930        } else {
16931            // Caller wants broadcast to go to one specific user.
16932            users = new int[] {userId};
16933        }
16934
16935        // Figure out who all will receive this broadcast.
16936        List receivers = null;
16937        List<BroadcastFilter> registeredReceivers = null;
16938        // Need to resolve the intent to interested receivers...
16939        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16940                 == 0) {
16941            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16942        }
16943        if (intent.getComponent() == null) {
16944            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16945                // Query one target user at a time, excluding shell-restricted users
16946                for (int i = 0; i < users.length; i++) {
16947                    if (mUserController.hasUserRestriction(
16948                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16949                        continue;
16950                    }
16951                    List<BroadcastFilter> registeredReceiversForUser =
16952                            mReceiverResolver.queryIntent(intent,
16953                                    resolvedType, false, users[i]);
16954                    if (registeredReceivers == null) {
16955                        registeredReceivers = registeredReceiversForUser;
16956                    } else if (registeredReceiversForUser != null) {
16957                        registeredReceivers.addAll(registeredReceiversForUser);
16958                    }
16959                }
16960            } else {
16961                registeredReceivers = mReceiverResolver.queryIntent(intent,
16962                        resolvedType, false, userId);
16963            }
16964        }
16965
16966        final boolean replacePending =
16967                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16968
16969        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16970                + " replacePending=" + replacePending);
16971
16972        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16973        if (!ordered && NR > 0) {
16974            // If we are not serializing this broadcast, then send the
16975            // registered receivers separately so they don't wait for the
16976            // components to be launched.
16977            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16978            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16979                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16980                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16981                    resultExtras, ordered, sticky, false, userId);
16982            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16983            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16984            if (!replaced) {
16985                queue.enqueueParallelBroadcastLocked(r);
16986                queue.scheduleBroadcastsLocked();
16987            }
16988            registeredReceivers = null;
16989            NR = 0;
16990        }
16991
16992        // Merge into one list.
16993        int ir = 0;
16994        if (receivers != null) {
16995            // A special case for PACKAGE_ADDED: do not allow the package
16996            // being added to see this broadcast.  This prevents them from
16997            // using this as a back door to get run as soon as they are
16998            // installed.  Maybe in the future we want to have a special install
16999            // broadcast or such for apps, but we'd like to deliberately make
17000            // this decision.
17001            String skipPackages[] = null;
17002            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17003                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17004                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17005                Uri data = intent.getData();
17006                if (data != null) {
17007                    String pkgName = data.getSchemeSpecificPart();
17008                    if (pkgName != null) {
17009                        skipPackages = new String[] { pkgName };
17010                    }
17011                }
17012            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17013                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17014            }
17015            if (skipPackages != null && (skipPackages.length > 0)) {
17016                for (String skipPackage : skipPackages) {
17017                    if (skipPackage != null) {
17018                        int NT = receivers.size();
17019                        for (int it=0; it<NT; it++) {
17020                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17021                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17022                                receivers.remove(it);
17023                                it--;
17024                                NT--;
17025                            }
17026                        }
17027                    }
17028                }
17029            }
17030
17031            int NT = receivers != null ? receivers.size() : 0;
17032            int it = 0;
17033            ResolveInfo curt = null;
17034            BroadcastFilter curr = null;
17035            while (it < NT && ir < NR) {
17036                if (curt == null) {
17037                    curt = (ResolveInfo)receivers.get(it);
17038                }
17039                if (curr == null) {
17040                    curr = registeredReceivers.get(ir);
17041                }
17042                if (curr.getPriority() >= curt.priority) {
17043                    // Insert this broadcast record into the final list.
17044                    receivers.add(it, curr);
17045                    ir++;
17046                    curr = null;
17047                    it++;
17048                    NT++;
17049                } else {
17050                    // Skip to the next ResolveInfo in the final list.
17051                    it++;
17052                    curt = null;
17053                }
17054            }
17055        }
17056        while (ir < NR) {
17057            if (receivers == null) {
17058                receivers = new ArrayList();
17059            }
17060            receivers.add(registeredReceivers.get(ir));
17061            ir++;
17062        }
17063
17064        if ((receivers != null && receivers.size() > 0)
17065                || resultTo != null) {
17066            BroadcastQueue queue = broadcastQueueForIntent(intent);
17067            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17068                    callerPackage, callingPid, callingUid, resolvedType,
17069                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17070                    resultData, resultExtras, ordered, sticky, false, userId);
17071
17072            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17073                    + ": prev had " + queue.mOrderedBroadcasts.size());
17074            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17075                    "Enqueueing broadcast " + r.intent.getAction());
17076
17077            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17078            if (!replaced) {
17079                queue.enqueueOrderedBroadcastLocked(r);
17080                queue.scheduleBroadcastsLocked();
17081            }
17082        }
17083
17084        return ActivityManager.BROADCAST_SUCCESS;
17085    }
17086
17087    final Intent verifyBroadcastLocked(Intent intent) {
17088        // Refuse possible leaked file descriptors
17089        if (intent != null && intent.hasFileDescriptors() == true) {
17090            throw new IllegalArgumentException("File descriptors passed in Intent");
17091        }
17092
17093        int flags = intent.getFlags();
17094
17095        if (!mProcessesReady) {
17096            // if the caller really truly claims to know what they're doing, go
17097            // ahead and allow the broadcast without launching any receivers
17098            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17099                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17100            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17101                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17102                        + " before boot completion");
17103                throw new IllegalStateException("Cannot broadcast before boot completed");
17104            }
17105        }
17106
17107        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17108            throw new IllegalArgumentException(
17109                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17110        }
17111
17112        return intent;
17113    }
17114
17115    public final int broadcastIntent(IApplicationThread caller,
17116            Intent intent, String resolvedType, IIntentReceiver resultTo,
17117            int resultCode, String resultData, Bundle resultExtras,
17118            String[] requiredPermissions, int appOp, Bundle bOptions,
17119            boolean serialized, boolean sticky, int userId) {
17120        enforceNotIsolatedCaller("broadcastIntent");
17121        synchronized(this) {
17122            intent = verifyBroadcastLocked(intent);
17123
17124            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17125            final int callingPid = Binder.getCallingPid();
17126            final int callingUid = Binder.getCallingUid();
17127            final long origId = Binder.clearCallingIdentity();
17128            int res = broadcastIntentLocked(callerApp,
17129                    callerApp != null ? callerApp.info.packageName : null,
17130                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17131                    requiredPermissions, appOp, null, serialized, sticky,
17132                    callingPid, callingUid, userId);
17133            Binder.restoreCallingIdentity(origId);
17134            return res;
17135        }
17136    }
17137
17138
17139    int broadcastIntentInPackage(String packageName, int uid,
17140            Intent intent, String resolvedType, IIntentReceiver resultTo,
17141            int resultCode, String resultData, Bundle resultExtras,
17142            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17143            int userId) {
17144        synchronized(this) {
17145            intent = verifyBroadcastLocked(intent);
17146
17147            final long origId = Binder.clearCallingIdentity();
17148            String[] requiredPermissions = requiredPermission == null ? null
17149                    : new String[] {requiredPermission};
17150            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17151                    resultTo, resultCode, resultData, resultExtras,
17152                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17153                    sticky, -1, uid, userId);
17154            Binder.restoreCallingIdentity(origId);
17155            return res;
17156        }
17157    }
17158
17159    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17160        // Refuse possible leaked file descriptors
17161        if (intent != null && intent.hasFileDescriptors() == true) {
17162            throw new IllegalArgumentException("File descriptors passed in Intent");
17163        }
17164
17165        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17166                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17167
17168        synchronized(this) {
17169            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17170                    != PackageManager.PERMISSION_GRANTED) {
17171                String msg = "Permission Denial: unbroadcastIntent() from pid="
17172                        + Binder.getCallingPid()
17173                        + ", uid=" + Binder.getCallingUid()
17174                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17175                Slog.w(TAG, msg);
17176                throw new SecurityException(msg);
17177            }
17178            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17179            if (stickies != null) {
17180                ArrayList<Intent> list = stickies.get(intent.getAction());
17181                if (list != null) {
17182                    int N = list.size();
17183                    int i;
17184                    for (i=0; i<N; i++) {
17185                        if (intent.filterEquals(list.get(i))) {
17186                            list.remove(i);
17187                            break;
17188                        }
17189                    }
17190                    if (list.size() <= 0) {
17191                        stickies.remove(intent.getAction());
17192                    }
17193                }
17194                if (stickies.size() <= 0) {
17195                    mStickyBroadcasts.remove(userId);
17196                }
17197            }
17198        }
17199    }
17200
17201    void backgroundServicesFinishedLocked(int userId) {
17202        for (BroadcastQueue queue : mBroadcastQueues) {
17203            queue.backgroundServicesFinishedLocked(userId);
17204        }
17205    }
17206
17207    public void finishReceiver(IBinder who, int resultCode, String resultData,
17208            Bundle resultExtras, boolean resultAbort, int flags) {
17209        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17210
17211        // Refuse possible leaked file descriptors
17212        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17213            throw new IllegalArgumentException("File descriptors passed in Bundle");
17214        }
17215
17216        final long origId = Binder.clearCallingIdentity();
17217        try {
17218            boolean doNext = false;
17219            BroadcastRecord r;
17220
17221            synchronized(this) {
17222                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17223                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17224                r = queue.getMatchingOrderedReceiver(who);
17225                if (r != null) {
17226                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17227                        resultData, resultExtras, resultAbort, true);
17228                }
17229            }
17230
17231            if (doNext) {
17232                r.queue.processNextBroadcast(false);
17233            }
17234            trimApplications();
17235        } finally {
17236            Binder.restoreCallingIdentity(origId);
17237        }
17238    }
17239
17240    // =========================================================
17241    // INSTRUMENTATION
17242    // =========================================================
17243
17244    public boolean startInstrumentation(ComponentName className,
17245            String profileFile, int flags, Bundle arguments,
17246            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17247            int userId, String abiOverride) {
17248        enforceNotIsolatedCaller("startInstrumentation");
17249        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17250                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17251        // Refuse possible leaked file descriptors
17252        if (arguments != null && arguments.hasFileDescriptors()) {
17253            throw new IllegalArgumentException("File descriptors passed in Bundle");
17254        }
17255
17256        synchronized(this) {
17257            InstrumentationInfo ii = null;
17258            ApplicationInfo ai = null;
17259            try {
17260                ii = mContext.getPackageManager().getInstrumentationInfo(
17261                    className, STOCK_PM_FLAGS);
17262                ai = AppGlobals.getPackageManager().getApplicationInfo(
17263                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17264            } catch (PackageManager.NameNotFoundException e) {
17265            } catch (RemoteException e) {
17266            }
17267            if (ii == null) {
17268                reportStartInstrumentationFailure(watcher, className,
17269                        "Unable to find instrumentation info for: " + className);
17270                return false;
17271            }
17272            if (ai == null) {
17273                reportStartInstrumentationFailure(watcher, className,
17274                        "Unable to find instrumentation target package: " + ii.targetPackage);
17275                return false;
17276            }
17277
17278            int match = mContext.getPackageManager().checkSignatures(
17279                    ii.targetPackage, ii.packageName);
17280            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17281                String msg = "Permission Denial: starting instrumentation "
17282                        + className + " from pid="
17283                        + Binder.getCallingPid()
17284                        + ", uid=" + Binder.getCallingPid()
17285                        + " not allowed because package " + ii.packageName
17286                        + " does not have a signature matching the target "
17287                        + ii.targetPackage;
17288                reportStartInstrumentationFailure(watcher, className, msg);
17289                throw new SecurityException(msg);
17290            }
17291
17292            final long origId = Binder.clearCallingIdentity();
17293            // Instrumentation can kill and relaunch even persistent processes
17294            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17295                    "start instr");
17296            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17297            app.instrumentationClass = className;
17298            app.instrumentationInfo = ai;
17299            app.instrumentationProfileFile = profileFile;
17300            app.instrumentationArguments = arguments;
17301            app.instrumentationWatcher = watcher;
17302            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17303            app.instrumentationResultClass = className;
17304            Binder.restoreCallingIdentity(origId);
17305        }
17306
17307        return true;
17308    }
17309
17310    /**
17311     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17312     * error to the logs, but if somebody is watching, send the report there too.  This enables
17313     * the "am" command to report errors with more information.
17314     *
17315     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17316     * @param cn The component name of the instrumentation.
17317     * @param report The error report.
17318     */
17319    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17320            ComponentName cn, String report) {
17321        Slog.w(TAG, report);
17322        try {
17323            if (watcher != null) {
17324                Bundle results = new Bundle();
17325                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17326                results.putString("Error", report);
17327                watcher.instrumentationStatus(cn, -1, results);
17328            }
17329        } catch (RemoteException e) {
17330            Slog.w(TAG, e);
17331        }
17332    }
17333
17334    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17335        if (app.instrumentationWatcher != null) {
17336            try {
17337                // NOTE:  IInstrumentationWatcher *must* be oneway here
17338                app.instrumentationWatcher.instrumentationFinished(
17339                    app.instrumentationClass,
17340                    resultCode,
17341                    results);
17342            } catch (RemoteException e) {
17343            }
17344        }
17345
17346        // Can't call out of the system process with a lock held, so post a message.
17347        if (app.instrumentationUiAutomationConnection != null) {
17348            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17349                    app.instrumentationUiAutomationConnection).sendToTarget();
17350        }
17351
17352        app.instrumentationWatcher = null;
17353        app.instrumentationUiAutomationConnection = null;
17354        app.instrumentationClass = null;
17355        app.instrumentationInfo = null;
17356        app.instrumentationProfileFile = null;
17357        app.instrumentationArguments = null;
17358
17359        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17360                "finished inst");
17361    }
17362
17363    public void finishInstrumentation(IApplicationThread target,
17364            int resultCode, Bundle results) {
17365        int userId = UserHandle.getCallingUserId();
17366        // Refuse possible leaked file descriptors
17367        if (results != null && results.hasFileDescriptors()) {
17368            throw new IllegalArgumentException("File descriptors passed in Intent");
17369        }
17370
17371        synchronized(this) {
17372            ProcessRecord app = getRecordForAppLocked(target);
17373            if (app == null) {
17374                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17375                return;
17376            }
17377            final long origId = Binder.clearCallingIdentity();
17378            finishInstrumentationLocked(app, resultCode, results);
17379            Binder.restoreCallingIdentity(origId);
17380        }
17381    }
17382
17383    // =========================================================
17384    // CONFIGURATION
17385    // =========================================================
17386
17387    public ConfigurationInfo getDeviceConfigurationInfo() {
17388        ConfigurationInfo config = new ConfigurationInfo();
17389        synchronized (this) {
17390            config.reqTouchScreen = mConfiguration.touchscreen;
17391            config.reqKeyboardType = mConfiguration.keyboard;
17392            config.reqNavigation = mConfiguration.navigation;
17393            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17394                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17395                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17396            }
17397            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17398                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17399                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17400            }
17401            config.reqGlEsVersion = GL_ES_VERSION;
17402        }
17403        return config;
17404    }
17405
17406    ActivityStack getFocusedStack() {
17407        return mStackSupervisor.getFocusedStack();
17408    }
17409
17410    @Override
17411    public int getFocusedStackId() throws RemoteException {
17412        ActivityStack focusedStack = getFocusedStack();
17413        if (focusedStack != null) {
17414            return focusedStack.getStackId();
17415        }
17416        return -1;
17417    }
17418
17419    public Configuration getConfiguration() {
17420        Configuration ci;
17421        synchronized(this) {
17422            ci = new Configuration(mConfiguration);
17423            ci.userSetLocale = false;
17424        }
17425        return ci;
17426    }
17427
17428    @Override
17429    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17430        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17431                "suppressResizeConfigChanges()");
17432        synchronized (this) {
17433            mSuppressResizeConfigChanges = suppress;
17434        }
17435    }
17436
17437    @Override
17438    public void removeStack(int stackId) {
17439        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17440                "detahStack()");
17441        if (stackId == HOME_STACK_ID) {
17442            throw new IllegalArgumentException("Removing home stack is not allowed.");
17443        }
17444        synchronized (this) {
17445            ActivityStack stack = mStackSupervisor.getStack(stackId);
17446            if (stack != null) {
17447                ArrayList<TaskRecord> tasks = stack.getAllTasks();
17448                for (int i = tasks.size() - 1; i >= 0; i--) {
17449                    removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
17450                            !REMOVE_FROM_RECENTS);
17451                }
17452            }
17453        }
17454    }
17455
17456    @Override
17457    public void updatePersistentConfiguration(Configuration values) {
17458        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17459                "updateConfiguration()");
17460        enforceWriteSettingsPermission("updateConfiguration()");
17461        if (values == null) {
17462            throw new NullPointerException("Configuration must not be null");
17463        }
17464
17465        int userId = UserHandle.getCallingUserId();
17466
17467        synchronized(this) {
17468            final long origId = Binder.clearCallingIdentity();
17469            updateConfigurationLocked(values, null, false, true, userId);
17470            Binder.restoreCallingIdentity(origId);
17471        }
17472    }
17473
17474    private void enforceWriteSettingsPermission(String func) {
17475        int uid = Binder.getCallingUid();
17476        if (uid == Process.ROOT_UID) {
17477            return;
17478        }
17479
17480        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17481                Settings.getPackageNameForUid(mContext, uid), false)) {
17482            return;
17483        }
17484
17485        String msg = "Permission Denial: " + func + " from pid="
17486                + Binder.getCallingPid()
17487                + ", uid=" + uid
17488                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17489        Slog.w(TAG, msg);
17490        throw new SecurityException(msg);
17491    }
17492
17493    public void updateConfiguration(Configuration values) {
17494        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17495                "updateConfiguration()");
17496
17497        synchronized(this) {
17498            if (values == null && mWindowManager != null) {
17499                // sentinel: fetch the current configuration from the window manager
17500                values = mWindowManager.computeNewConfiguration();
17501            }
17502
17503            if (mWindowManager != null) {
17504                mProcessList.applyDisplaySize(mWindowManager);
17505            }
17506
17507            final long origId = Binder.clearCallingIdentity();
17508            if (values != null) {
17509                Settings.System.clearConfiguration(values);
17510            }
17511            updateConfigurationLocked(values, null, false);
17512            Binder.restoreCallingIdentity(origId);
17513        }
17514    }
17515
17516    void updateUserConfigurationLocked() {
17517        Configuration configuration = new Configuration(mConfiguration);
17518        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17519                mUserController.getCurrentUserIdLocked());
17520        updateConfigurationLocked(configuration, null, false);
17521    }
17522
17523    boolean updateConfigurationLocked(Configuration values,
17524            ActivityRecord starting, boolean initLocale) {
17525        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17526        return updateConfigurationLocked(values, starting, initLocale, false,
17527                UserHandle.USER_NULL);
17528    }
17529
17530    /**
17531     * Do either or both things: (1) change the current configuration, and (2)
17532     * make sure the given activity is running with the (now) current
17533     * configuration.  Returns true if the activity has been left running, or
17534     * false if <var>starting</var> is being destroyed to match the new
17535     * configuration.
17536     *
17537     * @param userId is only used when persistent parameter is set to true to persist configuration
17538     *               for that particular user
17539     */
17540    boolean updateConfigurationLocked(Configuration values,
17541            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17542        int changes = 0;
17543
17544        if (values != null) {
17545            Configuration newConfig = new Configuration(mConfiguration);
17546            changes = newConfig.updateFrom(values);
17547            if (changes != 0) {
17548                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17549                        "Updating configuration to: " + values);
17550
17551                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17552
17553                if (!initLocale && values.locale != null && values.userSetLocale) {
17554                    final String languageTag = values.locale.toLanguageTag();
17555                    SystemProperties.set("persist.sys.locale", languageTag);
17556                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17557                            values.locale));
17558                }
17559
17560                mConfigurationSeq++;
17561                if (mConfigurationSeq <= 0) {
17562                    mConfigurationSeq = 1;
17563                }
17564                newConfig.seq = mConfigurationSeq;
17565                mConfiguration = newConfig;
17566                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17567                mUsageStatsService.reportConfigurationChange(newConfig,
17568                        mUserController.getCurrentUserIdLocked());
17569                //mUsageStatsService.noteStartConfig(newConfig);
17570
17571                final Configuration configCopy = new Configuration(mConfiguration);
17572
17573                // TODO: If our config changes, should we auto dismiss any currently
17574                // showing dialogs?
17575                mShowDialogs = shouldShowDialogs(newConfig);
17576
17577                AttributeCache ac = AttributeCache.instance();
17578                if (ac != null) {
17579                    ac.updateConfiguration(configCopy);
17580                }
17581
17582                // Make sure all resources in our process are updated
17583                // right now, so that anyone who is going to retrieve
17584                // resource values after we return will be sure to get
17585                // the new ones.  This is especially important during
17586                // boot, where the first config change needs to guarantee
17587                // all resources have that config before following boot
17588                // code is executed.
17589                mSystemThread.applyConfigurationToResources(configCopy);
17590
17591                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17592                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17593                    msg.obj = new Configuration(configCopy);
17594                    msg.arg1 = userId;
17595                    mHandler.sendMessage(msg);
17596                }
17597
17598                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17599                    ProcessRecord app = mLruProcesses.get(i);
17600                    try {
17601                        if (app.thread != null) {
17602                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17603                                    + app.processName + " new config " + mConfiguration);
17604                            app.thread.scheduleConfigurationChanged(configCopy);
17605                        }
17606                    } catch (Exception e) {
17607                    }
17608                }
17609                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17610                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17611                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17612                        | Intent.FLAG_RECEIVER_FOREGROUND);
17613                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17614                        null, AppOpsManager.OP_NONE, null, false, false,
17615                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17616                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17617                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17618                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17619                    if (!mProcessesReady) {
17620                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17621                    }
17622                    broadcastIntentLocked(null, null, intent,
17623                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17624                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17625                }
17626            }
17627        }
17628
17629        boolean kept = true;
17630        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17631        // mainStack is null during startup.
17632        if (mainStack != null) {
17633            if (changes != 0 && starting == null) {
17634                // If the configuration changed, and the caller is not already
17635                // in the process of starting an activity, then find the top
17636                // activity to check if its configuration needs to change.
17637                starting = mainStack.topRunningActivityLocked();
17638            }
17639
17640            if (starting != null) {
17641                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17642                // And we need to make sure at this point that all other activities
17643                // are made visible with the correct configuration.
17644                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17645                        !PRESERVE_WINDOWS);
17646            }
17647        }
17648
17649        if (values != null && mWindowManager != null) {
17650            mWindowManager.setNewConfiguration(mConfiguration);
17651        }
17652
17653        return kept;
17654    }
17655
17656    /**
17657     * Decide based on the configuration whether we should shouw the ANR,
17658     * crash, etc dialogs.  The idea is that if there is no affordnace to
17659     * press the on-screen buttons, we shouldn't show the dialog.
17660     *
17661     * A thought: SystemUI might also want to get told about this, the Power
17662     * dialog / global actions also might want different behaviors.
17663     */
17664    private static final boolean shouldShowDialogs(Configuration config) {
17665        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17666                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17667                && config.navigation == Configuration.NAVIGATION_NONAV);
17668    }
17669
17670    @Override
17671    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17672        synchronized (this) {
17673            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17674            if (srec != null) {
17675                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17676            }
17677        }
17678        return false;
17679    }
17680
17681    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17682            Intent resultData) {
17683
17684        synchronized (this) {
17685            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17686            if (r != null) {
17687                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17688            }
17689            return false;
17690        }
17691    }
17692
17693    public int getLaunchedFromUid(IBinder activityToken) {
17694        ActivityRecord srec;
17695        synchronized (this) {
17696            srec = ActivityRecord.forTokenLocked(activityToken);
17697        }
17698        if (srec == null) {
17699            return -1;
17700        }
17701        return srec.launchedFromUid;
17702    }
17703
17704    public String getLaunchedFromPackage(IBinder activityToken) {
17705        ActivityRecord srec;
17706        synchronized (this) {
17707            srec = ActivityRecord.forTokenLocked(activityToken);
17708        }
17709        if (srec == null) {
17710            return null;
17711        }
17712        return srec.launchedFromPackage;
17713    }
17714
17715    // =========================================================
17716    // LIFETIME MANAGEMENT
17717    // =========================================================
17718
17719    // Returns which broadcast queue the app is the current [or imminent] receiver
17720    // on, or 'null' if the app is not an active broadcast recipient.
17721    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17722        BroadcastRecord r = app.curReceiver;
17723        if (r != null) {
17724            return r.queue;
17725        }
17726
17727        // It's not the current receiver, but it might be starting up to become one
17728        synchronized (this) {
17729            for (BroadcastQueue queue : mBroadcastQueues) {
17730                r = queue.mPendingBroadcast;
17731                if (r != null && r.curApp == app) {
17732                    // found it; report which queue it's in
17733                    return queue;
17734                }
17735            }
17736        }
17737
17738        return null;
17739    }
17740
17741    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17742            ComponentName targetComponent, String targetProcess) {
17743        if (!mTrackingAssociations) {
17744            return null;
17745        }
17746        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17747                = mAssociations.get(targetUid);
17748        if (components == null) {
17749            components = new ArrayMap<>();
17750            mAssociations.put(targetUid, components);
17751        }
17752        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17753        if (sourceUids == null) {
17754            sourceUids = new SparseArray<>();
17755            components.put(targetComponent, sourceUids);
17756        }
17757        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17758        if (sourceProcesses == null) {
17759            sourceProcesses = new ArrayMap<>();
17760            sourceUids.put(sourceUid, sourceProcesses);
17761        }
17762        Association ass = sourceProcesses.get(sourceProcess);
17763        if (ass == null) {
17764            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17765                    targetProcess);
17766            sourceProcesses.put(sourceProcess, ass);
17767        }
17768        ass.mCount++;
17769        ass.mNesting++;
17770        if (ass.mNesting == 1) {
17771            ass.mStartTime = SystemClock.uptimeMillis();
17772        }
17773        return ass;
17774    }
17775
17776    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17777            ComponentName targetComponent) {
17778        if (!mTrackingAssociations) {
17779            return;
17780        }
17781        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17782                = mAssociations.get(targetUid);
17783        if (components == null) {
17784            return;
17785        }
17786        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17787        if (sourceUids == null) {
17788            return;
17789        }
17790        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17791        if (sourceProcesses == null) {
17792            return;
17793        }
17794        Association ass = sourceProcesses.get(sourceProcess);
17795        if (ass == null || ass.mNesting <= 0) {
17796            return;
17797        }
17798        ass.mNesting--;
17799        if (ass.mNesting == 0) {
17800            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17801        }
17802    }
17803
17804    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17805            boolean doingAll, long now) {
17806        if (mAdjSeq == app.adjSeq) {
17807            // This adjustment has already been computed.
17808            return app.curRawAdj;
17809        }
17810
17811        if (app.thread == null) {
17812            app.adjSeq = mAdjSeq;
17813            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17814            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17815            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17816        }
17817
17818        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17819        app.adjSource = null;
17820        app.adjTarget = null;
17821        app.empty = false;
17822        app.cached = false;
17823
17824        final int activitiesSize = app.activities.size();
17825
17826        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17827            // The max adjustment doesn't allow this app to be anything
17828            // below foreground, so it is not worth doing work for it.
17829            app.adjType = "fixed";
17830            app.adjSeq = mAdjSeq;
17831            app.curRawAdj = app.maxAdj;
17832            app.foregroundActivities = false;
17833            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17834            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17835            // System processes can do UI, and when they do we want to have
17836            // them trim their memory after the user leaves the UI.  To
17837            // facilitate this, here we need to determine whether or not it
17838            // is currently showing UI.
17839            app.systemNoUi = true;
17840            if (app == TOP_APP) {
17841                app.systemNoUi = false;
17842            } else if (activitiesSize > 0) {
17843                for (int j = 0; j < activitiesSize; j++) {
17844                    final ActivityRecord r = app.activities.get(j);
17845                    if (r.visible) {
17846                        app.systemNoUi = false;
17847                    }
17848                }
17849            }
17850            if (!app.systemNoUi) {
17851                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17852            }
17853            return (app.curAdj=app.maxAdj);
17854        }
17855
17856        app.systemNoUi = false;
17857
17858        final int PROCESS_STATE_TOP = mTopProcessState;
17859
17860        // Determine the importance of the process, starting with most
17861        // important to least, and assign an appropriate OOM adjustment.
17862        int adj;
17863        int schedGroup;
17864        int procState;
17865        boolean foregroundActivities = false;
17866        BroadcastQueue queue;
17867        if (app == TOP_APP) {
17868            // The last app on the list is the foreground app.
17869            adj = ProcessList.FOREGROUND_APP_ADJ;
17870            schedGroup = Process.THREAD_GROUP_DEFAULT;
17871            app.adjType = "top-activity";
17872            foregroundActivities = true;
17873            procState = PROCESS_STATE_TOP;
17874        } else if (app.instrumentationClass != null) {
17875            // Don't want to kill running instrumentation.
17876            adj = ProcessList.FOREGROUND_APP_ADJ;
17877            schedGroup = Process.THREAD_GROUP_DEFAULT;
17878            app.adjType = "instrumentation";
17879            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17880        } else if ((queue = isReceivingBroadcast(app)) != null) {
17881            // An app that is currently receiving a broadcast also
17882            // counts as being in the foreground for OOM killer purposes.
17883            // It's placed in a sched group based on the nature of the
17884            // broadcast as reflected by which queue it's active in.
17885            adj = ProcessList.FOREGROUND_APP_ADJ;
17886            schedGroup = (queue == mFgBroadcastQueue)
17887                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17888            app.adjType = "broadcast";
17889            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17890        } else if (app.executingServices.size() > 0) {
17891            // An app that is currently executing a service callback also
17892            // counts as being in the foreground.
17893            adj = ProcessList.FOREGROUND_APP_ADJ;
17894            schedGroup = app.execServicesFg ?
17895                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17896            app.adjType = "exec-service";
17897            procState = ActivityManager.PROCESS_STATE_SERVICE;
17898            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17899        } else {
17900            // As far as we know the process is empty.  We may change our mind later.
17901            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17902            // At this point we don't actually know the adjustment.  Use the cached adj
17903            // value that the caller wants us to.
17904            adj = cachedAdj;
17905            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17906            app.cached = true;
17907            app.empty = true;
17908            app.adjType = "cch-empty";
17909        }
17910
17911        // Examine all activities if not already foreground.
17912        if (!foregroundActivities && activitiesSize > 0) {
17913            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
17914            for (int j = 0; j < activitiesSize; j++) {
17915                final ActivityRecord r = app.activities.get(j);
17916                if (r.app != app) {
17917                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17918                            + app + "?!? Using " + r.app + " instead.");
17919                    continue;
17920                }
17921                if (r.visible) {
17922                    // App has a visible activity; only upgrade adjustment.
17923                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17924                        adj = ProcessList.VISIBLE_APP_ADJ;
17925                        app.adjType = "visible";
17926                    }
17927                    if (procState > PROCESS_STATE_TOP) {
17928                        procState = PROCESS_STATE_TOP;
17929                    }
17930                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17931                    app.cached = false;
17932                    app.empty = false;
17933                    foregroundActivities = true;
17934                    if (r.task != null && minLayer > 0) {
17935                        final int layer = r.task.mLayerRank;
17936                        if (layer >= 0 && minLayer > layer) {
17937                            minLayer = layer;
17938                        }
17939                    }
17940                    break;
17941                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17942                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17943                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17944                        app.adjType = "pausing";
17945                    }
17946                    if (procState > PROCESS_STATE_TOP) {
17947                        procState = PROCESS_STATE_TOP;
17948                    }
17949                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17950                    app.cached = false;
17951                    app.empty = false;
17952                    foregroundActivities = true;
17953                } else if (r.state == ActivityState.STOPPING) {
17954                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17955                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17956                        app.adjType = "stopping";
17957                    }
17958                    // For the process state, we will at this point consider the
17959                    // process to be cached.  It will be cached either as an activity
17960                    // or empty depending on whether the activity is finishing.  We do
17961                    // this so that we can treat the process as cached for purposes of
17962                    // memory trimming (determing current memory level, trim command to
17963                    // send to process) since there can be an arbitrary number of stopping
17964                    // processes and they should soon all go into the cached state.
17965                    if (!r.finishing) {
17966                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17967                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17968                        }
17969                    }
17970                    app.cached = false;
17971                    app.empty = false;
17972                    foregroundActivities = true;
17973                } else {
17974                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17975                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17976                        app.adjType = "cch-act";
17977                    }
17978                }
17979            }
17980            if (adj == ProcessList.VISIBLE_APP_ADJ) {
17981                adj += minLayer;
17982            }
17983        }
17984
17985        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17986            if (app.foregroundServices) {
17987                // The user is aware of this app, so make it visible.
17988                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17989                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17990                app.cached = false;
17991                app.adjType = "fg-service";
17992                schedGroup = Process.THREAD_GROUP_DEFAULT;
17993            } else if (app.forcingToForeground != null) {
17994                // The user is aware of this app, so make it visible.
17995                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17996                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17997                app.cached = false;
17998                app.adjType = "force-fg";
17999                app.adjSource = app.forcingToForeground;
18000                schedGroup = Process.THREAD_GROUP_DEFAULT;
18001            }
18002        }
18003
18004        if (app == mHeavyWeightProcess) {
18005            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18006                // We don't want to kill the current heavy-weight process.
18007                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18008                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18009                app.cached = false;
18010                app.adjType = "heavy";
18011            }
18012            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18013                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18014            }
18015        }
18016
18017        if (app == mHomeProcess) {
18018            if (adj > ProcessList.HOME_APP_ADJ) {
18019                // This process is hosting what we currently consider to be the
18020                // home app, so we don't want to let it go into the background.
18021                adj = ProcessList.HOME_APP_ADJ;
18022                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18023                app.cached = false;
18024                app.adjType = "home";
18025            }
18026            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18027                procState = ActivityManager.PROCESS_STATE_HOME;
18028            }
18029        }
18030
18031        if (app == mPreviousProcess && app.activities.size() > 0) {
18032            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18033                // This was the previous process that showed UI to the user.
18034                // We want to try to keep it around more aggressively, to give
18035                // a good experience around switching between two apps.
18036                adj = ProcessList.PREVIOUS_APP_ADJ;
18037                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18038                app.cached = false;
18039                app.adjType = "previous";
18040            }
18041            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18042                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18043            }
18044        }
18045
18046        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18047                + " reason=" + app.adjType);
18048
18049        // By default, we use the computed adjustment.  It may be changed if
18050        // there are applications dependent on our services or providers, but
18051        // this gives us a baseline and makes sure we don't get into an
18052        // infinite recursion.
18053        app.adjSeq = mAdjSeq;
18054        app.curRawAdj = adj;
18055        app.hasStartedServices = false;
18056
18057        if (mBackupTarget != null && app == mBackupTarget.app) {
18058            // If possible we want to avoid killing apps while they're being backed up
18059            if (adj > ProcessList.BACKUP_APP_ADJ) {
18060                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18061                adj = ProcessList.BACKUP_APP_ADJ;
18062                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18063                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18064                }
18065                app.adjType = "backup";
18066                app.cached = false;
18067            }
18068            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18069                procState = ActivityManager.PROCESS_STATE_BACKUP;
18070            }
18071        }
18072
18073        boolean mayBeTop = false;
18074
18075        for (int is = app.services.size()-1;
18076                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18077                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18078                        || procState > ActivityManager.PROCESS_STATE_TOP);
18079                is--) {
18080            ServiceRecord s = app.services.valueAt(is);
18081            if (s.startRequested) {
18082                app.hasStartedServices = true;
18083                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18084                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18085                }
18086                if (app.hasShownUi && app != mHomeProcess) {
18087                    // If this process has shown some UI, let it immediately
18088                    // go to the LRU list because it may be pretty heavy with
18089                    // UI stuff.  We'll tag it with a label just to help
18090                    // debug and understand what is going on.
18091                    if (adj > ProcessList.SERVICE_ADJ) {
18092                        app.adjType = "cch-started-ui-services";
18093                    }
18094                } else {
18095                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18096                        // This service has seen some activity within
18097                        // recent memory, so we will keep its process ahead
18098                        // of the background processes.
18099                        if (adj > ProcessList.SERVICE_ADJ) {
18100                            adj = ProcessList.SERVICE_ADJ;
18101                            app.adjType = "started-services";
18102                            app.cached = false;
18103                        }
18104                    }
18105                    // If we have let the service slide into the background
18106                    // state, still have some text describing what it is doing
18107                    // even though the service no longer has an impact.
18108                    if (adj > ProcessList.SERVICE_ADJ) {
18109                        app.adjType = "cch-started-services";
18110                    }
18111                }
18112            }
18113            for (int conni = s.connections.size()-1;
18114                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18115                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18116                            || procState > ActivityManager.PROCESS_STATE_TOP);
18117                    conni--) {
18118                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18119                for (int i = 0;
18120                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18121                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18122                                || procState > ActivityManager.PROCESS_STATE_TOP);
18123                        i++) {
18124                    // XXX should compute this based on the max of
18125                    // all connected clients.
18126                    ConnectionRecord cr = clist.get(i);
18127                    if (cr.binding.client == app) {
18128                        // Binding to ourself is not interesting.
18129                        continue;
18130                    }
18131                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18132                        ProcessRecord client = cr.binding.client;
18133                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18134                                TOP_APP, doingAll, now);
18135                        int clientProcState = client.curProcState;
18136                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18137                            // If the other app is cached for any reason, for purposes here
18138                            // we are going to consider it empty.  The specific cached state
18139                            // doesn't propagate except under certain conditions.
18140                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18141                        }
18142                        String adjType = null;
18143                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18144                            // Not doing bind OOM management, so treat
18145                            // this guy more like a started service.
18146                            if (app.hasShownUi && app != mHomeProcess) {
18147                                // If this process has shown some UI, let it immediately
18148                                // go to the LRU list because it may be pretty heavy with
18149                                // UI stuff.  We'll tag it with a label just to help
18150                                // debug and understand what is going on.
18151                                if (adj > clientAdj) {
18152                                    adjType = "cch-bound-ui-services";
18153                                }
18154                                app.cached = false;
18155                                clientAdj = adj;
18156                                clientProcState = procState;
18157                            } else {
18158                                if (now >= (s.lastActivity
18159                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18160                                    // This service has not seen activity within
18161                                    // recent memory, so allow it to drop to the
18162                                    // LRU list if there is no other reason to keep
18163                                    // it around.  We'll also tag it with a label just
18164                                    // to help debug and undertand what is going on.
18165                                    if (adj > clientAdj) {
18166                                        adjType = "cch-bound-services";
18167                                    }
18168                                    clientAdj = adj;
18169                                }
18170                            }
18171                        }
18172                        if (adj > clientAdj) {
18173                            // If this process has recently shown UI, and
18174                            // the process that is binding to it is less
18175                            // important than being visible, then we don't
18176                            // care about the binding as much as we care
18177                            // about letting this process get into the LRU
18178                            // list to be killed and restarted if needed for
18179                            // memory.
18180                            if (app.hasShownUi && app != mHomeProcess
18181                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18182                                adjType = "cch-bound-ui-services";
18183                            } else {
18184                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18185                                        |Context.BIND_IMPORTANT)) != 0) {
18186                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18187                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18188                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18189                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18190                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18191                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18192                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18193                                    adj = clientAdj;
18194                                } else {
18195                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18196                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18197                                    }
18198                                }
18199                                if (!client.cached) {
18200                                    app.cached = false;
18201                                }
18202                                adjType = "service";
18203                            }
18204                        }
18205                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18206                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18207                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18208                            }
18209                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18210                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18211                                    // Special handling of clients who are in the top state.
18212                                    // We *may* want to consider this process to be in the
18213                                    // top state as well, but only if there is not another
18214                                    // reason for it to be running.  Being on the top is a
18215                                    // special state, meaning you are specifically running
18216                                    // for the current top app.  If the process is already
18217                                    // running in the background for some other reason, it
18218                                    // is more important to continue considering it to be
18219                                    // in the background state.
18220                                    mayBeTop = true;
18221                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18222                                } else {
18223                                    // Special handling for above-top states (persistent
18224                                    // processes).  These should not bring the current process
18225                                    // into the top state, since they are not on top.  Instead
18226                                    // give them the best state after that.
18227                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18228                                        clientProcState =
18229                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18230                                    } else if (mWakefulness
18231                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18232                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18233                                                    != 0) {
18234                                        clientProcState =
18235                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18236                                    } else {
18237                                        clientProcState =
18238                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18239                                    }
18240                                }
18241                            }
18242                        } else {
18243                            if (clientProcState <
18244                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18245                                clientProcState =
18246                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18247                            }
18248                        }
18249                        if (procState > clientProcState) {
18250                            procState = clientProcState;
18251                        }
18252                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18253                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18254                            app.pendingUiClean = true;
18255                        }
18256                        if (adjType != null) {
18257                            app.adjType = adjType;
18258                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18259                                    .REASON_SERVICE_IN_USE;
18260                            app.adjSource = cr.binding.client;
18261                            app.adjSourceProcState = clientProcState;
18262                            app.adjTarget = s.name;
18263                        }
18264                    }
18265                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18266                        app.treatLikeActivity = true;
18267                    }
18268                    final ActivityRecord a = cr.activity;
18269                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18270                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18271                                (a.visible || a.state == ActivityState.RESUMED
18272                                 || a.state == ActivityState.PAUSING)) {
18273                            adj = ProcessList.FOREGROUND_APP_ADJ;
18274                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18275                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18276                            }
18277                            app.cached = false;
18278                            app.adjType = "service";
18279                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18280                                    .REASON_SERVICE_IN_USE;
18281                            app.adjSource = a;
18282                            app.adjSourceProcState = procState;
18283                            app.adjTarget = s.name;
18284                        }
18285                    }
18286                }
18287            }
18288        }
18289
18290        for (int provi = app.pubProviders.size()-1;
18291                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18292                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18293                        || procState > ActivityManager.PROCESS_STATE_TOP);
18294                provi--) {
18295            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18296            for (int i = cpr.connections.size()-1;
18297                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18298                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18299                            || procState > ActivityManager.PROCESS_STATE_TOP);
18300                    i--) {
18301                ContentProviderConnection conn = cpr.connections.get(i);
18302                ProcessRecord client = conn.client;
18303                if (client == app) {
18304                    // Being our own client is not interesting.
18305                    continue;
18306                }
18307                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18308                int clientProcState = client.curProcState;
18309                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18310                    // If the other app is cached for any reason, for purposes here
18311                    // we are going to consider it empty.
18312                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18313                }
18314                if (adj > clientAdj) {
18315                    if (app.hasShownUi && app != mHomeProcess
18316                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18317                        app.adjType = "cch-ui-provider";
18318                    } else {
18319                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18320                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18321                        app.adjType = "provider";
18322                    }
18323                    app.cached &= client.cached;
18324                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18325                            .REASON_PROVIDER_IN_USE;
18326                    app.adjSource = client;
18327                    app.adjSourceProcState = clientProcState;
18328                    app.adjTarget = cpr.name;
18329                }
18330                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18331                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18332                        // Special handling of clients who are in the top state.
18333                        // We *may* want to consider this process to be in the
18334                        // top state as well, but only if there is not another
18335                        // reason for it to be running.  Being on the top is a
18336                        // special state, meaning you are specifically running
18337                        // for the current top app.  If the process is already
18338                        // running in the background for some other reason, it
18339                        // is more important to continue considering it to be
18340                        // in the background state.
18341                        mayBeTop = true;
18342                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18343                    } else {
18344                        // Special handling for above-top states (persistent
18345                        // processes).  These should not bring the current process
18346                        // into the top state, since they are not on top.  Instead
18347                        // give them the best state after that.
18348                        clientProcState =
18349                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18350                    }
18351                }
18352                if (procState > clientProcState) {
18353                    procState = clientProcState;
18354                }
18355                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18356                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18357                }
18358            }
18359            // If the provider has external (non-framework) process
18360            // dependencies, ensure that its adjustment is at least
18361            // FOREGROUND_APP_ADJ.
18362            if (cpr.hasExternalProcessHandles()) {
18363                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18364                    adj = ProcessList.FOREGROUND_APP_ADJ;
18365                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18366                    app.cached = false;
18367                    app.adjType = "provider";
18368                    app.adjTarget = cpr.name;
18369                }
18370                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18371                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18372                }
18373            }
18374        }
18375
18376        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18377            // A client of one of our services or providers is in the top state.  We
18378            // *may* want to be in the top state, but not if we are already running in
18379            // the background for some other reason.  For the decision here, we are going
18380            // to pick out a few specific states that we want to remain in when a client
18381            // is top (states that tend to be longer-term) and otherwise allow it to go
18382            // to the top state.
18383            switch (procState) {
18384                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18385                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18386                case ActivityManager.PROCESS_STATE_SERVICE:
18387                    // These all are longer-term states, so pull them up to the top
18388                    // of the background states, but not all the way to the top state.
18389                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18390                    break;
18391                default:
18392                    // Otherwise, top is a better choice, so take it.
18393                    procState = ActivityManager.PROCESS_STATE_TOP;
18394                    break;
18395            }
18396        }
18397
18398        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18399            if (app.hasClientActivities) {
18400                // This is a cached process, but with client activities.  Mark it so.
18401                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18402                app.adjType = "cch-client-act";
18403            } else if (app.treatLikeActivity) {
18404                // This is a cached process, but somebody wants us to treat it like it has
18405                // an activity, okay!
18406                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18407                app.adjType = "cch-as-act";
18408            }
18409        }
18410
18411        if (adj == ProcessList.SERVICE_ADJ) {
18412            if (doingAll) {
18413                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18414                mNewNumServiceProcs++;
18415                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18416                if (!app.serviceb) {
18417                    // This service isn't far enough down on the LRU list to
18418                    // normally be a B service, but if we are low on RAM and it
18419                    // is large we want to force it down since we would prefer to
18420                    // keep launcher over it.
18421                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18422                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18423                        app.serviceHighRam = true;
18424                        app.serviceb = true;
18425                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18426                    } else {
18427                        mNewNumAServiceProcs++;
18428                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18429                    }
18430                } else {
18431                    app.serviceHighRam = false;
18432                }
18433            }
18434            if (app.serviceb) {
18435                adj = ProcessList.SERVICE_B_ADJ;
18436            }
18437        }
18438
18439        app.curRawAdj = adj;
18440
18441        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18442        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18443        if (adj > app.maxAdj) {
18444            adj = app.maxAdj;
18445            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18446                schedGroup = Process.THREAD_GROUP_DEFAULT;
18447            }
18448        }
18449
18450        // Do final modification to adj.  Everything we do between here and applying
18451        // the final setAdj must be done in this function, because we will also use
18452        // it when computing the final cached adj later.  Note that we don't need to
18453        // worry about this for max adj above, since max adj will always be used to
18454        // keep it out of the cached vaues.
18455        app.curAdj = app.modifyRawOomAdj(adj);
18456        app.curSchedGroup = schedGroup;
18457        app.curProcState = procState;
18458        app.foregroundActivities = foregroundActivities;
18459
18460        return app.curRawAdj;
18461    }
18462
18463    /**
18464     * Record new PSS sample for a process.
18465     */
18466    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18467        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18468        proc.lastPssTime = now;
18469        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18470        if (DEBUG_PSS) Slog.d(TAG_PSS,
18471                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18472                + " state=" + ProcessList.makeProcStateString(procState));
18473        if (proc.initialIdlePss == 0) {
18474            proc.initialIdlePss = pss;
18475        }
18476        proc.lastPss = pss;
18477        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18478            proc.lastCachedPss = pss;
18479        }
18480
18481        final SparseArray<Pair<Long, String>> watchUids
18482                = mMemWatchProcesses.getMap().get(proc.processName);
18483        Long check = null;
18484        if (watchUids != null) {
18485            Pair<Long, String> val = watchUids.get(proc.uid);
18486            if (val == null) {
18487                val = watchUids.get(0);
18488            }
18489            if (val != null) {
18490                check = val.first;
18491            }
18492        }
18493        if (check != null) {
18494            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18495                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18496                if (!isDebuggable) {
18497                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18498                        isDebuggable = true;
18499                    }
18500                }
18501                if (isDebuggable) {
18502                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18503                    final ProcessRecord myProc = proc;
18504                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18505                    mMemWatchDumpProcName = proc.processName;
18506                    mMemWatchDumpFile = heapdumpFile.toString();
18507                    mMemWatchDumpPid = proc.pid;
18508                    mMemWatchDumpUid = proc.uid;
18509                    BackgroundThread.getHandler().post(new Runnable() {
18510                        @Override
18511                        public void run() {
18512                            revokeUriPermission(ActivityThread.currentActivityThread()
18513                                            .getApplicationThread(),
18514                                    DumpHeapActivity.JAVA_URI,
18515                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18516                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18517                                    UserHandle.myUserId());
18518                            ParcelFileDescriptor fd = null;
18519                            try {
18520                                heapdumpFile.delete();
18521                                fd = ParcelFileDescriptor.open(heapdumpFile,
18522                                        ParcelFileDescriptor.MODE_CREATE |
18523                                                ParcelFileDescriptor.MODE_TRUNCATE |
18524                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18525                                                ParcelFileDescriptor.MODE_APPEND);
18526                                IApplicationThread thread = myProc.thread;
18527                                if (thread != null) {
18528                                    try {
18529                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18530                                                "Requesting dump heap from "
18531                                                + myProc + " to " + heapdumpFile);
18532                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18533                                    } catch (RemoteException e) {
18534                                    }
18535                                }
18536                            } catch (FileNotFoundException e) {
18537                                e.printStackTrace();
18538                            } finally {
18539                                if (fd != null) {
18540                                    try {
18541                                        fd.close();
18542                                    } catch (IOException e) {
18543                                    }
18544                                }
18545                            }
18546                        }
18547                    });
18548                } else {
18549                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18550                            + ", but debugging not enabled");
18551                }
18552            }
18553        }
18554    }
18555
18556    /**
18557     * Schedule PSS collection of a process.
18558     */
18559    void requestPssLocked(ProcessRecord proc, int procState) {
18560        if (mPendingPssProcesses.contains(proc)) {
18561            return;
18562        }
18563        if (mPendingPssProcesses.size() == 0) {
18564            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18565        }
18566        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18567        proc.pssProcState = procState;
18568        mPendingPssProcesses.add(proc);
18569    }
18570
18571    /**
18572     * Schedule PSS collection of all processes.
18573     */
18574    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18575        if (!always) {
18576            if (now < (mLastFullPssTime +
18577                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18578                return;
18579            }
18580        }
18581        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18582        mLastFullPssTime = now;
18583        mFullPssPending = true;
18584        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18585        mPendingPssProcesses.clear();
18586        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18587            ProcessRecord app = mLruProcesses.get(i);
18588            if (app.thread == null
18589                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18590                continue;
18591            }
18592            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18593                app.pssProcState = app.setProcState;
18594                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18595                        mTestPssMode, isSleeping(), now);
18596                mPendingPssProcesses.add(app);
18597            }
18598        }
18599        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18600    }
18601
18602    public void setTestPssMode(boolean enabled) {
18603        synchronized (this) {
18604            mTestPssMode = enabled;
18605            if (enabled) {
18606                // Whenever we enable the mode, we want to take a snapshot all of current
18607                // process mem use.
18608                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18609            }
18610        }
18611    }
18612
18613    /**
18614     * Ask a given process to GC right now.
18615     */
18616    final void performAppGcLocked(ProcessRecord app) {
18617        try {
18618            app.lastRequestedGc = SystemClock.uptimeMillis();
18619            if (app.thread != null) {
18620                if (app.reportLowMemory) {
18621                    app.reportLowMemory = false;
18622                    app.thread.scheduleLowMemory();
18623                } else {
18624                    app.thread.processInBackground();
18625                }
18626            }
18627        } catch (Exception e) {
18628            // whatever.
18629        }
18630    }
18631
18632    /**
18633     * Returns true if things are idle enough to perform GCs.
18634     */
18635    private final boolean canGcNowLocked() {
18636        boolean processingBroadcasts = false;
18637        for (BroadcastQueue q : mBroadcastQueues) {
18638            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18639                processingBroadcasts = true;
18640            }
18641        }
18642        return !processingBroadcasts
18643                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18644    }
18645
18646    /**
18647     * Perform GCs on all processes that are waiting for it, but only
18648     * if things are idle.
18649     */
18650    final void performAppGcsLocked() {
18651        final int N = mProcessesToGc.size();
18652        if (N <= 0) {
18653            return;
18654        }
18655        if (canGcNowLocked()) {
18656            while (mProcessesToGc.size() > 0) {
18657                ProcessRecord proc = mProcessesToGc.remove(0);
18658                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18659                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18660                            <= SystemClock.uptimeMillis()) {
18661                        // To avoid spamming the system, we will GC processes one
18662                        // at a time, waiting a few seconds between each.
18663                        performAppGcLocked(proc);
18664                        scheduleAppGcsLocked();
18665                        return;
18666                    } else {
18667                        // It hasn't been long enough since we last GCed this
18668                        // process...  put it in the list to wait for its time.
18669                        addProcessToGcListLocked(proc);
18670                        break;
18671                    }
18672                }
18673            }
18674
18675            scheduleAppGcsLocked();
18676        }
18677    }
18678
18679    /**
18680     * If all looks good, perform GCs on all processes waiting for them.
18681     */
18682    final void performAppGcsIfAppropriateLocked() {
18683        if (canGcNowLocked()) {
18684            performAppGcsLocked();
18685            return;
18686        }
18687        // Still not idle, wait some more.
18688        scheduleAppGcsLocked();
18689    }
18690
18691    /**
18692     * Schedule the execution of all pending app GCs.
18693     */
18694    final void scheduleAppGcsLocked() {
18695        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18696
18697        if (mProcessesToGc.size() > 0) {
18698            // Schedule a GC for the time to the next process.
18699            ProcessRecord proc = mProcessesToGc.get(0);
18700            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18701
18702            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18703            long now = SystemClock.uptimeMillis();
18704            if (when < (now+GC_TIMEOUT)) {
18705                when = now + GC_TIMEOUT;
18706            }
18707            mHandler.sendMessageAtTime(msg, when);
18708        }
18709    }
18710
18711    /**
18712     * Add a process to the array of processes waiting to be GCed.  Keeps the
18713     * list in sorted order by the last GC time.  The process can't already be
18714     * on the list.
18715     */
18716    final void addProcessToGcListLocked(ProcessRecord proc) {
18717        boolean added = false;
18718        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18719            if (mProcessesToGc.get(i).lastRequestedGc <
18720                    proc.lastRequestedGc) {
18721                added = true;
18722                mProcessesToGc.add(i+1, proc);
18723                break;
18724            }
18725        }
18726        if (!added) {
18727            mProcessesToGc.add(0, proc);
18728        }
18729    }
18730
18731    /**
18732     * Set up to ask a process to GC itself.  This will either do it
18733     * immediately, or put it on the list of processes to gc the next
18734     * time things are idle.
18735     */
18736    final void scheduleAppGcLocked(ProcessRecord app) {
18737        long now = SystemClock.uptimeMillis();
18738        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18739            return;
18740        }
18741        if (!mProcessesToGc.contains(app)) {
18742            addProcessToGcListLocked(app);
18743            scheduleAppGcsLocked();
18744        }
18745    }
18746
18747    final void checkExcessivePowerUsageLocked(boolean doKills) {
18748        updateCpuStatsNow();
18749
18750        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18751        boolean doWakeKills = doKills;
18752        boolean doCpuKills = doKills;
18753        if (mLastPowerCheckRealtime == 0) {
18754            doWakeKills = false;
18755        }
18756        if (mLastPowerCheckUptime == 0) {
18757            doCpuKills = false;
18758        }
18759        if (stats.isScreenOn()) {
18760            doWakeKills = false;
18761        }
18762        final long curRealtime = SystemClock.elapsedRealtime();
18763        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18764        final long curUptime = SystemClock.uptimeMillis();
18765        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18766        mLastPowerCheckRealtime = curRealtime;
18767        mLastPowerCheckUptime = curUptime;
18768        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18769            doWakeKills = false;
18770        }
18771        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18772            doCpuKills = false;
18773        }
18774        int i = mLruProcesses.size();
18775        while (i > 0) {
18776            i--;
18777            ProcessRecord app = mLruProcesses.get(i);
18778            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18779                long wtime;
18780                synchronized (stats) {
18781                    wtime = stats.getProcessWakeTime(app.info.uid,
18782                            app.pid, curRealtime);
18783                }
18784                long wtimeUsed = wtime - app.lastWakeTime;
18785                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18786                if (DEBUG_POWER) {
18787                    StringBuilder sb = new StringBuilder(128);
18788                    sb.append("Wake for ");
18789                    app.toShortString(sb);
18790                    sb.append(": over ");
18791                    TimeUtils.formatDuration(realtimeSince, sb);
18792                    sb.append(" used ");
18793                    TimeUtils.formatDuration(wtimeUsed, sb);
18794                    sb.append(" (");
18795                    sb.append((wtimeUsed*100)/realtimeSince);
18796                    sb.append("%)");
18797                    Slog.i(TAG_POWER, sb.toString());
18798                    sb.setLength(0);
18799                    sb.append("CPU for ");
18800                    app.toShortString(sb);
18801                    sb.append(": over ");
18802                    TimeUtils.formatDuration(uptimeSince, sb);
18803                    sb.append(" used ");
18804                    TimeUtils.formatDuration(cputimeUsed, sb);
18805                    sb.append(" (");
18806                    sb.append((cputimeUsed*100)/uptimeSince);
18807                    sb.append("%)");
18808                    Slog.i(TAG_POWER, sb.toString());
18809                }
18810                // If a process has held a wake lock for more
18811                // than 50% of the time during this period,
18812                // that sounds bad.  Kill!
18813                if (doWakeKills && realtimeSince > 0
18814                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18815                    synchronized (stats) {
18816                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18817                                realtimeSince, wtimeUsed);
18818                    }
18819                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18820                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18821                } else if (doCpuKills && uptimeSince > 0
18822                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18823                    synchronized (stats) {
18824                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18825                                uptimeSince, cputimeUsed);
18826                    }
18827                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18828                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18829                } else {
18830                    app.lastWakeTime = wtime;
18831                    app.lastCpuTime = app.curCpuTime;
18832                }
18833            }
18834        }
18835    }
18836
18837    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18838            long nowElapsed) {
18839        boolean success = true;
18840
18841        if (app.curRawAdj != app.setRawAdj) {
18842            app.setRawAdj = app.curRawAdj;
18843        }
18844
18845        int changes = 0;
18846
18847        if (app.curAdj != app.setAdj) {
18848            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18849            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18850                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18851                    + app.adjType);
18852            app.setAdj = app.curAdj;
18853        }
18854
18855        if (app.setSchedGroup != app.curSchedGroup) {
18856            app.setSchedGroup = app.curSchedGroup;
18857            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18858                    "Setting process group of " + app.processName
18859                    + " to " + app.curSchedGroup);
18860            if (app.waitingToKill != null && app.curReceiver == null
18861                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18862                app.kill(app.waitingToKill, true);
18863                success = false;
18864            } else {
18865                if (true) {
18866                    long oldId = Binder.clearCallingIdentity();
18867                    try {
18868                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18869                    } catch (Exception e) {
18870                        Slog.w(TAG, "Failed setting process group of " + app.pid
18871                                + " to " + app.curSchedGroup);
18872                        e.printStackTrace();
18873                    } finally {
18874                        Binder.restoreCallingIdentity(oldId);
18875                    }
18876                } else {
18877                    if (app.thread != null) {
18878                        try {
18879                            app.thread.setSchedulingGroup(app.curSchedGroup);
18880                        } catch (RemoteException e) {
18881                        }
18882                    }
18883                }
18884                Process.setSwappiness(app.pid,
18885                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18886            }
18887        }
18888        if (app.repForegroundActivities != app.foregroundActivities) {
18889            app.repForegroundActivities = app.foregroundActivities;
18890            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18891        }
18892        if (app.repProcState != app.curProcState) {
18893            app.repProcState = app.curProcState;
18894            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18895            if (app.thread != null) {
18896                try {
18897                    if (false) {
18898                        //RuntimeException h = new RuntimeException("here");
18899                        Slog.i(TAG, "Sending new process state " + app.repProcState
18900                                + " to " + app /*, h*/);
18901                    }
18902                    app.thread.setProcessState(app.repProcState);
18903                } catch (RemoteException e) {
18904                }
18905            }
18906        }
18907        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18908                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18909            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18910                // Experimental code to more aggressively collect pss while
18911                // running test...  the problem is that this tends to collect
18912                // the data right when a process is transitioning between process
18913                // states, which well tend to give noisy data.
18914                long start = SystemClock.uptimeMillis();
18915                long pss = Debug.getPss(app.pid, mTmpLong, null);
18916                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18917                mPendingPssProcesses.remove(app);
18918                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18919                        + " to " + app.curProcState + ": "
18920                        + (SystemClock.uptimeMillis()-start) + "ms");
18921            }
18922            app.lastStateTime = now;
18923            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18924                    mTestPssMode, isSleeping(), now);
18925            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18926                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18927                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18928                    + (app.nextPssTime-now) + ": " + app);
18929        } else {
18930            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18931                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18932                    mTestPssMode)))) {
18933                requestPssLocked(app, app.setProcState);
18934                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18935                        mTestPssMode, isSleeping(), now);
18936            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18937                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18938        }
18939        if (app.setProcState != app.curProcState) {
18940            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18941                    "Proc state change of " + app.processName
18942                            + " to " + app.curProcState);
18943            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18944            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18945            if (setImportant && !curImportant) {
18946                // This app is no longer something we consider important enough to allow to
18947                // use arbitrary amounts of battery power.  Note
18948                // its current wake lock time to later know to kill it if
18949                // it is not behaving well.
18950                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18951                synchronized (stats) {
18952                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18953                            app.pid, nowElapsed);
18954                }
18955                app.lastCpuTime = app.curCpuTime;
18956
18957            }
18958            // Inform UsageStats of important process state change
18959            // Must be called before updating setProcState
18960            maybeUpdateUsageStatsLocked(app, nowElapsed);
18961
18962            app.setProcState = app.curProcState;
18963            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18964                app.notCachedSinceIdle = false;
18965            }
18966            if (!doingAll) {
18967                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18968            } else {
18969                app.procStateChanged = true;
18970            }
18971        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
18972                > USAGE_STATS_INTERACTION_INTERVAL) {
18973            // For apps that sit around for a long time in the interactive state, we need
18974            // to report this at least once a day so they don't go idle.
18975            maybeUpdateUsageStatsLocked(app, nowElapsed);
18976        }
18977
18978        if (changes != 0) {
18979            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18980                    "Changes in " + app + ": " + changes);
18981            int i = mPendingProcessChanges.size()-1;
18982            ProcessChangeItem item = null;
18983            while (i >= 0) {
18984                item = mPendingProcessChanges.get(i);
18985                if (item.pid == app.pid) {
18986                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18987                            "Re-using existing item: " + item);
18988                    break;
18989                }
18990                i--;
18991            }
18992            if (i < 0) {
18993                // No existing item in pending changes; need a new one.
18994                final int NA = mAvailProcessChanges.size();
18995                if (NA > 0) {
18996                    item = mAvailProcessChanges.remove(NA-1);
18997                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18998                            "Retrieving available item: " + item);
18999                } else {
19000                    item = new ProcessChangeItem();
19001                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19002                            "Allocating new item: " + item);
19003                }
19004                item.changes = 0;
19005                item.pid = app.pid;
19006                item.uid = app.info.uid;
19007                if (mPendingProcessChanges.size() == 0) {
19008                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19009                            "*** Enqueueing dispatch processes changed!");
19010                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
19011                }
19012                mPendingProcessChanges.add(item);
19013            }
19014            item.changes |= changes;
19015            item.processState = app.repProcState;
19016            item.foregroundActivities = app.repForegroundActivities;
19017            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19018                    "Item " + Integer.toHexString(System.identityHashCode(item))
19019                    + " " + app.toShortString() + ": changes=" + item.changes
19020                    + " procState=" + item.processState
19021                    + " foreground=" + item.foregroundActivities
19022                    + " type=" + app.adjType + " source=" + app.adjSource
19023                    + " target=" + app.adjTarget);
19024        }
19025
19026        return success;
19027    }
19028
19029    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
19030        if (uidRec.pendingChange == null) {
19031            if (mPendingUidChanges.size() == 0) {
19032                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19033                        "*** Enqueueing dispatch uid changed!");
19034                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
19035            }
19036            final int NA = mAvailUidChanges.size();
19037            if (NA > 0) {
19038                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
19039                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19040                        "Retrieving available item: " + uidRec.pendingChange);
19041            } else {
19042                uidRec.pendingChange = new UidRecord.ChangeItem();
19043                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19044                        "Allocating new item: " + uidRec.pendingChange);
19045            }
19046            uidRec.pendingChange.uidRecord = uidRec;
19047            uidRec.pendingChange.uid = uidRec.uid;
19048            mPendingUidChanges.add(uidRec.pendingChange);
19049        }
19050        uidRec.pendingChange.gone = gone;
19051        uidRec.pendingChange.processState = uidRec.setProcState;
19052    }
19053
19054    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19055            String authority) {
19056        if (app == null) return;
19057        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19058            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19059            if (userState == null) return;
19060            final long now = SystemClock.elapsedRealtime();
19061            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19062            if (lastReported == null || lastReported < now - 60 * 1000L) {
19063                mUsageStatsService.reportContentProviderUsage(
19064                        authority, providerPkgName, app.userId);
19065                userState.mProviderLastReportedFg.put(authority, now);
19066            }
19067        }
19068    }
19069
19070    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19071        if (DEBUG_USAGE_STATS) {
19072            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19073                    + "] state changes: old = " + app.setProcState + ", new = "
19074                    + app.curProcState);
19075        }
19076        if (mUsageStatsService == null) {
19077            return;
19078        }
19079        boolean isInteraction;
19080        // To avoid some abuse patterns, we are going to be careful about what we consider
19081        // to be an app interaction.  Being the top activity doesn't count while the display
19082        // is sleeping, nor do short foreground services.
19083        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19084            isInteraction = true;
19085            app.fgInteractionTime = 0;
19086        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19087            if (app.fgInteractionTime == 0) {
19088                app.fgInteractionTime = nowElapsed;
19089                isInteraction = false;
19090            } else {
19091                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19092            }
19093        } else {
19094            isInteraction = app.curProcState
19095                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19096            app.fgInteractionTime = 0;
19097        }
19098        if (isInteraction && (!app.reportedInteraction
19099                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19100            app.interactionEventTime = nowElapsed;
19101            String[] packages = app.getPackageList();
19102            if (packages != null) {
19103                for (int i = 0; i < packages.length; i++) {
19104                    mUsageStatsService.reportEvent(packages[i], app.userId,
19105                            UsageEvents.Event.SYSTEM_INTERACTION);
19106                }
19107            }
19108        }
19109        app.reportedInteraction = isInteraction;
19110        if (!isInteraction) {
19111            app.interactionEventTime = 0;
19112        }
19113    }
19114
19115    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19116        if (proc.thread != null) {
19117            if (proc.baseProcessTracker != null) {
19118                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19119            }
19120            if (proc.repProcState >= 0) {
19121                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19122                        proc.repProcState);
19123            }
19124        }
19125    }
19126
19127    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19128            ProcessRecord TOP_APP, boolean doingAll, long now) {
19129        if (app.thread == null) {
19130            return false;
19131        }
19132
19133        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19134
19135        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19136    }
19137
19138    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19139            boolean oomAdj) {
19140        if (isForeground != proc.foregroundServices) {
19141            proc.foregroundServices = isForeground;
19142            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19143                    proc.info.uid);
19144            if (isForeground) {
19145                if (curProcs == null) {
19146                    curProcs = new ArrayList<ProcessRecord>();
19147                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19148                }
19149                if (!curProcs.contains(proc)) {
19150                    curProcs.add(proc);
19151                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19152                            proc.info.packageName, proc.info.uid);
19153                }
19154            } else {
19155                if (curProcs != null) {
19156                    if (curProcs.remove(proc)) {
19157                        mBatteryStatsService.noteEvent(
19158                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19159                                proc.info.packageName, proc.info.uid);
19160                        if (curProcs.size() <= 0) {
19161                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19162                        }
19163                    }
19164                }
19165            }
19166            if (oomAdj) {
19167                updateOomAdjLocked();
19168            }
19169        }
19170    }
19171
19172    private final ActivityRecord resumedAppLocked() {
19173        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19174        String pkg;
19175        int uid;
19176        if (act != null) {
19177            pkg = act.packageName;
19178            uid = act.info.applicationInfo.uid;
19179        } else {
19180            pkg = null;
19181            uid = -1;
19182        }
19183        // Has the UID or resumed package name changed?
19184        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19185                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19186            if (mCurResumedPackage != null) {
19187                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19188                        mCurResumedPackage, mCurResumedUid);
19189            }
19190            mCurResumedPackage = pkg;
19191            mCurResumedUid = uid;
19192            if (mCurResumedPackage != null) {
19193                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19194                        mCurResumedPackage, mCurResumedUid);
19195            }
19196        }
19197        return act;
19198    }
19199
19200    final boolean updateOomAdjLocked(ProcessRecord app) {
19201        final ActivityRecord TOP_ACT = resumedAppLocked();
19202        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19203        final boolean wasCached = app.cached;
19204
19205        mAdjSeq++;
19206
19207        // This is the desired cached adjusment we want to tell it to use.
19208        // If our app is currently cached, we know it, and that is it.  Otherwise,
19209        // we don't know it yet, and it needs to now be cached we will then
19210        // need to do a complete oom adj.
19211        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19212                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19213        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19214                SystemClock.uptimeMillis());
19215        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19216            // Changed to/from cached state, so apps after it in the LRU
19217            // list may also be changed.
19218            updateOomAdjLocked();
19219        }
19220        return success;
19221    }
19222
19223    final void updateOomAdjLocked() {
19224        final ActivityRecord TOP_ACT = resumedAppLocked();
19225        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19226        final long now = SystemClock.uptimeMillis();
19227        final long nowElapsed = SystemClock.elapsedRealtime();
19228        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19229        final int N = mLruProcesses.size();
19230
19231        if (false) {
19232            RuntimeException e = new RuntimeException();
19233            e.fillInStackTrace();
19234            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19235        }
19236
19237        // Reset state in all uid records.
19238        for (int i=mActiveUids.size()-1; i>=0; i--) {
19239            final UidRecord uidRec = mActiveUids.valueAt(i);
19240            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19241                    "Starting update of " + uidRec);
19242            uidRec.reset();
19243        }
19244
19245        mStackSupervisor.rankTaskLayersIfNeeded();
19246
19247        mAdjSeq++;
19248        mNewNumServiceProcs = 0;
19249        mNewNumAServiceProcs = 0;
19250
19251        final int emptyProcessLimit;
19252        final int cachedProcessLimit;
19253        if (mProcessLimit <= 0) {
19254            emptyProcessLimit = cachedProcessLimit = 0;
19255        } else if (mProcessLimit == 1) {
19256            emptyProcessLimit = 1;
19257            cachedProcessLimit = 0;
19258        } else {
19259            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19260            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19261        }
19262
19263        // Let's determine how many processes we have running vs.
19264        // how many slots we have for background processes; we may want
19265        // to put multiple processes in a slot of there are enough of
19266        // them.
19267        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19268                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19269        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19270        if (numEmptyProcs > cachedProcessLimit) {
19271            // If there are more empty processes than our limit on cached
19272            // processes, then use the cached process limit for the factor.
19273            // This ensures that the really old empty processes get pushed
19274            // down to the bottom, so if we are running low on memory we will
19275            // have a better chance at keeping around more cached processes
19276            // instead of a gazillion empty processes.
19277            numEmptyProcs = cachedProcessLimit;
19278        }
19279        int emptyFactor = numEmptyProcs/numSlots;
19280        if (emptyFactor < 1) emptyFactor = 1;
19281        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19282        if (cachedFactor < 1) cachedFactor = 1;
19283        int stepCached = 0;
19284        int stepEmpty = 0;
19285        int numCached = 0;
19286        int numEmpty = 0;
19287        int numTrimming = 0;
19288
19289        mNumNonCachedProcs = 0;
19290        mNumCachedHiddenProcs = 0;
19291
19292        // First update the OOM adjustment for each of the
19293        // application processes based on their current state.
19294        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19295        int nextCachedAdj = curCachedAdj+1;
19296        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19297        int nextEmptyAdj = curEmptyAdj+2;
19298        for (int i=N-1; i>=0; i--) {
19299            ProcessRecord app = mLruProcesses.get(i);
19300            if (!app.killedByAm && app.thread != null) {
19301                app.procStateChanged = false;
19302                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19303
19304                // If we haven't yet assigned the final cached adj
19305                // to the process, do that now.
19306                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19307                    switch (app.curProcState) {
19308                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19309                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19310                            // This process is a cached process holding activities...
19311                            // assign it the next cached value for that type, and then
19312                            // step that cached level.
19313                            app.curRawAdj = curCachedAdj;
19314                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19315                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19316                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19317                                    + ")");
19318                            if (curCachedAdj != nextCachedAdj) {
19319                                stepCached++;
19320                                if (stepCached >= cachedFactor) {
19321                                    stepCached = 0;
19322                                    curCachedAdj = nextCachedAdj;
19323                                    nextCachedAdj += 2;
19324                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19325                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19326                                    }
19327                                }
19328                            }
19329                            break;
19330                        default:
19331                            // For everything else, assign next empty cached process
19332                            // level and bump that up.  Note that this means that
19333                            // long-running services that have dropped down to the
19334                            // cached level will be treated as empty (since their process
19335                            // state is still as a service), which is what we want.
19336                            app.curRawAdj = curEmptyAdj;
19337                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19338                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19339                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19340                                    + ")");
19341                            if (curEmptyAdj != nextEmptyAdj) {
19342                                stepEmpty++;
19343                                if (stepEmpty >= emptyFactor) {
19344                                    stepEmpty = 0;
19345                                    curEmptyAdj = nextEmptyAdj;
19346                                    nextEmptyAdj += 2;
19347                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19348                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19349                                    }
19350                                }
19351                            }
19352                            break;
19353                    }
19354                }
19355
19356                applyOomAdjLocked(app, true, now, nowElapsed);
19357
19358                // Count the number of process types.
19359                switch (app.curProcState) {
19360                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19361                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19362                        mNumCachedHiddenProcs++;
19363                        numCached++;
19364                        if (numCached > cachedProcessLimit) {
19365                            app.kill("cached #" + numCached, true);
19366                        }
19367                        break;
19368                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19369                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19370                                && app.lastActivityTime < oldTime) {
19371                            app.kill("empty for "
19372                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19373                                    / 1000) + "s", true);
19374                        } else {
19375                            numEmpty++;
19376                            if (numEmpty > emptyProcessLimit) {
19377                                app.kill("empty #" + numEmpty, true);
19378                            }
19379                        }
19380                        break;
19381                    default:
19382                        mNumNonCachedProcs++;
19383                        break;
19384                }
19385
19386                if (app.isolated && app.services.size() <= 0) {
19387                    // If this is an isolated process, and there are no
19388                    // services running in it, then the process is no longer
19389                    // needed.  We agressively kill these because we can by
19390                    // definition not re-use the same process again, and it is
19391                    // good to avoid having whatever code was running in them
19392                    // left sitting around after no longer needed.
19393                    app.kill("isolated not needed", true);
19394                } else {
19395                    // Keeping this process, update its uid.
19396                    final UidRecord uidRec = app.uidRecord;
19397                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19398                        uidRec.curProcState = app.curProcState;
19399                    }
19400                }
19401
19402                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19403                        && !app.killedByAm) {
19404                    numTrimming++;
19405                }
19406            }
19407        }
19408
19409        mNumServiceProcs = mNewNumServiceProcs;
19410
19411        // Now determine the memory trimming level of background processes.
19412        // Unfortunately we need to start at the back of the list to do this
19413        // properly.  We only do this if the number of background apps we
19414        // are managing to keep around is less than half the maximum we desire;
19415        // if we are keeping a good number around, we'll let them use whatever
19416        // memory they want.
19417        final int numCachedAndEmpty = numCached + numEmpty;
19418        int memFactor;
19419        if (numCached <= ProcessList.TRIM_CACHED_APPS
19420                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19421            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19422                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19423            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19424                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19425            } else {
19426                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19427            }
19428        } else {
19429            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19430        }
19431        // We always allow the memory level to go up (better).  We only allow it to go
19432        // down if we are in a state where that is allowed, *and* the total number of processes
19433        // has gone down since last time.
19434        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19435                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19436                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19437        if (memFactor > mLastMemoryLevel) {
19438            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19439                memFactor = mLastMemoryLevel;
19440                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19441            }
19442        }
19443        mLastMemoryLevel = memFactor;
19444        mLastNumProcesses = mLruProcesses.size();
19445        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19446        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19447        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19448            if (mLowRamStartTime == 0) {
19449                mLowRamStartTime = now;
19450            }
19451            int step = 0;
19452            int fgTrimLevel;
19453            switch (memFactor) {
19454                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19455                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19456                    break;
19457                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19458                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19459                    break;
19460                default:
19461                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19462                    break;
19463            }
19464            int factor = numTrimming/3;
19465            int minFactor = 2;
19466            if (mHomeProcess != null) minFactor++;
19467            if (mPreviousProcess != null) minFactor++;
19468            if (factor < minFactor) factor = minFactor;
19469            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19470            for (int i=N-1; i>=0; i--) {
19471                ProcessRecord app = mLruProcesses.get(i);
19472                if (allChanged || app.procStateChanged) {
19473                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19474                    app.procStateChanged = false;
19475                }
19476                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19477                        && !app.killedByAm) {
19478                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19479                        try {
19480                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19481                                    "Trimming memory of " + app.processName + " to " + curLevel);
19482                            app.thread.scheduleTrimMemory(curLevel);
19483                        } catch (RemoteException e) {
19484                        }
19485                        if (false) {
19486                            // For now we won't do this; our memory trimming seems
19487                            // to be good enough at this point that destroying
19488                            // activities causes more harm than good.
19489                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19490                                    && app != mHomeProcess && app != mPreviousProcess) {
19491                                // Need to do this on its own message because the stack may not
19492                                // be in a consistent state at this point.
19493                                // For these apps we will also finish their activities
19494                                // to help them free memory.
19495                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19496                            }
19497                        }
19498                    }
19499                    app.trimMemoryLevel = curLevel;
19500                    step++;
19501                    if (step >= factor) {
19502                        step = 0;
19503                        switch (curLevel) {
19504                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19505                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19506                                break;
19507                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19508                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19509                                break;
19510                        }
19511                    }
19512                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19513                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19514                            && app.thread != null) {
19515                        try {
19516                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19517                                    "Trimming memory of heavy-weight " + app.processName
19518                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19519                            app.thread.scheduleTrimMemory(
19520                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19521                        } catch (RemoteException e) {
19522                        }
19523                    }
19524                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19525                } else {
19526                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19527                            || app.systemNoUi) && app.pendingUiClean) {
19528                        // If this application is now in the background and it
19529                        // had done UI, then give it the special trim level to
19530                        // have it free UI resources.
19531                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19532                        if (app.trimMemoryLevel < level && app.thread != null) {
19533                            try {
19534                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19535                                        "Trimming memory of bg-ui " + app.processName
19536                                        + " to " + level);
19537                                app.thread.scheduleTrimMemory(level);
19538                            } catch (RemoteException e) {
19539                            }
19540                        }
19541                        app.pendingUiClean = false;
19542                    }
19543                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19544                        try {
19545                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19546                                    "Trimming memory of fg " + app.processName
19547                                    + " to " + fgTrimLevel);
19548                            app.thread.scheduleTrimMemory(fgTrimLevel);
19549                        } catch (RemoteException e) {
19550                        }
19551                    }
19552                    app.trimMemoryLevel = fgTrimLevel;
19553                }
19554            }
19555        } else {
19556            if (mLowRamStartTime != 0) {
19557                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19558                mLowRamStartTime = 0;
19559            }
19560            for (int i=N-1; i>=0; i--) {
19561                ProcessRecord app = mLruProcesses.get(i);
19562                if (allChanged || app.procStateChanged) {
19563                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19564                    app.procStateChanged = false;
19565                }
19566                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19567                        || app.systemNoUi) && app.pendingUiClean) {
19568                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19569                            && app.thread != null) {
19570                        try {
19571                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19572                                    "Trimming memory of ui hidden " + app.processName
19573                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19574                            app.thread.scheduleTrimMemory(
19575                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19576                        } catch (RemoteException e) {
19577                        }
19578                    }
19579                    app.pendingUiClean = false;
19580                }
19581                app.trimMemoryLevel = 0;
19582            }
19583        }
19584
19585        if (mAlwaysFinishActivities) {
19586            // Need to do this on its own message because the stack may not
19587            // be in a consistent state at this point.
19588            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19589        }
19590
19591        if (allChanged) {
19592            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19593        }
19594
19595        // Update from any uid changes.
19596        for (int i=mActiveUids.size()-1; i>=0; i--) {
19597            final UidRecord uidRec = mActiveUids.valueAt(i);
19598            if (uidRec.setProcState != uidRec.curProcState) {
19599                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19600                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19601                        + " to " + uidRec.curProcState);
19602                uidRec.setProcState = uidRec.curProcState;
19603                enqueueUidChangeLocked(uidRec, false);
19604            }
19605        }
19606
19607        if (mProcessStats.shouldWriteNowLocked(now)) {
19608            mHandler.post(new Runnable() {
19609                @Override public void run() {
19610                    synchronized (ActivityManagerService.this) {
19611                        mProcessStats.writeStateAsyncLocked();
19612                    }
19613                }
19614            });
19615        }
19616
19617        if (DEBUG_OOM_ADJ) {
19618            final long duration = SystemClock.uptimeMillis() - now;
19619            if (false) {
19620                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19621                        new RuntimeException("here").fillInStackTrace());
19622            } else {
19623                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19624            }
19625        }
19626    }
19627
19628    final void trimApplications() {
19629        synchronized (this) {
19630            int i;
19631
19632            // First remove any unused application processes whose package
19633            // has been removed.
19634            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19635                final ProcessRecord app = mRemovedProcesses.get(i);
19636                if (app.activities.size() == 0
19637                        && app.curReceiver == null && app.services.size() == 0) {
19638                    Slog.i(
19639                        TAG, "Exiting empty application process "
19640                        + app.processName + " ("
19641                        + (app.thread != null ? app.thread.asBinder() : null)
19642                        + ")\n");
19643                    if (app.pid > 0 && app.pid != MY_PID) {
19644                        app.kill("empty", false);
19645                    } else {
19646                        try {
19647                            app.thread.scheduleExit();
19648                        } catch (Exception e) {
19649                            // Ignore exceptions.
19650                        }
19651                    }
19652                    cleanUpApplicationRecordLocked(app, false, true, -1);
19653                    mRemovedProcesses.remove(i);
19654
19655                    if (app.persistent) {
19656                        addAppLocked(app.info, false, null /* ABI override */);
19657                    }
19658                }
19659            }
19660
19661            // Now update the oom adj for all processes.
19662            updateOomAdjLocked();
19663        }
19664    }
19665
19666    /** This method sends the specified signal to each of the persistent apps */
19667    public void signalPersistentProcesses(int sig) throws RemoteException {
19668        if (sig != Process.SIGNAL_USR1) {
19669            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19670        }
19671
19672        synchronized (this) {
19673            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19674                    != PackageManager.PERMISSION_GRANTED) {
19675                throw new SecurityException("Requires permission "
19676                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19677            }
19678
19679            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19680                ProcessRecord r = mLruProcesses.get(i);
19681                if (r.thread != null && r.persistent) {
19682                    Process.sendSignal(r.pid, sig);
19683                }
19684            }
19685        }
19686    }
19687
19688    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19689        if (proc == null || proc == mProfileProc) {
19690            proc = mProfileProc;
19691            profileType = mProfileType;
19692            clearProfilerLocked();
19693        }
19694        if (proc == null) {
19695            return;
19696        }
19697        try {
19698            proc.thread.profilerControl(false, null, profileType);
19699        } catch (RemoteException e) {
19700            throw new IllegalStateException("Process disappeared");
19701        }
19702    }
19703
19704    private void clearProfilerLocked() {
19705        if (mProfileFd != null) {
19706            try {
19707                mProfileFd.close();
19708            } catch (IOException e) {
19709            }
19710        }
19711        mProfileApp = null;
19712        mProfileProc = null;
19713        mProfileFile = null;
19714        mProfileType = 0;
19715        mAutoStopProfiler = false;
19716        mSamplingInterval = 0;
19717    }
19718
19719    public boolean profileControl(String process, int userId, boolean start,
19720            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19721
19722        try {
19723            synchronized (this) {
19724                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19725                // its own permission.
19726                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19727                        != PackageManager.PERMISSION_GRANTED) {
19728                    throw new SecurityException("Requires permission "
19729                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19730                }
19731
19732                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19733                    throw new IllegalArgumentException("null profile info or fd");
19734                }
19735
19736                ProcessRecord proc = null;
19737                if (process != null) {
19738                    proc = findProcessLocked(process, userId, "profileControl");
19739                }
19740
19741                if (start && (proc == null || proc.thread == null)) {
19742                    throw new IllegalArgumentException("Unknown process: " + process);
19743                }
19744
19745                if (start) {
19746                    stopProfilerLocked(null, 0);
19747                    setProfileApp(proc.info, proc.processName, profilerInfo);
19748                    mProfileProc = proc;
19749                    mProfileType = profileType;
19750                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19751                    try {
19752                        fd = fd.dup();
19753                    } catch (IOException e) {
19754                        fd = null;
19755                    }
19756                    profilerInfo.profileFd = fd;
19757                    proc.thread.profilerControl(start, profilerInfo, profileType);
19758                    fd = null;
19759                    mProfileFd = null;
19760                } else {
19761                    stopProfilerLocked(proc, profileType);
19762                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19763                        try {
19764                            profilerInfo.profileFd.close();
19765                        } catch (IOException e) {
19766                        }
19767                    }
19768                }
19769
19770                return true;
19771            }
19772        } catch (RemoteException e) {
19773            throw new IllegalStateException("Process disappeared");
19774        } finally {
19775            if (profilerInfo != null && profilerInfo.profileFd != null) {
19776                try {
19777                    profilerInfo.profileFd.close();
19778                } catch (IOException e) {
19779                }
19780            }
19781        }
19782    }
19783
19784    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19785        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19786                userId, true, ALLOW_FULL_ONLY, callName, null);
19787        ProcessRecord proc = null;
19788        try {
19789            int pid = Integer.parseInt(process);
19790            synchronized (mPidsSelfLocked) {
19791                proc = mPidsSelfLocked.get(pid);
19792            }
19793        } catch (NumberFormatException e) {
19794        }
19795
19796        if (proc == null) {
19797            ArrayMap<String, SparseArray<ProcessRecord>> all
19798                    = mProcessNames.getMap();
19799            SparseArray<ProcessRecord> procs = all.get(process);
19800            if (procs != null && procs.size() > 0) {
19801                proc = procs.valueAt(0);
19802                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19803                    for (int i=1; i<procs.size(); i++) {
19804                        ProcessRecord thisProc = procs.valueAt(i);
19805                        if (thisProc.userId == userId) {
19806                            proc = thisProc;
19807                            break;
19808                        }
19809                    }
19810                }
19811            }
19812        }
19813
19814        return proc;
19815    }
19816
19817    public boolean dumpHeap(String process, int userId, boolean managed,
19818            String path, ParcelFileDescriptor fd) throws RemoteException {
19819
19820        try {
19821            synchronized (this) {
19822                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19823                // its own permission (same as profileControl).
19824                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19825                        != PackageManager.PERMISSION_GRANTED) {
19826                    throw new SecurityException("Requires permission "
19827                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19828                }
19829
19830                if (fd == null) {
19831                    throw new IllegalArgumentException("null fd");
19832                }
19833
19834                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19835                if (proc == null || proc.thread == null) {
19836                    throw new IllegalArgumentException("Unknown process: " + process);
19837                }
19838
19839                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19840                if (!isDebuggable) {
19841                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19842                        throw new SecurityException("Process not debuggable: " + proc);
19843                    }
19844                }
19845
19846                proc.thread.dumpHeap(managed, path, fd);
19847                fd = null;
19848                return true;
19849            }
19850        } catch (RemoteException e) {
19851            throw new IllegalStateException("Process disappeared");
19852        } finally {
19853            if (fd != null) {
19854                try {
19855                    fd.close();
19856                } catch (IOException e) {
19857                }
19858            }
19859        }
19860    }
19861
19862    @Override
19863    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19864            String reportPackage) {
19865        if (processName != null) {
19866            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19867                    "setDumpHeapDebugLimit()");
19868        } else {
19869            synchronized (mPidsSelfLocked) {
19870                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19871                if (proc == null) {
19872                    throw new SecurityException("No process found for calling pid "
19873                            + Binder.getCallingPid());
19874                }
19875                if (!Build.IS_DEBUGGABLE
19876                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19877                    throw new SecurityException("Not running a debuggable build");
19878                }
19879                processName = proc.processName;
19880                uid = proc.uid;
19881                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19882                    throw new SecurityException("Package " + reportPackage + " is not running in "
19883                            + proc);
19884                }
19885            }
19886        }
19887        synchronized (this) {
19888            if (maxMemSize > 0) {
19889                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19890            } else {
19891                if (uid != 0) {
19892                    mMemWatchProcesses.remove(processName, uid);
19893                } else {
19894                    mMemWatchProcesses.getMap().remove(processName);
19895                }
19896            }
19897        }
19898    }
19899
19900    @Override
19901    public void dumpHeapFinished(String path) {
19902        synchronized (this) {
19903            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19904                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19905                        + " does not match last pid " + mMemWatchDumpPid);
19906                return;
19907            }
19908            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19909                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19910                        + " does not match last path " + mMemWatchDumpFile);
19911                return;
19912            }
19913            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19914            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19915        }
19916    }
19917
19918    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19919    public void monitor() {
19920        synchronized (this) { }
19921    }
19922
19923    void onCoreSettingsChange(Bundle settings) {
19924        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19925            ProcessRecord processRecord = mLruProcesses.get(i);
19926            try {
19927                if (processRecord.thread != null) {
19928                    processRecord.thread.setCoreSettings(settings);
19929                }
19930            } catch (RemoteException re) {
19931                /* ignore */
19932            }
19933        }
19934    }
19935
19936    // Multi-user methods
19937
19938    /**
19939     * Start user, if its not already running, but don't bring it to foreground.
19940     */
19941    @Override
19942    public boolean startUserInBackground(final int userId) {
19943        return mUserController.startUser(userId, /* foreground */ false);
19944    }
19945
19946    @Override
19947    public boolean switchUser(final int userId) {
19948        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19949        String userName;
19950        synchronized (this) {
19951            UserInfo userInfo = mUserController.getUserInfo(userId);
19952            if (userInfo == null) {
19953                Slog.w(TAG, "No user info for user #" + userId);
19954                return false;
19955            }
19956            if (userInfo.isManagedProfile()) {
19957                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19958                return false;
19959            }
19960            userName = userInfo.name;
19961            mUserController.setTargetUserIdLocked(userId);
19962        }
19963        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19964        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19965        return true;
19966    }
19967
19968    void scheduleStartProfilesLocked() {
19969        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19970            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19971                    DateUtils.SECOND_IN_MILLIS);
19972        }
19973    }
19974
19975    @Override
19976    public int stopUser(final int userId, final IStopUserCallback callback) {
19977        return mUserController.stopUser(userId, callback);
19978    }
19979
19980    void onUserRemovedLocked(int userId) {
19981        mRecentTasks.removeTasksForUserLocked(userId);
19982    }
19983
19984    @Override
19985    public UserInfo getCurrentUser() {
19986        return mUserController.getCurrentUser();
19987    }
19988
19989    @Override
19990    public boolean isUserRunning(int userId, boolean orStopped) {
19991        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19992                != PackageManager.PERMISSION_GRANTED) {
19993            String msg = "Permission Denial: isUserRunning() from pid="
19994                    + Binder.getCallingPid()
19995                    + ", uid=" + Binder.getCallingUid()
19996                    + " requires " + INTERACT_ACROSS_USERS;
19997            Slog.w(TAG, msg);
19998            throw new SecurityException(msg);
19999        }
20000        synchronized (this) {
20001            return mUserController.isUserRunningLocked(userId, orStopped);
20002        }
20003    }
20004
20005    @Override
20006    public int[] getRunningUserIds() {
20007        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20008                != PackageManager.PERMISSION_GRANTED) {
20009            String msg = "Permission Denial: isUserRunning() from pid="
20010                    + Binder.getCallingPid()
20011                    + ", uid=" + Binder.getCallingUid()
20012                    + " requires " + INTERACT_ACROSS_USERS;
20013            Slog.w(TAG, msg);
20014            throw new SecurityException(msg);
20015        }
20016        synchronized (this) {
20017            return mUserController.getStartedUserArrayLocked();
20018        }
20019    }
20020
20021    @Override
20022    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20023        mUserController.registerUserSwitchObserver(observer);
20024    }
20025
20026    @Override
20027    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20028        mUserController.unregisterUserSwitchObserver(observer);
20029    }
20030
20031    private int applyUserId(int uid, int userId) {
20032        return UserHandle.getUid(userId, uid);
20033    }
20034
20035    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20036        if (info == null) return null;
20037        ApplicationInfo newInfo = new ApplicationInfo(info);
20038        newInfo.uid = applyUserId(info.uid, userId);
20039        newInfo.dataDir = Environment
20040                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20041                .getAbsolutePath();
20042        return newInfo;
20043    }
20044
20045    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20046        if (aInfo == null
20047                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20048            return aInfo;
20049        }
20050
20051        ActivityInfo info = new ActivityInfo(aInfo);
20052        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20053        return info;
20054    }
20055
20056    private boolean processSanityChecksLocked(ProcessRecord process) {
20057        if (process == null || process.thread == null) {
20058            return false;
20059        }
20060
20061        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20062        if (!isDebuggable) {
20063            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20064                return false;
20065            }
20066        }
20067
20068        return true;
20069    }
20070
20071    public boolean startBinderTracking() throws RemoteException {
20072        synchronized (this) {
20073            mBinderTransactionTrackingEnabled = true;
20074            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20075            // permission (same as profileControl).
20076            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20077                    != PackageManager.PERMISSION_GRANTED) {
20078                throw new SecurityException("Requires permission "
20079                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20080            }
20081
20082            for (int i = 0; i < mLruProcesses.size(); i++) {
20083                ProcessRecord process = mLruProcesses.get(i);
20084                if (!processSanityChecksLocked(process)) {
20085                    continue;
20086                }
20087                try {
20088                    process.thread.startBinderTracking();
20089                } catch (RemoteException e) {
20090                    Log.v(TAG, "Process disappared");
20091                }
20092            }
20093            return true;
20094        }
20095    }
20096
20097    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20098        try {
20099            synchronized (this) {
20100                mBinderTransactionTrackingEnabled = false;
20101                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20102                // permission (same as profileControl).
20103                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20104                        != PackageManager.PERMISSION_GRANTED) {
20105                    throw new SecurityException("Requires permission "
20106                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20107                }
20108
20109                if (fd == null) {
20110                    throw new IllegalArgumentException("null fd");
20111                }
20112
20113                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20114                pw.println("Binder transaction traces for all processes.\n");
20115                for (ProcessRecord process : mLruProcesses) {
20116                    if (!processSanityChecksLocked(process)) {
20117                        continue;
20118                    }
20119
20120                    pw.println("Traces for process: " + process.processName);
20121                    pw.flush();
20122                    try {
20123                        TransferPipe tp = new TransferPipe();
20124                        try {
20125                            process.thread.stopBinderTrackingAndDump(
20126                                    tp.getWriteFd().getFileDescriptor());
20127                            tp.go(fd.getFileDescriptor());
20128                        } finally {
20129                            tp.kill();
20130                        }
20131                    } catch (IOException e) {
20132                        pw.println("Failure while dumping IPC traces from " + process +
20133                                ".  Exception: " + e);
20134                        pw.flush();
20135                    } catch (RemoteException e) {
20136                        pw.println("Got a RemoteException while dumping IPC traces from " +
20137                                process + ".  Exception: " + e);
20138                        pw.flush();
20139                    }
20140                }
20141                fd = null;
20142                return true;
20143            }
20144        } finally {
20145            if (fd != null) {
20146                try {
20147                    fd.close();
20148                } catch (IOException e) {
20149                }
20150            }
20151        }
20152    }
20153
20154    void stopReportingCrashesLocked(ProcessRecord proc) {
20155        if (mAppsNotReportingCrashes == null) {
20156            mAppsNotReportingCrashes = new ArraySet<>();
20157        }
20158        mAppsNotReportingCrashes.add(proc.info.packageName);
20159    }
20160
20161    private final class LocalService extends ActivityManagerInternal {
20162        @Override
20163        public void onWakefulnessChanged(int wakefulness) {
20164            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20165        }
20166
20167        @Override
20168        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20169                String processName, String abiOverride, int uid, Runnable crashHandler) {
20170            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20171                    processName, abiOverride, uid, crashHandler);
20172        }
20173
20174        @Override
20175        public SleepToken acquireSleepToken(String tag) {
20176            Preconditions.checkNotNull(tag);
20177
20178            synchronized (ActivityManagerService.this) {
20179                SleepTokenImpl token = new SleepTokenImpl(tag);
20180                mSleepTokens.add(token);
20181                updateSleepIfNeededLocked();
20182                return token;
20183            }
20184        }
20185
20186        @Override
20187        public ComponentName getHomeActivityForUser(int userId) {
20188            synchronized (ActivityManagerService.this) {
20189                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20190                return homeActivity == null ? null : homeActivity.realActivity;
20191            }
20192        }
20193
20194        @Override
20195        public void onUserRemoved(int userId) {
20196            synchronized (ActivityManagerService.this) {
20197                ActivityManagerService.this.onUserRemovedLocked(userId);
20198            }
20199        }
20200    }
20201
20202    private final class SleepTokenImpl extends SleepToken {
20203        private final String mTag;
20204        private final long mAcquireTime;
20205
20206        public SleepTokenImpl(String tag) {
20207            mTag = tag;
20208            mAcquireTime = SystemClock.uptimeMillis();
20209        }
20210
20211        @Override
20212        public void release() {
20213            synchronized (ActivityManagerService.this) {
20214                if (mSleepTokens.remove(this)) {
20215                    updateSleepIfNeededLocked();
20216                }
20217            }
20218        }
20219
20220        @Override
20221        public String toString() {
20222            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20223        }
20224    }
20225
20226    /**
20227     * An implementation of IAppTask, that allows an app to manage its own tasks via
20228     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20229     * only the process that calls getAppTasks() can call the AppTask methods.
20230     */
20231    class AppTaskImpl extends IAppTask.Stub {
20232        private int mTaskId;
20233        private int mCallingUid;
20234
20235        public AppTaskImpl(int taskId, int callingUid) {
20236            mTaskId = taskId;
20237            mCallingUid = callingUid;
20238        }
20239
20240        private void checkCaller() {
20241            if (mCallingUid != Binder.getCallingUid()) {
20242                throw new SecurityException("Caller " + mCallingUid
20243                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20244            }
20245        }
20246
20247        @Override
20248        public void finishAndRemoveTask() {
20249            checkCaller();
20250
20251            synchronized (ActivityManagerService.this) {
20252                long origId = Binder.clearCallingIdentity();
20253                try {
20254                    // We remove the task from recents to preserve backwards
20255                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20256                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20257                    }
20258                } finally {
20259                    Binder.restoreCallingIdentity(origId);
20260                }
20261            }
20262        }
20263
20264        @Override
20265        public ActivityManager.RecentTaskInfo getTaskInfo() {
20266            checkCaller();
20267
20268            synchronized (ActivityManagerService.this) {
20269                long origId = Binder.clearCallingIdentity();
20270                try {
20271                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20272                    if (tr == null) {
20273                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20274                    }
20275                    return createRecentTaskInfoFromTaskRecord(tr);
20276                } finally {
20277                    Binder.restoreCallingIdentity(origId);
20278                }
20279            }
20280        }
20281
20282        @Override
20283        public void moveToFront() {
20284            checkCaller();
20285            // Will bring task to front if it already has a root activity.
20286            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20287        }
20288
20289        @Override
20290        public int startActivity(IBinder whoThread, String callingPackage,
20291                Intent intent, String resolvedType, Bundle bOptions) {
20292            checkCaller();
20293
20294            int callingUser = UserHandle.getCallingUserId();
20295            TaskRecord tr;
20296            IApplicationThread appThread;
20297            synchronized (ActivityManagerService.this) {
20298                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20299                if (tr == null) {
20300                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20301                }
20302                appThread = ApplicationThreadNative.asInterface(whoThread);
20303                if (appThread == null) {
20304                    throw new IllegalArgumentException("Bad app thread " + appThread);
20305                }
20306            }
20307            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20308                    resolvedType, null, null, null, null, 0, 0, null, null,
20309                    null, bOptions, false, callingUser, null, tr);
20310        }
20311
20312        @Override
20313        public void setExcludeFromRecents(boolean exclude) {
20314            checkCaller();
20315
20316            synchronized (ActivityManagerService.this) {
20317                long origId = Binder.clearCallingIdentity();
20318                try {
20319                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20320                    if (tr == null) {
20321                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20322                    }
20323                    Intent intent = tr.getBaseIntent();
20324                    if (exclude) {
20325                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20326                    } else {
20327                        intent.setFlags(intent.getFlags()
20328                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20329                    }
20330                } finally {
20331                    Binder.restoreCallingIdentity(origId);
20332                }
20333            }
20334        }
20335    }
20336}
20337