ActivityManagerService.java revision bef28feba57be7fd6a4d14a85a8229154338b2ed
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.PermissionInfo;
64import android.content.res.Resources;
65import android.graphics.Bitmap;
66import android.graphics.Point;
67import android.graphics.Rect;
68import android.os.BatteryStats;
69import android.os.PersistableBundle;
70import android.os.PowerManager;
71import android.os.ResultReceiver;
72import android.os.Trace;
73import android.os.TransactionTooLargeException;
74import android.os.WorkSource;
75import android.os.storage.IMountService;
76import android.os.storage.MountServiceInternal;
77import android.os.storage.StorageManager;
78import android.provider.Settings.Global;
79import android.service.voice.IVoiceInteractionSession;
80import android.service.voice.VoiceInteractionSession;
81import android.util.ArrayMap;
82import android.util.ArraySet;
83import android.util.DebugUtils;
84import android.view.Display;
85
86import com.android.internal.R;
87import com.android.internal.annotations.GuardedBy;
88import com.android.internal.app.AssistUtils;
89import com.android.internal.app.DumpHeapActivity;
90import com.android.internal.app.IAppOpsCallback;
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.SystemService;
113import com.android.server.SystemServiceManager;
114import com.android.server.Watchdog;
115import com.android.server.am.ActivityStack.ActivityState;
116import com.android.server.firewall.IntentFirewall;
117import com.android.server.pm.Installer;
118import com.android.server.statusbar.StatusBarManagerInternal;
119import com.android.server.wm.AppTransition;
120import com.android.server.wm.WindowManagerService;
121import com.google.android.collect.Lists;
122import com.google.android.collect.Maps;
123
124import libcore.io.IoUtils;
125import libcore.util.EmptyArray;
126
127import org.xmlpull.v1.XmlPullParser;
128import org.xmlpull.v1.XmlPullParserException;
129import org.xmlpull.v1.XmlSerializer;
130
131import android.app.Activity;
132import android.app.ActivityManager;
133import android.app.ActivityManager.RunningTaskInfo;
134import android.app.ActivityManager.StackInfo;
135import android.app.ActivityManager.TaskThumbnailInfo;
136import android.app.ActivityManagerInternal;
137import android.app.ActivityManagerInternal.SleepToken;
138import android.app.ActivityManagerNative;
139import android.app.ActivityOptions;
140import android.app.ActivityThread;
141import android.app.AlertDialog;
142import android.app.AppGlobals;
143import android.app.ApplicationErrorReport;
144import android.app.Dialog;
145import android.app.IActivityController;
146import android.app.IApplicationThread;
147import android.app.IInstrumentationWatcher;
148import android.app.INotificationManager;
149import android.app.IProcessObserver;
150import android.app.IServiceConnection;
151import android.app.IStopUserCallback;
152import android.app.IUidObserver;
153import android.app.IUiAutomationConnection;
154import android.app.IUserSwitchObserver;
155import android.app.Instrumentation;
156import android.app.Notification;
157import android.app.NotificationManager;
158import android.app.PendingIntent;
159import android.app.backup.IBackupManager;
160import android.app.admin.DevicePolicyManager;
161import android.content.ActivityNotFoundException;
162import android.content.BroadcastReceiver;
163import android.content.ClipData;
164import android.content.ComponentCallbacks2;
165import android.content.ComponentName;
166import android.content.ContentProvider;
167import android.content.ContentResolver;
168import android.content.Context;
169import android.content.DialogInterface;
170import android.content.IContentProvider;
171import android.content.IIntentReceiver;
172import android.content.IIntentSender;
173import android.content.Intent;
174import android.content.IntentFilter;
175import android.content.IntentSender;
176import android.content.pm.ActivityInfo;
177import android.content.pm.ApplicationInfo;
178import android.content.pm.ConfigurationInfo;
179import android.content.pm.IPackageDataObserver;
180import android.content.pm.IPackageManager;
181import android.content.pm.InstrumentationInfo;
182import android.content.pm.PackageInfo;
183import android.content.pm.PackageManager;
184import android.content.pm.ParceledListSlice;
185import android.content.pm.UserInfo;
186import android.content.pm.PackageManager.NameNotFoundException;
187import android.content.pm.PathPermission;
188import android.content.pm.ProviderInfo;
189import android.content.pm.ResolveInfo;
190import android.content.pm.ServiceInfo;
191import android.content.res.CompatibilityInfo;
192import android.content.res.Configuration;
193import android.net.Proxy;
194import android.net.ProxyInfo;
195import android.net.Uri;
196import android.os.Binder;
197import android.os.Build;
198import android.os.Bundle;
199import android.os.Debug;
200import android.os.DropBoxManager;
201import android.os.Environment;
202import android.os.FactoryTest;
203import android.os.FileObserver;
204import android.os.FileUtils;
205import android.os.Handler;
206import android.os.IBinder;
207import android.os.IPermissionController;
208import android.os.IProcessInfoService;
209import android.os.Looper;
210import android.os.Message;
211import android.os.Parcel;
212import android.os.ParcelFileDescriptor;
213import android.os.PowerManagerInternal;
214import android.os.Process;
215import android.os.RemoteCallbackList;
216import android.os.RemoteException;
217import android.os.ServiceManager;
218import android.os.StrictMode;
219import android.os.SystemClock;
220import android.os.SystemProperties;
221import android.os.UpdateLock;
222import android.os.UserHandle;
223import android.os.UserManager;
224import android.provider.Settings;
225import android.text.format.DateUtils;
226import android.text.format.Time;
227import android.util.AtomicFile;
228import android.util.EventLog;
229import android.util.Log;
230import android.util.Pair;
231import android.util.PrintWriterPrinter;
232import android.util.Slog;
233import android.util.SparseArray;
234import android.util.TimeUtils;
235import android.util.Xml;
236import android.view.Gravity;
237import android.view.LayoutInflater;
238import android.view.View;
239import android.view.WindowManager;
240
241import dalvik.system.VMRuntime;
242
243import java.io.BufferedInputStream;
244import java.io.BufferedOutputStream;
245import java.io.DataInputStream;
246import java.io.DataOutputStream;
247import java.io.File;
248import java.io.FileDescriptor;
249import java.io.FileInputStream;
250import java.io.FileNotFoundException;
251import java.io.FileOutputStream;
252import java.io.IOException;
253import java.io.InputStreamReader;
254import java.io.PrintWriter;
255import java.io.StringWriter;
256import java.lang.ref.WeakReference;
257import java.nio.charset.StandardCharsets;
258import java.util.ArrayList;
259import java.util.Arrays;
260import java.util.Collections;
261import java.util.Comparator;
262import java.util.HashMap;
263import java.util.HashSet;
264import java.util.Iterator;
265import java.util.List;
266import java.util.Locale;
267import java.util.Map;
268import java.util.Set;
269import java.util.concurrent.atomic.AtomicBoolean;
270import java.util.concurrent.atomic.AtomicLong;
271
272public final class ActivityManagerService extends ActivityManagerNative
273        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
274
275    // File that stores last updated system version and called preboot receivers
276    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
277
278    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
279    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
280    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
281    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
282    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
283    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
284    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
285    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
286    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
287    private static final String TAG_LRU = TAG + POSTFIX_LRU;
288    private static final String TAG_MU = TAG + POSTFIX_MU;
289    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
290    private static final String TAG_POWER = TAG + POSTFIX_POWER;
291    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
292    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
293    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
294    private static final String TAG_PSS = TAG + POSTFIX_PSS;
295    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
296    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
297    private static final String TAG_STACK = TAG + POSTFIX_STACK;
298    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
299    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
300    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
301    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
302    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
303
304    /** Control over CPU and battery monitoring */
305    // write battery stats every 30 minutes.
306    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
307    static final boolean MONITOR_CPU_USAGE = true;
308    // don't sample cpu less than every 5 seconds.
309    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
310    // wait possibly forever for next cpu sample.
311    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
312    static final boolean MONITOR_THREAD_CPU_USAGE = false;
313
314    // The flags that are set for all calls we make to the package manager.
315    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
316
317    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
318
319    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
320
321    // Amount of time after a call to stopAppSwitches() during which we will
322    // prevent further untrusted switches from happening.
323    static final long APP_SWITCH_DELAY_TIME = 5*1000;
324
325    // How long we wait for a launched process to attach to the activity manager
326    // before we decide it's never going to come up for real.
327    static final int PROC_START_TIMEOUT = 10*1000;
328    // How long we wait for an attached process to publish its content providers
329    // before we decide it must be hung.
330    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
331
332    // How long we will retain processes hosting content providers in the "last activity"
333    // state before allowing them to drop down to the regular cached LRU list.  This is
334    // to avoid thrashing of provider processes under low memory situations.
335    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
336
337    // How long we wait for a launched process to attach to the activity manager
338    // before we decide it's never going to come up for real, when the process was
339    // started with a wrapper for instrumentation (such as Valgrind) because it
340    // could take much longer than usual.
341    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
342
343    // How long to wait after going idle before forcing apps to GC.
344    static final int GC_TIMEOUT = 5*1000;
345
346    // The minimum amount of time between successive GC requests for a process.
347    static final int GC_MIN_INTERVAL = 60*1000;
348
349    // The minimum amount of time between successive PSS requests for a process.
350    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
351
352    // The minimum amount of time between successive PSS requests for a process
353    // when the request is due to the memory state being lowered.
354    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
355
356    // The rate at which we check for apps using excessive power -- 15 mins.
357    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
358
359    // The minimum sample duration we will allow before deciding we have
360    // enough data on wake locks to start killing things.
361    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
362
363    // The minimum sample duration we will allow before deciding we have
364    // enough data on CPU usage to start killing things.
365    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
366
367    // How long we allow a receiver to run before giving up on it.
368    static final int BROADCAST_FG_TIMEOUT = 10*1000;
369    static final int BROADCAST_BG_TIMEOUT = 60*1000;
370
371    // How long we wait until we timeout on key dispatching.
372    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
373
374    // How long we wait until we timeout on key dispatching during instrumentation.
375    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
376
377    // This is the amount of time an app needs to be running a foreground service before
378    // we will consider it to be doing interaction for usage stats.
379    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
380
381    // Maximum amount of time we will allow to elapse before re-reporting usage stats
382    // interaction with foreground processes.
383    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
384
385    // Maximum number of users we allow to be running at a time.
386    static final int MAX_RUNNING_USERS = 3;
387
388    // This is the amount of time we allow an app to settle after it goes into the background,
389    // before we start restricting what it can do.
390    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
391
392    // How long to wait in getAssistContextExtras for the activity and foreground services
393    // to respond with the result.
394    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
395
396    // How long top wait when going through the modern assist (which doesn't need to block
397    // on getting this result before starting to launch its UI).
398    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
399
400    // Maximum number of persisted Uri grants a package is allowed
401    static final int MAX_PERSISTED_URI_GRANTS = 128;
402
403    static final int MY_PID = Process.myPid();
404
405    static final String[] EMPTY_STRING_ARRAY = new String[0];
406
407    // How many bytes to write into the dropbox log before truncating
408    static final int DROPBOX_MAX_SIZE = 256 * 1024;
409
410    // Access modes for handleIncomingUser.
411    static final int ALLOW_NON_FULL = 0;
412    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
413    static final int ALLOW_FULL_ONLY = 2;
414
415    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
416
417    // Delay in notifying task stack change listeners (in millis)
418    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
419
420    // Necessary ApplicationInfo flags to mark an app as persistent
421    private static final int PERSISTENT_MASK =
422            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
423
424
425    // Delay to disable app launch boost
426    static final int APP_BOOST_MESSAGE_DELAY = 3000;
427    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
428    static final int APP_BOOST_TIMEOUT = 2500;
429
430    // Used to indicate that a task is removed it should also be removed from recents.
431    private static final boolean REMOVE_FROM_RECENTS = true;
432
433    private static native int nativeMigrateToBoost();
434    private static native int nativeMigrateFromBoost();
435    private boolean mIsBoosted = false;
436    private long mBoostStartTime = 0;
437
438    /** All system services */
439    SystemServiceManager mSystemServiceManager;
440
441    private Installer mInstaller;
442
443    /** Run all ActivityStacks through this */
444    ActivityStackSupervisor mStackSupervisor;
445
446    /** Task stack change listeners. */
447    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
448            new RemoteCallbackList<ITaskStackListener>();
449
450    public IntentFirewall mIntentFirewall;
451
452    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
453    // default actuion automatically.  Important for devices without direct input
454    // devices.
455    private boolean mShowDialogs = true;
456
457    BroadcastQueue mFgBroadcastQueue;
458    BroadcastQueue mBgBroadcastQueue;
459    // Convenient for easy iteration over the queues. Foreground is first
460    // so that dispatch of foreground broadcasts gets precedence.
461    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
462
463    BroadcastQueue broadcastQueueForIntent(Intent intent) {
464        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
465        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
466                "Broadcast intent " + intent + " on "
467                + (isFg ? "foreground" : "background") + " queue");
468        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
469    }
470
471    /**
472     * Activity we have told the window manager to have key focus.
473     */
474    ActivityRecord mFocusedActivity = null;
475
476    /**
477     * User id of the last activity mFocusedActivity was set to.
478     */
479    private int mLastFocusedUserId;
480
481    /**
482     * If non-null, we are tracking the time the user spends in the currently focused app.
483     */
484    private AppTimeTracker mCurAppTimeTracker;
485
486    /**
487     * List of intents that were used to start the most recent tasks.
488     */
489    private final RecentTasks mRecentTasks;
490
491    /**
492     * For addAppTask: cached of the last activity component that was added.
493     */
494    ComponentName mLastAddedTaskComponent;
495
496    /**
497     * For addAppTask: cached of the last activity uid that was added.
498     */
499    int mLastAddedTaskUid;
500
501    /**
502     * For addAppTask: cached of the last ActivityInfo that was added.
503     */
504    ActivityInfo mLastAddedTaskActivity;
505
506    /**
507     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
508     */
509    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
510
511    /**
512     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
513     */
514    String mDeviceOwnerName;
515
516    final UserController mUserController;
517
518    public class PendingAssistExtras extends Binder implements Runnable {
519        public final ActivityRecord activity;
520        public final Bundle extras;
521        public final Intent intent;
522        public final String hint;
523        public final IResultReceiver receiver;
524        public final int userHandle;
525        public boolean haveResult = false;
526        public Bundle result = null;
527        public AssistStructure structure = null;
528        public AssistContent content = null;
529        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
530                String _hint, IResultReceiver _receiver, int _userHandle) {
531            activity = _activity;
532            extras = _extras;
533            intent = _intent;
534            hint = _hint;
535            receiver = _receiver;
536            userHandle = _userHandle;
537        }
538        @Override
539        public void run() {
540            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
541            synchronized (this) {
542                haveResult = true;
543                notifyAll();
544            }
545            pendingAssistExtrasTimedOut(this);
546        }
547    }
548
549    final ArrayList<PendingAssistExtras> mPendingAssistExtras
550            = new ArrayList<PendingAssistExtras>();
551
552    /**
553     * Process management.
554     */
555    final ProcessList mProcessList = new ProcessList();
556
557    /**
558     * All of the applications we currently have running organized by name.
559     * The keys are strings of the application package name (as
560     * returned by the package manager), and the keys are ApplicationRecord
561     * objects.
562     */
563    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
564
565    /**
566     * Tracking long-term execution of processes to look for abuse and other
567     * bad app behavior.
568     */
569    final ProcessStatsService mProcessStats;
570
571    /**
572     * The currently running isolated processes.
573     */
574    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
575
576    /**
577     * Counter for assigning isolated process uids, to avoid frequently reusing the
578     * same ones.
579     */
580    int mNextIsolatedProcessUid = 0;
581
582    /**
583     * The currently running heavy-weight process, if any.
584     */
585    ProcessRecord mHeavyWeightProcess = null;
586
587    /**
588     * The last time that various processes have crashed.
589     */
590    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
591
592    /**
593     * Information about a process that is currently marked as bad.
594     */
595    static final class BadProcessInfo {
596        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
597            this.time = time;
598            this.shortMsg = shortMsg;
599            this.longMsg = longMsg;
600            this.stack = stack;
601        }
602
603        final long time;
604        final String shortMsg;
605        final String longMsg;
606        final String stack;
607    }
608
609    /**
610     * Set of applications that we consider to be bad, and will reject
611     * incoming broadcasts from (which the user has no control over).
612     * Processes are added to this set when they have crashed twice within
613     * a minimum amount of time; they are removed from it when they are
614     * later restarted (hopefully due to some user action).  The value is the
615     * time it was added to the list.
616     */
617    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
618
619    /**
620     * All of the processes we currently have running organized by pid.
621     * The keys are the pid running the application.
622     *
623     * <p>NOTE: This object is protected by its own lock, NOT the global
624     * activity manager lock!
625     */
626    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
627
628    /**
629     * All of the processes that have been forced to be foreground.  The key
630     * is the pid of the caller who requested it (we hold a death
631     * link on it).
632     */
633    abstract class ForegroundToken implements IBinder.DeathRecipient {
634        int pid;
635        IBinder token;
636    }
637    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
638
639    /**
640     * List of records for processes that someone had tried to start before the
641     * system was ready.  We don't start them at that point, but ensure they
642     * are started by the time booting is complete.
643     */
644    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
645
646    /**
647     * List of persistent applications that are in the process
648     * of being started.
649     */
650    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
651
652    /**
653     * Processes that are being forcibly torn down.
654     */
655    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
656
657    /**
658     * List of running applications, sorted by recent usage.
659     * The first entry in the list is the least recently used.
660     */
661    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
662
663    /**
664     * Where in mLruProcesses that the processes hosting activities start.
665     */
666    int mLruProcessActivityStart = 0;
667
668    /**
669     * Where in mLruProcesses that the processes hosting services start.
670     * This is after (lower index) than mLruProcessesActivityStart.
671     */
672    int mLruProcessServiceStart = 0;
673
674    /**
675     * List of processes that should gc as soon as things are idle.
676     */
677    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
678
679    /**
680     * Processes we want to collect PSS data from.
681     */
682    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
683
684    private boolean mBinderTransactionTrackingEnabled = false;
685
686    /**
687     * Last time we requested PSS data of all processes.
688     */
689    long mLastFullPssTime = SystemClock.uptimeMillis();
690
691    /**
692     * If set, the next time we collect PSS data we should do a full collection
693     * with data from native processes and the kernel.
694     */
695    boolean mFullPssPending = false;
696
697    /**
698     * This is the process holding what we currently consider to be
699     * the "home" activity.
700     */
701    ProcessRecord mHomeProcess;
702
703    /**
704     * This is the process holding the activity the user last visited that
705     * is in a different process from the one they are currently in.
706     */
707    ProcessRecord mPreviousProcess;
708
709    /**
710     * The time at which the previous process was last visible.
711     */
712    long mPreviousProcessVisibleTime;
713
714    /**
715     * Track all uids that have actively running processes.
716     */
717    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
718
719    /**
720     * This is for verifying the UID report flow.
721     */
722    static final boolean VALIDATE_UID_STATES = true;
723    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
724
725    /**
726     * Packages that the user has asked to have run in screen size
727     * compatibility mode instead of filling the screen.
728     */
729    final CompatModePackages mCompatModePackages;
730
731    /**
732     * Set of IntentSenderRecord objects that are currently active.
733     */
734    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
735            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
736
737    /**
738     * Fingerprints (hashCode()) of stack traces that we've
739     * already logged DropBox entries for.  Guarded by itself.  If
740     * something (rogue user app) forces this over
741     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
742     */
743    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
744    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
745
746    /**
747     * Strict Mode background batched logging state.
748     *
749     * The string buffer is guarded by itself, and its lock is also
750     * used to determine if another batched write is already
751     * in-flight.
752     */
753    private final StringBuilder mStrictModeBuffer = new StringBuilder();
754
755    /**
756     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
757     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
758     */
759    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
760
761    /**
762     * Resolver for broadcast intents to registered receivers.
763     * Holds BroadcastFilter (subclass of IntentFilter).
764     */
765    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
766            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
767        @Override
768        protected boolean allowFilterResult(
769                BroadcastFilter filter, List<BroadcastFilter> dest) {
770            IBinder target = filter.receiverList.receiver.asBinder();
771            for (int i = dest.size() - 1; i >= 0; i--) {
772                if (dest.get(i).receiverList.receiver.asBinder() == target) {
773                    return false;
774                }
775            }
776            return true;
777        }
778
779        @Override
780        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
781            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
782                    || userId == filter.owningUserId) {
783                return super.newResult(filter, match, userId);
784            }
785            return null;
786        }
787
788        @Override
789        protected BroadcastFilter[] newArray(int size) {
790            return new BroadcastFilter[size];
791        }
792
793        @Override
794        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
795            return packageName.equals(filter.packageName);
796        }
797    };
798
799    /**
800     * State of all active sticky broadcasts per user.  Keys are the action of the
801     * sticky Intent, values are an ArrayList of all broadcasted intents with
802     * that action (which should usually be one).  The SparseArray is keyed
803     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
804     * for stickies that are sent to all users.
805     */
806    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
807            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
808
809    final ActiveServices mServices;
810
811    final static class Association {
812        final int mSourceUid;
813        final String mSourceProcess;
814        final int mTargetUid;
815        final ComponentName mTargetComponent;
816        final String mTargetProcess;
817
818        int mCount;
819        long mTime;
820
821        int mNesting;
822        long mStartTime;
823
824        Association(int sourceUid, String sourceProcess, int targetUid,
825                ComponentName targetComponent, String targetProcess) {
826            mSourceUid = sourceUid;
827            mSourceProcess = sourceProcess;
828            mTargetUid = targetUid;
829            mTargetComponent = targetComponent;
830            mTargetProcess = targetProcess;
831        }
832    }
833
834    /**
835     * When service association tracking is enabled, this is all of the associations we
836     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
837     * -> association data.
838     */
839    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
840            mAssociations = new SparseArray<>();
841    boolean mTrackingAssociations;
842
843    /**
844     * Backup/restore process management
845     */
846    String mBackupAppName = null;
847    BackupRecord mBackupTarget = null;
848
849    final ProviderMap mProviderMap;
850
851    /**
852     * List of content providers who have clients waiting for them.  The
853     * application is currently being launched and the provider will be
854     * removed from this list once it is published.
855     */
856    final ArrayList<ContentProviderRecord> mLaunchingProviders
857            = new ArrayList<ContentProviderRecord>();
858
859    /**
860     * File storing persisted {@link #mGrantedUriPermissions}.
861     */
862    private final AtomicFile mGrantFile;
863
864    /** XML constants used in {@link #mGrantFile} */
865    private static final String TAG_URI_GRANTS = "uri-grants";
866    private static final String TAG_URI_GRANT = "uri-grant";
867    private static final String ATTR_USER_HANDLE = "userHandle";
868    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
869    private static final String ATTR_TARGET_USER_ID = "targetUserId";
870    private static final String ATTR_SOURCE_PKG = "sourcePkg";
871    private static final String ATTR_TARGET_PKG = "targetPkg";
872    private static final String ATTR_URI = "uri";
873    private static final String ATTR_MODE_FLAGS = "modeFlags";
874    private static final String ATTR_CREATED_TIME = "createdTime";
875    private static final String ATTR_PREFIX = "prefix";
876
877    /**
878     * Global set of specific {@link Uri} permissions that have been granted.
879     * This optimized lookup structure maps from {@link UriPermission#targetUid}
880     * to {@link UriPermission#uri} to {@link UriPermission}.
881     */
882    @GuardedBy("this")
883    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
884            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
885
886    public static class GrantUri {
887        public final int sourceUserId;
888        public final Uri uri;
889        public boolean prefix;
890
891        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
892            this.sourceUserId = sourceUserId;
893            this.uri = uri;
894            this.prefix = prefix;
895        }
896
897        @Override
898        public int hashCode() {
899            int hashCode = 1;
900            hashCode = 31 * hashCode + sourceUserId;
901            hashCode = 31 * hashCode + uri.hashCode();
902            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
903            return hashCode;
904        }
905
906        @Override
907        public boolean equals(Object o) {
908            if (o instanceof GrantUri) {
909                GrantUri other = (GrantUri) o;
910                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
911                        && prefix == other.prefix;
912            }
913            return false;
914        }
915
916        @Override
917        public String toString() {
918            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
919            if (prefix) result += " [prefix]";
920            return result;
921        }
922
923        public String toSafeString() {
924            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
925            if (prefix) result += " [prefix]";
926            return result;
927        }
928
929        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
930            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
931                    ContentProvider.getUriWithoutUserId(uri), false);
932        }
933    }
934
935    CoreSettingsObserver mCoreSettingsObserver;
936
937    /**
938     * Thread-local storage used to carry caller permissions over through
939     * indirect content-provider access.
940     */
941    private class Identity {
942        public final IBinder token;
943        public final int pid;
944        public final int uid;
945
946        Identity(IBinder _token, int _pid, int _uid) {
947            token = _token;
948            pid = _pid;
949            uid = _uid;
950        }
951    }
952
953    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
954
955    /**
956     * All information we have collected about the runtime performance of
957     * any user id that can impact battery performance.
958     */
959    final BatteryStatsService mBatteryStatsService;
960
961    /**
962     * Information about component usage
963     */
964    UsageStatsManagerInternal mUsageStatsService;
965
966    /**
967     * Access to DeviceIdleController service.
968     */
969    DeviceIdleController.LocalService mLocalDeviceIdleController;
970
971    /**
972     * Information about and control over application operations
973     */
974    final AppOpsService mAppOpsService;
975
976    /**
977     * Save recent tasks information across reboots.
978     */
979    final TaskPersister mTaskPersister;
980
981    /**
982     * Current configuration information.  HistoryRecord objects are given
983     * a reference to this object to indicate which configuration they are
984     * currently running in, so this object must be kept immutable.
985     */
986    Configuration mConfiguration = new Configuration();
987
988    /**
989     * Current sequencing integer of the configuration, for skipping old
990     * configurations.
991     */
992    int mConfigurationSeq = 0;
993
994    boolean mSuppressResizeConfigChanges = false;
995
996    /**
997     * Hardware-reported OpenGLES version.
998     */
999    final int GL_ES_VERSION;
1000
1001    /**
1002     * List of initialization arguments to pass to all processes when binding applications to them.
1003     * For example, references to the commonly used services.
1004     */
1005    HashMap<String, IBinder> mAppBindArgs;
1006
1007    /**
1008     * Temporary to avoid allocations.  Protected by main lock.
1009     */
1010    final StringBuilder mStringBuilder = new StringBuilder(256);
1011
1012    /**
1013     * Used to control how we initialize the service.
1014     */
1015    ComponentName mTopComponent;
1016    String mTopAction = Intent.ACTION_MAIN;
1017    String mTopData;
1018    boolean mProcessesReady = false;
1019    boolean mSystemReady = false;
1020    boolean mBooting = false;
1021    boolean mCallFinishBooting = false;
1022    boolean mBootAnimationComplete = false;
1023    boolean mWaitingUpdate = false;
1024    boolean mDidUpdate = false;
1025    boolean mOnBattery = false;
1026    boolean mLaunchWarningShown = false;
1027
1028    Context mContext;
1029
1030    int mFactoryTest;
1031
1032    boolean mCheckedForSetup;
1033
1034    /**
1035     * The time at which we will allow normal application switches again,
1036     * after a call to {@link #stopAppSwitches()}.
1037     */
1038    long mAppSwitchesAllowedTime;
1039
1040    /**
1041     * This is set to true after the first switch after mAppSwitchesAllowedTime
1042     * is set; any switches after that will clear the time.
1043     */
1044    boolean mDidAppSwitch;
1045
1046    /**
1047     * Last time (in realtime) at which we checked for power usage.
1048     */
1049    long mLastPowerCheckRealtime;
1050
1051    /**
1052     * Last time (in uptime) at which we checked for power usage.
1053     */
1054    long mLastPowerCheckUptime;
1055
1056    /**
1057     * Set while we are wanting to sleep, to prevent any
1058     * activities from being started/resumed.
1059     */
1060    private boolean mSleeping = false;
1061
1062    /**
1063     * The process state used for processes that are running the top activities.
1064     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1065     */
1066    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1067
1068    /**
1069     * Set while we are running a voice interaction.  This overrides
1070     * sleeping while it is active.
1071     */
1072    private IVoiceInteractionSession mRunningVoice;
1073
1074    /**
1075     * For some direct access we need to power manager.
1076     */
1077    PowerManagerInternal mLocalPowerManager;
1078
1079    /**
1080     * We want to hold a wake lock while running a voice interaction session, since
1081     * this may happen with the screen off and we need to keep the CPU running to
1082     * be able to continue to interact with the user.
1083     */
1084    PowerManager.WakeLock mVoiceWakeLock;
1085
1086    /**
1087     * State of external calls telling us if the device is awake or asleep.
1088     */
1089    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1090
1091    /**
1092     * A list of tokens that cause the top activity to be put to sleep.
1093     * They are used by components that may hide and block interaction with underlying
1094     * activities.
1095     */
1096    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1097
1098    static final int LOCK_SCREEN_HIDDEN = 0;
1099    static final int LOCK_SCREEN_LEAVING = 1;
1100    static final int LOCK_SCREEN_SHOWN = 2;
1101    /**
1102     * State of external call telling us if the lock screen is shown.
1103     */
1104    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1105
1106    /**
1107     * Set if we are shutting down the system, similar to sleeping.
1108     */
1109    boolean mShuttingDown = false;
1110
1111    /**
1112     * Current sequence id for oom_adj computation traversal.
1113     */
1114    int mAdjSeq = 0;
1115
1116    /**
1117     * Current sequence id for process LRU updating.
1118     */
1119    int mLruSeq = 0;
1120
1121    /**
1122     * Keep track of the non-cached/empty process we last found, to help
1123     * determine how to distribute cached/empty processes next time.
1124     */
1125    int mNumNonCachedProcs = 0;
1126
1127    /**
1128     * Keep track of the number of cached hidden procs, to balance oom adj
1129     * distribution between those and empty procs.
1130     */
1131    int mNumCachedHiddenProcs = 0;
1132
1133    /**
1134     * Keep track of the number of service processes we last found, to
1135     * determine on the next iteration which should be B services.
1136     */
1137    int mNumServiceProcs = 0;
1138    int mNewNumAServiceProcs = 0;
1139    int mNewNumServiceProcs = 0;
1140
1141    /**
1142     * Allow the current computed overall memory level of the system to go down?
1143     * This is set to false when we are killing processes for reasons other than
1144     * memory management, so that the now smaller process list will not be taken as
1145     * an indication that memory is tighter.
1146     */
1147    boolean mAllowLowerMemLevel = false;
1148
1149    /**
1150     * The last computed memory level, for holding when we are in a state that
1151     * processes are going away for other reasons.
1152     */
1153    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1154
1155    /**
1156     * The last total number of process we have, to determine if changes actually look
1157     * like a shrinking number of process due to lower RAM.
1158     */
1159    int mLastNumProcesses;
1160
1161    /**
1162     * The uptime of the last time we performed idle maintenance.
1163     */
1164    long mLastIdleTime = SystemClock.uptimeMillis();
1165
1166    /**
1167     * Total time spent with RAM that has been added in the past since the last idle time.
1168     */
1169    long mLowRamTimeSinceLastIdle = 0;
1170
1171    /**
1172     * If RAM is currently low, when that horrible situation started.
1173     */
1174    long mLowRamStartTime = 0;
1175
1176    /**
1177     * For reporting to battery stats the current top application.
1178     */
1179    private String mCurResumedPackage = null;
1180    private int mCurResumedUid = -1;
1181
1182    /**
1183     * For reporting to battery stats the apps currently running foreground
1184     * service.  The ProcessMap is package/uid tuples; each of these contain
1185     * an array of the currently foreground processes.
1186     */
1187    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1188            = new ProcessMap<ArrayList<ProcessRecord>>();
1189
1190    /**
1191     * This is set if we had to do a delayed dexopt of an app before launching
1192     * it, to increase the ANR timeouts in that case.
1193     */
1194    boolean mDidDexOpt;
1195
1196    /**
1197     * Set if the systemServer made a call to enterSafeMode.
1198     */
1199    boolean mSafeMode;
1200
1201    /**
1202     * If true, we are running under a test environment so will sample PSS from processes
1203     * much more rapidly to try to collect better data when the tests are rapidly
1204     * running through apps.
1205     */
1206    boolean mTestPssMode = false;
1207
1208    String mDebugApp = null;
1209    boolean mWaitForDebugger = false;
1210    boolean mDebugTransient = false;
1211    String mOrigDebugApp = null;
1212    boolean mOrigWaitForDebugger = false;
1213    boolean mAlwaysFinishActivities = false;
1214    boolean mForceResizableActivites;
1215    IActivityController mController = null;
1216    String mProfileApp = null;
1217    ProcessRecord mProfileProc = null;
1218    String mProfileFile;
1219    ParcelFileDescriptor mProfileFd;
1220    int mSamplingInterval = 0;
1221    boolean mAutoStopProfiler = false;
1222    int mProfileType = 0;
1223    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1224    String mMemWatchDumpProcName;
1225    String mMemWatchDumpFile;
1226    int mMemWatchDumpPid;
1227    int mMemWatchDumpUid;
1228    String mTrackAllocationApp = null;
1229
1230    final long[] mTmpLong = new long[1];
1231
1232    static final class ProcessChangeItem {
1233        static final int CHANGE_ACTIVITIES = 1<<0;
1234        static final int CHANGE_PROCESS_STATE = 1<<1;
1235        int changes;
1236        int uid;
1237        int pid;
1238        int processState;
1239        boolean foregroundActivities;
1240    }
1241
1242    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1243    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1244
1245    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1246    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1247
1248    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1249    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1250
1251    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1252    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1253
1254    ArraySet<String> mAppsNotReportingCrashes;
1255
1256    /**
1257     * Runtime CPU use collection thread.  This object's lock is used to
1258     * perform synchronization with the thread (notifying it to run).
1259     */
1260    final Thread mProcessCpuThread;
1261
1262    /**
1263     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1264     * Must acquire this object's lock when accessing it.
1265     * NOTE: this lock will be held while doing long operations (trawling
1266     * through all processes in /proc), so it should never be acquired by
1267     * any critical paths such as when holding the main activity manager lock.
1268     */
1269    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1270            MONITOR_THREAD_CPU_USAGE);
1271    final AtomicLong mLastCpuTime = new AtomicLong(0);
1272    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1273
1274    long mLastWriteTime = 0;
1275
1276    /**
1277     * Used to retain an update lock when the foreground activity is in
1278     * immersive mode.
1279     */
1280    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1281
1282    /**
1283     * Set to true after the system has finished booting.
1284     */
1285    boolean mBooted = false;
1286
1287    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1288    int mProcessLimitOverride = -1;
1289
1290    WindowManagerService mWindowManager;
1291
1292    final ActivityThread mSystemThread;
1293
1294    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1295        final ProcessRecord mApp;
1296        final int mPid;
1297        final IApplicationThread mAppThread;
1298
1299        AppDeathRecipient(ProcessRecord app, int pid,
1300                IApplicationThread thread) {
1301            if (DEBUG_ALL) Slog.v(
1302                TAG, "New death recipient " + this
1303                + " for thread " + thread.asBinder());
1304            mApp = app;
1305            mPid = pid;
1306            mAppThread = thread;
1307        }
1308
1309        @Override
1310        public void binderDied() {
1311            if (DEBUG_ALL) Slog.v(
1312                TAG, "Death received in " + this
1313                + " for thread " + mAppThread.asBinder());
1314            synchronized(ActivityManagerService.this) {
1315                appDiedLocked(mApp, mPid, mAppThread, true);
1316            }
1317        }
1318    }
1319
1320    static final int SHOW_ERROR_UI_MSG = 1;
1321    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1322    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1323    static final int UPDATE_CONFIGURATION_MSG = 4;
1324    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1325    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1326    static final int SERVICE_TIMEOUT_MSG = 12;
1327    static final int UPDATE_TIME_ZONE = 13;
1328    static final int SHOW_UID_ERROR_UI_MSG = 14;
1329    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1330    static final int PROC_START_TIMEOUT_MSG = 20;
1331    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1332    static final int KILL_APPLICATION_MSG = 22;
1333    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1334    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1335    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1336    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1337    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1338    static final int CLEAR_DNS_CACHE_MSG = 28;
1339    static final int UPDATE_HTTP_PROXY_MSG = 29;
1340    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1341    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1342    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1343    static final int REPORT_MEM_USAGE_MSG = 33;
1344    static final int REPORT_USER_SWITCH_MSG = 34;
1345    static final int CONTINUE_USER_SWITCH_MSG = 35;
1346    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1347    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1348    static final int PERSIST_URI_GRANTS_MSG = 38;
1349    static final int REQUEST_ALL_PSS_MSG = 39;
1350    static final int START_PROFILES_MSG = 40;
1351    static final int UPDATE_TIME = 41;
1352    static final int SYSTEM_USER_START_MSG = 42;
1353    static final int SYSTEM_USER_CURRENT_MSG = 43;
1354    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1355    static final int FINISH_BOOTING_MSG = 45;
1356    static final int START_USER_SWITCH_UI_MSG = 46;
1357    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1358    static final int DISMISS_DIALOG_UI_MSG = 48;
1359    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1360    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1361    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1362    static final int DELETE_DUMPHEAP_MSG = 52;
1363    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1364    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1365    static final int REPORT_TIME_TRACKER_MSG = 55;
1366    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1367    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1368    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1369    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1370    static final int IDLE_UIDS_MSG = 60;
1371
1372    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1373    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1374    static final int FIRST_COMPAT_MODE_MSG = 300;
1375    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1376
1377    CompatModeDialog mCompatModeDialog;
1378    long mLastMemUsageReportTime = 0;
1379
1380    /**
1381     * Flag whether the current user is a "monkey", i.e. whether
1382     * the UI is driven by a UI automation tool.
1383     */
1384    private boolean mUserIsMonkey;
1385
1386    /** Flag whether the device has a Recents UI */
1387    boolean mHasRecents;
1388
1389    /** The dimensions of the thumbnails in the Recents UI. */
1390    int mThumbnailWidth;
1391    int mThumbnailHeight;
1392
1393    final ServiceThread mHandlerThread;
1394    final MainHandler mHandler;
1395    final UiHandler mUiHandler;
1396
1397    final class UiHandler extends Handler {
1398        public UiHandler() {
1399            super(com.android.server.UiThread.get().getLooper(), null, true);
1400        }
1401
1402        @Override
1403        public void handleMessage(Message msg) {
1404            switch (msg.what) {
1405            case SHOW_ERROR_UI_MSG: {
1406                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1407                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1408                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1409                synchronized (ActivityManagerService.this) {
1410                    ProcessRecord proc = (ProcessRecord)data.get("app");
1411                    AppErrorResult res = (AppErrorResult) data.get("result");
1412                    if (proc != null && proc.crashDialog != null) {
1413                        Slog.e(TAG, "App already has crash dialog: " + proc);
1414                        if (res != null) {
1415                            res.set(0);
1416                        }
1417                        return;
1418                    }
1419                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1420                            >= Process.FIRST_APPLICATION_UID
1421                            && proc.pid != MY_PID);
1422                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1423                        isBackground &= (proc.userId != userId);
1424                    }
1425                    if (isBackground && !showBackground) {
1426                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1427                        if (res != null) {
1428                            res.set(0);
1429                        }
1430                        return;
1431                    }
1432                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1433                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1434                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1435                        Dialog d = new AppErrorDialog(mContext,
1436                                ActivityManagerService.this, res, proc);
1437                        d.show();
1438                        proc.crashDialog = d;
1439                    } else {
1440                        // The device is asleep, so just pretend that the user
1441                        // saw a crash dialog and hit "force quit".
1442                        if (res != null) {
1443                            res.set(0);
1444                        }
1445                    }
1446                }
1447
1448                ensureBootCompleted();
1449            } break;
1450            case SHOW_NOT_RESPONDING_UI_MSG: {
1451                synchronized (ActivityManagerService.this) {
1452                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1453                    ProcessRecord proc = (ProcessRecord)data.get("app");
1454                    if (proc != null && proc.anrDialog != null) {
1455                        Slog.e(TAG, "App already has anr dialog: " + proc);
1456                        return;
1457                    }
1458
1459                    Intent intent = new Intent("android.intent.action.ANR");
1460                    if (!mProcessesReady) {
1461                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1462                                | Intent.FLAG_RECEIVER_FOREGROUND);
1463                    }
1464                    broadcastIntentLocked(null, null, intent,
1465                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1466                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1467
1468                    if (mShowDialogs) {
1469                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1470                                mContext, proc, (ActivityRecord)data.get("activity"),
1471                                msg.arg1 != 0);
1472                        d.show();
1473                        proc.anrDialog = d;
1474                    } else {
1475                        // Just kill the app if there is no dialog to be shown.
1476                        killAppAtUsersRequest(proc, null);
1477                    }
1478                }
1479
1480                ensureBootCompleted();
1481            } break;
1482            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1483                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1484                synchronized (ActivityManagerService.this) {
1485                    ProcessRecord proc = (ProcessRecord) data.get("app");
1486                    if (proc == null) {
1487                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1488                        break;
1489                    }
1490                    if (proc.crashDialog != null) {
1491                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1492                        return;
1493                    }
1494                    AppErrorResult res = (AppErrorResult) data.get("result");
1495                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1496                        Dialog d = new StrictModeViolationDialog(mContext,
1497                                ActivityManagerService.this, res, proc);
1498                        d.show();
1499                        proc.crashDialog = d;
1500                    } else {
1501                        // The device is asleep, so just pretend that the user
1502                        // saw a crash dialog and hit "force quit".
1503                        res.set(0);
1504                    }
1505                }
1506                ensureBootCompleted();
1507            } break;
1508            case SHOW_FACTORY_ERROR_UI_MSG: {
1509                Dialog d = new FactoryErrorDialog(
1510                    mContext, msg.getData().getCharSequence("msg"));
1511                d.show();
1512                ensureBootCompleted();
1513            } break;
1514            case WAIT_FOR_DEBUGGER_UI_MSG: {
1515                synchronized (ActivityManagerService.this) {
1516                    ProcessRecord app = (ProcessRecord)msg.obj;
1517                    if (msg.arg1 != 0) {
1518                        if (!app.waitedForDebugger) {
1519                            Dialog d = new AppWaitingForDebuggerDialog(
1520                                    ActivityManagerService.this,
1521                                    mContext, app);
1522                            app.waitDialog = d;
1523                            app.waitedForDebugger = true;
1524                            d.show();
1525                        }
1526                    } else {
1527                        if (app.waitDialog != null) {
1528                            app.waitDialog.dismiss();
1529                            app.waitDialog = null;
1530                        }
1531                    }
1532                }
1533            } break;
1534            case SHOW_UID_ERROR_UI_MSG: {
1535                if (mShowDialogs) {
1536                    AlertDialog d = new BaseErrorDialog(mContext);
1537                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1538                    d.setCancelable(false);
1539                    d.setTitle(mContext.getText(R.string.android_system_label));
1540                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1541                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1542                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1543                    d.show();
1544                }
1545            } break;
1546            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1547                if (mShowDialogs) {
1548                    AlertDialog d = new BaseErrorDialog(mContext);
1549                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1550                    d.setCancelable(false);
1551                    d.setTitle(mContext.getText(R.string.android_system_label));
1552                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1553                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1554                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1555                    d.show();
1556                }
1557            } break;
1558            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1559                synchronized (ActivityManagerService.this) {
1560                    ActivityRecord ar = (ActivityRecord) msg.obj;
1561                    if (mCompatModeDialog != null) {
1562                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1563                                ar.info.applicationInfo.packageName)) {
1564                            return;
1565                        }
1566                        mCompatModeDialog.dismiss();
1567                        mCompatModeDialog = null;
1568                    }
1569                    if (ar != null && false) {
1570                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1571                                ar.packageName)) {
1572                            int mode = mCompatModePackages.computeCompatModeLocked(
1573                                    ar.info.applicationInfo);
1574                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1575                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1576                                mCompatModeDialog = new CompatModeDialog(
1577                                        ActivityManagerService.this, mContext,
1578                                        ar.info.applicationInfo);
1579                                mCompatModeDialog.show();
1580                            }
1581                        }
1582                    }
1583                }
1584                break;
1585            }
1586            case START_USER_SWITCH_UI_MSG: {
1587                mUserController.showUserSwitchDialog(msg.arg1, (String) msg.obj);
1588                break;
1589            }
1590            case DISMISS_DIALOG_UI_MSG: {
1591                final Dialog d = (Dialog) msg.obj;
1592                d.dismiss();
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED_UI_MSG: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1606                dispatchUidsChanged();
1607            } break;
1608            }
1609        }
1610    }
1611
1612    final class MainHandler extends Handler {
1613        public MainHandler(Looper looper) {
1614            super(looper, null, true);
1615        }
1616
1617        @Override
1618        public void handleMessage(Message msg) {
1619            switch (msg.what) {
1620            case UPDATE_CONFIGURATION_MSG: {
1621                final ContentResolver resolver = mContext.getContentResolver();
1622                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1623                        msg.arg1);
1624            } break;
1625            case GC_BACKGROUND_PROCESSES_MSG: {
1626                synchronized (ActivityManagerService.this) {
1627                    performAppGcsIfAppropriateLocked();
1628                }
1629            } break;
1630            case SERVICE_TIMEOUT_MSG: {
1631                if (mDidDexOpt) {
1632                    mDidDexOpt = false;
1633                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1634                    nmsg.obj = msg.obj;
1635                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1636                    return;
1637                }
1638                mServices.serviceTimeout((ProcessRecord)msg.obj);
1639            } break;
1640            case UPDATE_TIME_ZONE: {
1641                synchronized (ActivityManagerService.this) {
1642                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1643                        ProcessRecord r = mLruProcesses.get(i);
1644                        if (r.thread != null) {
1645                            try {
1646                                r.thread.updateTimeZone();
1647                            } catch (RemoteException ex) {
1648                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1649                            }
1650                        }
1651                    }
1652                }
1653            } break;
1654            case CLEAR_DNS_CACHE_MSG: {
1655                synchronized (ActivityManagerService.this) {
1656                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1657                        ProcessRecord r = mLruProcesses.get(i);
1658                        if (r.thread != null) {
1659                            try {
1660                                r.thread.clearDnsCache();
1661                            } catch (RemoteException ex) {
1662                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1663                            }
1664                        }
1665                    }
1666                }
1667            } break;
1668            case UPDATE_HTTP_PROXY_MSG: {
1669                ProxyInfo proxy = (ProxyInfo)msg.obj;
1670                String host = "";
1671                String port = "";
1672                String exclList = "";
1673                Uri pacFileUrl = Uri.EMPTY;
1674                if (proxy != null) {
1675                    host = proxy.getHost();
1676                    port = Integer.toString(proxy.getPort());
1677                    exclList = proxy.getExclusionListAsString();
1678                    pacFileUrl = proxy.getPacFileUrl();
1679                }
1680                synchronized (ActivityManagerService.this) {
1681                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1682                        ProcessRecord r = mLruProcesses.get(i);
1683                        if (r.thread != null) {
1684                            try {
1685                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1686                            } catch (RemoteException ex) {
1687                                Slog.w(TAG, "Failed to update http proxy for: " +
1688                                        r.info.processName);
1689                            }
1690                        }
1691                    }
1692                }
1693            } break;
1694            case PROC_START_TIMEOUT_MSG: {
1695                if (mDidDexOpt) {
1696                    mDidDexOpt = false;
1697                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1698                    nmsg.obj = msg.obj;
1699                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1700                    return;
1701                }
1702                ProcessRecord app = (ProcessRecord)msg.obj;
1703                synchronized (ActivityManagerService.this) {
1704                    processStartTimedOutLocked(app);
1705                }
1706            } break;
1707            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1708                ProcessRecord app = (ProcessRecord)msg.obj;
1709                synchronized (ActivityManagerService.this) {
1710                    processContentProviderPublishTimedOutLocked(app);
1711                }
1712            } break;
1713            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1716                }
1717            } break;
1718            case KILL_APPLICATION_MSG: {
1719                synchronized (ActivityManagerService.this) {
1720                    int appid = msg.arg1;
1721                    boolean restart = (msg.arg2 == 1);
1722                    Bundle bundle = (Bundle)msg.obj;
1723                    String pkg = bundle.getString("pkg");
1724                    String reason = bundle.getString("reason");
1725                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1726                            false, UserHandle.USER_ALL, reason);
1727                }
1728            } break;
1729            case FINALIZE_PENDING_INTENT_MSG: {
1730                ((PendingIntentRecord)msg.obj).completeFinalize();
1731            } break;
1732            case POST_HEAVY_NOTIFICATION_MSG: {
1733                INotificationManager inm = NotificationManager.getService();
1734                if (inm == null) {
1735                    return;
1736                }
1737
1738                ActivityRecord root = (ActivityRecord)msg.obj;
1739                ProcessRecord process = root.app;
1740                if (process == null) {
1741                    return;
1742                }
1743
1744                try {
1745                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1746                    String text = mContext.getString(R.string.heavy_weight_notification,
1747                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1748                    Notification notification = new Notification.Builder(context)
1749                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1750                            .setWhen(0)
1751                            .setOngoing(true)
1752                            .setTicker(text)
1753                            .setColor(mContext.getColor(
1754                                    com.android.internal.R.color.system_notification_accent_color))
1755                            .setContentTitle(text)
1756                            .setContentText(
1757                                    mContext.getText(R.string.heavy_weight_notification_detail))
1758                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1759                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1760                                    new UserHandle(root.userId)))
1761                            .build();
1762                    try {
1763                        int[] outId = new int[1];
1764                        inm.enqueueNotificationWithTag("android", "android", null,
1765                                R.string.heavy_weight_notification,
1766                                notification, outId, root.userId);
1767                    } catch (RuntimeException e) {
1768                        Slog.w(ActivityManagerService.TAG,
1769                                "Error showing notification for heavy-weight app", e);
1770                    } catch (RemoteException e) {
1771                    }
1772                } catch (NameNotFoundException e) {
1773                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1774                }
1775            } break;
1776            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1777                INotificationManager inm = NotificationManager.getService();
1778                if (inm == null) {
1779                    return;
1780                }
1781                try {
1782                    inm.cancelNotificationWithTag("android", null,
1783                            R.string.heavy_weight_notification,  msg.arg1);
1784                } catch (RuntimeException e) {
1785                    Slog.w(ActivityManagerService.TAG,
1786                            "Error canceling notification for service", e);
1787                } catch (RemoteException e) {
1788                }
1789            } break;
1790            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1791                synchronized (ActivityManagerService.this) {
1792                    checkExcessivePowerUsageLocked(true);
1793                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1794                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1795                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1796                }
1797            } break;
1798            case REPORT_MEM_USAGE_MSG: {
1799                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1800                Thread thread = new Thread() {
1801                    @Override public void run() {
1802                        reportMemUsage(memInfos);
1803                    }
1804                };
1805                thread.start();
1806                break;
1807            }
1808            case REPORT_USER_SWITCH_MSG: {
1809                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1810                break;
1811            }
1812            case CONTINUE_USER_SWITCH_MSG: {
1813                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1814                break;
1815            }
1816            case USER_SWITCH_TIMEOUT_MSG: {
1817                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1818                break;
1819            }
1820            case IMMERSIVE_MODE_LOCK_MSG: {
1821                final boolean nextState = (msg.arg1 != 0);
1822                if (mUpdateLock.isHeld() != nextState) {
1823                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1824                            "Applying new update lock state '" + nextState
1825                            + "' for " + (ActivityRecord)msg.obj);
1826                    if (nextState) {
1827                        mUpdateLock.acquire();
1828                    } else {
1829                        mUpdateLock.release();
1830                    }
1831                }
1832                break;
1833            }
1834            case PERSIST_URI_GRANTS_MSG: {
1835                writeGrantedUriPermissions();
1836                break;
1837            }
1838            case REQUEST_ALL_PSS_MSG: {
1839                synchronized (ActivityManagerService.this) {
1840                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1841                }
1842                break;
1843            }
1844            case START_PROFILES_MSG: {
1845                synchronized (ActivityManagerService.this) {
1846                    mUserController.startProfilesLocked();
1847                }
1848                break;
1849            }
1850            case UPDATE_TIME: {
1851                synchronized (ActivityManagerService.this) {
1852                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1853                        ProcessRecord r = mLruProcesses.get(i);
1854                        if (r.thread != null) {
1855                            try {
1856                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1857                            } catch (RemoteException ex) {
1858                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1859                            }
1860                        }
1861                    }
1862                }
1863                break;
1864            }
1865            case SYSTEM_USER_START_MSG: {
1866                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1867                        Integer.toString(msg.arg1), msg.arg1);
1868                mSystemServiceManager.startUser(msg.arg1);
1869                break;
1870            }
1871            case SYSTEM_USER_CURRENT_MSG: {
1872                mBatteryStatsService.noteEvent(
1873                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1874                        Integer.toString(msg.arg2), msg.arg2);
1875                mBatteryStatsService.noteEvent(
1876                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1877                        Integer.toString(msg.arg1), msg.arg1);
1878                mSystemServiceManager.switchUser(msg.arg1);
1879                break;
1880            }
1881            case ENTER_ANIMATION_COMPLETE_MSG: {
1882                synchronized (ActivityManagerService.this) {
1883                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1884                    if (r != null && r.app != null && r.app.thread != null) {
1885                        try {
1886                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1887                        } catch (RemoteException e) {
1888                        }
1889                    }
1890                }
1891                break;
1892            }
1893            case FINISH_BOOTING_MSG: {
1894                if (msg.arg1 != 0) {
1895                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1896                    finishBooting();
1897                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1898                }
1899                if (msg.arg2 != 0) {
1900                    enableScreenAfterBoot();
1901                }
1902                break;
1903            }
1904            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1905                try {
1906                    Locale l = (Locale) msg.obj;
1907                    IBinder service = ServiceManager.getService("mount");
1908                    IMountService mountService = IMountService.Stub.asInterface(service);
1909                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1910                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1911                } catch (RemoteException e) {
1912                    Log.e(TAG, "Error storing locale for decryption UI", e);
1913                }
1914                break;
1915            }
1916            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1917                synchronized (ActivityManagerService.this) {
1918                    int i = mTaskStackListeners.beginBroadcast();
1919                    while (i > 0) {
1920                        i--;
1921                        try {
1922                            // Make a one-way callback to the listener
1923                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1924                        } catch (RemoteException e){
1925                            // Handled by the RemoteCallbackList
1926                        }
1927                    }
1928                    mTaskStackListeners.finishBroadcast();
1929                }
1930                break;
1931            }
1932            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1933                final int uid = msg.arg1;
1934                final byte[] firstPacket = (byte[]) msg.obj;
1935
1936                synchronized (mPidsSelfLocked) {
1937                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1938                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1939                        if (p.uid == uid) {
1940                            try {
1941                                p.thread.notifyCleartextNetwork(firstPacket);
1942                            } catch (RemoteException ignored) {
1943                            }
1944                        }
1945                    }
1946                }
1947                break;
1948            }
1949            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1950                final String procName;
1951                final int uid;
1952                final long memLimit;
1953                final String reportPackage;
1954                synchronized (ActivityManagerService.this) {
1955                    procName = mMemWatchDumpProcName;
1956                    uid = mMemWatchDumpUid;
1957                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1958                    if (val == null) {
1959                        val = mMemWatchProcesses.get(procName, 0);
1960                    }
1961                    if (val != null) {
1962                        memLimit = val.first;
1963                        reportPackage = val.second;
1964                    } else {
1965                        memLimit = 0;
1966                        reportPackage = null;
1967                    }
1968                }
1969                if (procName == null) {
1970                    return;
1971                }
1972
1973                if (DEBUG_PSS) Slog.d(TAG_PSS,
1974                        "Showing dump heap notification from " + procName + "/" + uid);
1975
1976                INotificationManager inm = NotificationManager.getService();
1977                if (inm == null) {
1978                    return;
1979                }
1980
1981                String text = mContext.getString(R.string.dump_heap_notification, procName);
1982
1983
1984                Intent deleteIntent = new Intent();
1985                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1986                Intent intent = new Intent();
1987                intent.setClassName("android", DumpHeapActivity.class.getName());
1988                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1989                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1990                if (reportPackage != null) {
1991                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1992                }
1993                int userId = UserHandle.getUserId(uid);
1994                Notification notification = new Notification.Builder(mContext)
1995                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1996                        .setWhen(0)
1997                        .setOngoing(true)
1998                        .setAutoCancel(true)
1999                        .setTicker(text)
2000                        .setColor(mContext.getColor(
2001                                com.android.internal.R.color.system_notification_accent_color))
2002                        .setContentTitle(text)
2003                        .setContentText(
2004                                mContext.getText(R.string.dump_heap_notification_detail))
2005                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2006                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2007                                new UserHandle(userId)))
2008                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2009                                deleteIntent, 0, UserHandle.SYSTEM))
2010                        .build();
2011
2012                try {
2013                    int[] outId = new int[1];
2014                    inm.enqueueNotificationWithTag("android", "android", null,
2015                            R.string.dump_heap_notification,
2016                            notification, outId, userId);
2017                } catch (RuntimeException e) {
2018                    Slog.w(ActivityManagerService.TAG,
2019                            "Error showing notification for dump heap", e);
2020                } catch (RemoteException e) {
2021                }
2022            } break;
2023            case DELETE_DUMPHEAP_MSG: {
2024                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2025                        DumpHeapActivity.JAVA_URI,
2026                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2027                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2028                        UserHandle.myUserId());
2029                synchronized (ActivityManagerService.this) {
2030                    mMemWatchDumpFile = null;
2031                    mMemWatchDumpProcName = null;
2032                    mMemWatchDumpPid = -1;
2033                    mMemWatchDumpUid = -1;
2034                }
2035            } break;
2036            case FOREGROUND_PROFILE_CHANGED_MSG: {
2037                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2038            } break;
2039            case REPORT_TIME_TRACKER_MSG: {
2040                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2041                tracker.deliverResult(mContext);
2042            } break;
2043            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2044                mUserController.dispatchUserSwitchComplete(msg.arg1);
2045            } break;
2046            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2047                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2048                try {
2049                    connection.shutdown();
2050                } catch (RemoteException e) {
2051                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2052                }
2053                // Only a UiAutomation can set this flag and now that
2054                // it is finished we make sure it is reset to its default.
2055                mUserIsMonkey = false;
2056            } break;
2057            case APP_BOOST_DEACTIVATE_MSG: {
2058                synchronized(ActivityManagerService.this) {
2059                    if (mIsBoosted) {
2060                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2061                            nativeMigrateFromBoost();
2062                            mIsBoosted = false;
2063                            mBoostStartTime = 0;
2064                        } else {
2065                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2066                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2067                        }
2068                    }
2069                }
2070            } break;
2071            case IDLE_UIDS_MSG: {
2072                idleUids();
2073            } break;
2074            }
2075        }
2076    };
2077
2078    static final int COLLECT_PSS_BG_MSG = 1;
2079
2080    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2081        @Override
2082        public void handleMessage(Message msg) {
2083            switch (msg.what) {
2084            case COLLECT_PSS_BG_MSG: {
2085                long start = SystemClock.uptimeMillis();
2086                MemInfoReader memInfo = null;
2087                synchronized (ActivityManagerService.this) {
2088                    if (mFullPssPending) {
2089                        mFullPssPending = false;
2090                        memInfo = new MemInfoReader();
2091                    }
2092                }
2093                if (memInfo != null) {
2094                    updateCpuStatsNow();
2095                    long nativeTotalPss = 0;
2096                    synchronized (mProcessCpuTracker) {
2097                        final int N = mProcessCpuTracker.countStats();
2098                        for (int j=0; j<N; j++) {
2099                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2100                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2101                                // This is definitely an application process; skip it.
2102                                continue;
2103                            }
2104                            synchronized (mPidsSelfLocked) {
2105                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2106                                    // This is one of our own processes; skip it.
2107                                    continue;
2108                                }
2109                            }
2110                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2111                        }
2112                    }
2113                    memInfo.readMemInfo();
2114                    synchronized (ActivityManagerService.this) {
2115                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2116                                + (SystemClock.uptimeMillis()-start) + "ms");
2117                        final long cachedKb = memInfo.getCachedSizeKb();
2118                        final long freeKb = memInfo.getFreeSizeKb();
2119                        final long zramKb = memInfo.getZramTotalSizeKb();
2120                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2121                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2122                                kernelKb*1024, nativeTotalPss*1024);
2123                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2124                                nativeTotalPss);
2125                    }
2126                }
2127
2128                int num = 0;
2129                long[] tmp = new long[1];
2130                do {
2131                    ProcessRecord proc;
2132                    int procState;
2133                    int pid;
2134                    long lastPssTime;
2135                    synchronized (ActivityManagerService.this) {
2136                        if (mPendingPssProcesses.size() <= 0) {
2137                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2138                                    "Collected PSS of " + num + " processes in "
2139                                    + (SystemClock.uptimeMillis() - start) + "ms");
2140                            mPendingPssProcesses.clear();
2141                            return;
2142                        }
2143                        proc = mPendingPssProcesses.remove(0);
2144                        procState = proc.pssProcState;
2145                        lastPssTime = proc.lastPssTime;
2146                        if (proc.thread != null && procState == proc.setProcState
2147                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2148                                        < SystemClock.uptimeMillis()) {
2149                            pid = proc.pid;
2150                        } else {
2151                            proc = null;
2152                            pid = 0;
2153                        }
2154                    }
2155                    if (proc != null) {
2156                        long pss = Debug.getPss(pid, tmp, null);
2157                        synchronized (ActivityManagerService.this) {
2158                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2159                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2160                                num++;
2161                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2162                                        SystemClock.uptimeMillis());
2163                            }
2164                        }
2165                    }
2166                } while (true);
2167            }
2168            }
2169        }
2170    };
2171
2172    public void setSystemProcess() {
2173        try {
2174            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2175            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2176            ServiceManager.addService("meminfo", new MemBinder(this));
2177            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2178            ServiceManager.addService("dbinfo", new DbBinder(this));
2179            if (MONITOR_CPU_USAGE) {
2180                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2181            }
2182            ServiceManager.addService("permission", new PermissionController(this));
2183            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2184
2185            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2186                    "android", STOCK_PM_FLAGS);
2187            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2188
2189            synchronized (this) {
2190                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2191                app.persistent = true;
2192                app.pid = MY_PID;
2193                app.maxAdj = ProcessList.SYSTEM_ADJ;
2194                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2195                synchronized (mPidsSelfLocked) {
2196                    mPidsSelfLocked.put(app.pid, app);
2197                }
2198                updateLruProcessLocked(app, false, null);
2199                updateOomAdjLocked();
2200            }
2201        } catch (PackageManager.NameNotFoundException e) {
2202            throw new RuntimeException(
2203                    "Unable to find android system package", e);
2204        }
2205    }
2206
2207    public void setWindowManager(WindowManagerService wm) {
2208        mWindowManager = wm;
2209        mStackSupervisor.setWindowManager(wm);
2210    }
2211
2212    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2213        mUsageStatsService = usageStatsManager;
2214    }
2215
2216    public void startObservingNativeCrashes() {
2217        final NativeCrashListener ncl = new NativeCrashListener(this);
2218        ncl.start();
2219    }
2220
2221    public IAppOpsService getAppOpsService() {
2222        return mAppOpsService;
2223    }
2224
2225    static class MemBinder extends Binder {
2226        ActivityManagerService mActivityManagerService;
2227        MemBinder(ActivityManagerService activityManagerService) {
2228            mActivityManagerService = activityManagerService;
2229        }
2230
2231        @Override
2232        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234                    != PackageManager.PERMISSION_GRANTED) {
2235                pw.println("Permission Denial: can't dump meminfo from from pid="
2236                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237                        + " without permission " + android.Manifest.permission.DUMP);
2238                return;
2239            }
2240
2241            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2242        }
2243    }
2244
2245    static class GraphicsBinder extends Binder {
2246        ActivityManagerService mActivityManagerService;
2247        GraphicsBinder(ActivityManagerService activityManagerService) {
2248            mActivityManagerService = activityManagerService;
2249        }
2250
2251        @Override
2252        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254                    != PackageManager.PERMISSION_GRANTED) {
2255                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2256                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257                        + " without permission " + android.Manifest.permission.DUMP);
2258                return;
2259            }
2260
2261            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2262        }
2263    }
2264
2265    static class DbBinder extends Binder {
2266        ActivityManagerService mActivityManagerService;
2267        DbBinder(ActivityManagerService activityManagerService) {
2268            mActivityManagerService = activityManagerService;
2269        }
2270
2271        @Override
2272        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2273            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2274                    != PackageManager.PERMISSION_GRANTED) {
2275                pw.println("Permission Denial: can't dump dbinfo from from pid="
2276                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2277                        + " without permission " + android.Manifest.permission.DUMP);
2278                return;
2279            }
2280
2281            mActivityManagerService.dumpDbInfo(fd, pw, args);
2282        }
2283    }
2284
2285    static class CpuBinder extends Binder {
2286        ActivityManagerService mActivityManagerService;
2287        CpuBinder(ActivityManagerService activityManagerService) {
2288            mActivityManagerService = activityManagerService;
2289        }
2290
2291        @Override
2292        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2293            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2294                    != PackageManager.PERMISSION_GRANTED) {
2295                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2296                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2297                        + " without permission " + android.Manifest.permission.DUMP);
2298                return;
2299            }
2300
2301            synchronized (mActivityManagerService.mProcessCpuTracker) {
2302                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2303                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2304                        SystemClock.uptimeMillis()));
2305            }
2306        }
2307    }
2308
2309    public static final class Lifecycle extends SystemService {
2310        private final ActivityManagerService mService;
2311
2312        public Lifecycle(Context context) {
2313            super(context);
2314            mService = new ActivityManagerService(context);
2315        }
2316
2317        @Override
2318        public void onStart() {
2319            mService.start();
2320        }
2321
2322        public ActivityManagerService getService() {
2323            return mService;
2324        }
2325    }
2326
2327    // Note: This method is invoked on the main thread but may need to attach various
2328    // handlers to other threads.  So take care to be explicit about the looper.
2329    public ActivityManagerService(Context systemContext) {
2330        mContext = systemContext;
2331        mFactoryTest = FactoryTest.getMode();
2332        mSystemThread = ActivityThread.currentActivityThread();
2333
2334        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2335
2336        mHandlerThread = new ServiceThread(TAG,
2337                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2338        mHandlerThread.start();
2339        mHandler = new MainHandler(mHandlerThread.getLooper());
2340        mUiHandler = new UiHandler();
2341
2342        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2343                "foreground", BROADCAST_FG_TIMEOUT, false);
2344        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2345                "background", BROADCAST_BG_TIMEOUT, true);
2346        mBroadcastQueues[0] = mFgBroadcastQueue;
2347        mBroadcastQueues[1] = mBgBroadcastQueue;
2348
2349        mServices = new ActiveServices(this);
2350        mProviderMap = new ProviderMap(this);
2351
2352        // TODO: Move creation of battery stats service outside of activity manager service.
2353        File dataDir = Environment.getDataDirectory();
2354        File systemDir = new File(dataDir, "system");
2355        systemDir.mkdirs();
2356        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2357        mBatteryStatsService.getActiveStatistics().readLocked();
2358        mBatteryStatsService.scheduleWriteToDisk();
2359        mOnBattery = DEBUG_POWER ? true
2360                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2361        mBatteryStatsService.getActiveStatistics().setCallback(this);
2362
2363        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2364
2365        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2366        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2367                new IAppOpsCallback.Stub() {
2368                    @Override public void opChanged(int op, int uid, String packageName) {
2369                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2370                            if (mAppOpsService.checkOperation(op, uid, packageName)
2371                                    != AppOpsManager.MODE_ALLOWED) {
2372                                runInBackgroundDisabled(uid);
2373                            }
2374                        }
2375                    }
2376                });
2377
2378        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2379
2380        mUserController = new UserController(this);
2381
2382        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2383            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2384
2385        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2386
2387        mConfiguration.setToDefaults();
2388        mConfiguration.setLocale(Locale.getDefault());
2389
2390        mConfigurationSeq = mConfiguration.seq = 1;
2391        mProcessCpuTracker.init();
2392
2393        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2394        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2395        mRecentTasks = new RecentTasks(this);
2396        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2397        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2398
2399        mProcessCpuThread = new Thread("CpuTracker") {
2400            @Override
2401            public void run() {
2402                while (true) {
2403                    try {
2404                        try {
2405                            synchronized(this) {
2406                                final long now = SystemClock.uptimeMillis();
2407                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2408                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2409                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2410                                //        + ", write delay=" + nextWriteDelay);
2411                                if (nextWriteDelay < nextCpuDelay) {
2412                                    nextCpuDelay = nextWriteDelay;
2413                                }
2414                                if (nextCpuDelay > 0) {
2415                                    mProcessCpuMutexFree.set(true);
2416                                    this.wait(nextCpuDelay);
2417                                }
2418                            }
2419                        } catch (InterruptedException e) {
2420                        }
2421                        updateCpuStatsNow();
2422                    } catch (Exception e) {
2423                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2424                    }
2425                }
2426            }
2427        };
2428
2429        Watchdog.getInstance().addMonitor(this);
2430        Watchdog.getInstance().addThread(mHandler);
2431    }
2432
2433    public void setSystemServiceManager(SystemServiceManager mgr) {
2434        mSystemServiceManager = mgr;
2435    }
2436
2437    public void setInstaller(Installer installer) {
2438        mInstaller = installer;
2439    }
2440
2441    private void start() {
2442        Process.removeAllProcessGroups();
2443        mProcessCpuThread.start();
2444
2445        mBatteryStatsService.publish(mContext);
2446        mAppOpsService.publish(mContext);
2447        Slog.d("AppOps", "AppOpsService published");
2448        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2449    }
2450
2451    public void initPowerManagement() {
2452        mStackSupervisor.initPowerManagement();
2453        mBatteryStatsService.initPowerManagement();
2454        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2455        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2456        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2457        mVoiceWakeLock.setReferenceCounted(false);
2458    }
2459
2460    @Override
2461    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2462            throws RemoteException {
2463        if (code == SYSPROPS_TRANSACTION) {
2464            // We need to tell all apps about the system property change.
2465            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2466            synchronized(this) {
2467                final int NP = mProcessNames.getMap().size();
2468                for (int ip=0; ip<NP; ip++) {
2469                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2470                    final int NA = apps.size();
2471                    for (int ia=0; ia<NA; ia++) {
2472                        ProcessRecord app = apps.valueAt(ia);
2473                        if (app.thread != null) {
2474                            procs.add(app.thread.asBinder());
2475                        }
2476                    }
2477                }
2478            }
2479
2480            int N = procs.size();
2481            for (int i=0; i<N; i++) {
2482                Parcel data2 = Parcel.obtain();
2483                try {
2484                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2485                } catch (RemoteException e) {
2486                }
2487                data2.recycle();
2488            }
2489        }
2490        try {
2491            return super.onTransact(code, data, reply, flags);
2492        } catch (RuntimeException e) {
2493            // The activity manager only throws security exceptions, so let's
2494            // log all others.
2495            if (!(e instanceof SecurityException)) {
2496                Slog.wtf(TAG, "Activity Manager Crash", e);
2497            }
2498            throw e;
2499        }
2500    }
2501
2502    void updateCpuStats() {
2503        final long now = SystemClock.uptimeMillis();
2504        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2505            return;
2506        }
2507        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2508            synchronized (mProcessCpuThread) {
2509                mProcessCpuThread.notify();
2510            }
2511        }
2512    }
2513
2514    void updateCpuStatsNow() {
2515        synchronized (mProcessCpuTracker) {
2516            mProcessCpuMutexFree.set(false);
2517            final long now = SystemClock.uptimeMillis();
2518            boolean haveNewCpuStats = false;
2519
2520            if (MONITOR_CPU_USAGE &&
2521                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2522                mLastCpuTime.set(now);
2523                mProcessCpuTracker.update();
2524                if (mProcessCpuTracker.hasGoodLastStats()) {
2525                    haveNewCpuStats = true;
2526                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2527                    //Slog.i(TAG, "Total CPU usage: "
2528                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2529
2530                    // Slog the cpu usage if the property is set.
2531                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2532                        int user = mProcessCpuTracker.getLastUserTime();
2533                        int system = mProcessCpuTracker.getLastSystemTime();
2534                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2535                        int irq = mProcessCpuTracker.getLastIrqTime();
2536                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2537                        int idle = mProcessCpuTracker.getLastIdleTime();
2538
2539                        int total = user + system + iowait + irq + softIrq + idle;
2540                        if (total == 0) total = 1;
2541
2542                        EventLog.writeEvent(EventLogTags.CPU,
2543                                ((user+system+iowait+irq+softIrq) * 100) / total,
2544                                (user * 100) / total,
2545                                (system * 100) / total,
2546                                (iowait * 100) / total,
2547                                (irq * 100) / total,
2548                                (softIrq * 100) / total);
2549                    }
2550                }
2551            }
2552
2553            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2554            synchronized(bstats) {
2555                synchronized(mPidsSelfLocked) {
2556                    if (haveNewCpuStats) {
2557                        if (bstats.startAddingCpuLocked()) {
2558                            int totalUTime = 0;
2559                            int totalSTime = 0;
2560                            final int N = mProcessCpuTracker.countStats();
2561                            for (int i=0; i<N; i++) {
2562                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2563                                if (!st.working) {
2564                                    continue;
2565                                }
2566                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2567                                totalUTime += st.rel_utime;
2568                                totalSTime += st.rel_stime;
2569                                if (pr != null) {
2570                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2571                                    if (ps == null || !ps.isActive()) {
2572                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2573                                                pr.info.uid, pr.processName);
2574                                    }
2575                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2576                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2577                                } else {
2578                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2579                                    if (ps == null || !ps.isActive()) {
2580                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2581                                                bstats.mapUid(st.uid), st.name);
2582                                    }
2583                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2584                                }
2585                            }
2586                            final int userTime = mProcessCpuTracker.getLastUserTime();
2587                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2588                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2589                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2590                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2591                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2592                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2593                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2594                        }
2595                    }
2596                }
2597
2598                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2599                    mLastWriteTime = now;
2600                    mBatteryStatsService.scheduleWriteToDisk();
2601                }
2602            }
2603        }
2604    }
2605
2606    @Override
2607    public void batteryNeedsCpuUpdate() {
2608        updateCpuStatsNow();
2609    }
2610
2611    @Override
2612    public void batteryPowerChanged(boolean onBattery) {
2613        // When plugging in, update the CPU stats first before changing
2614        // the plug state.
2615        updateCpuStatsNow();
2616        synchronized (this) {
2617            synchronized(mPidsSelfLocked) {
2618                mOnBattery = DEBUG_POWER ? true : onBattery;
2619            }
2620        }
2621    }
2622
2623    @Override
2624    public void batterySendBroadcast(Intent intent) {
2625        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2626                AppOpsManager.OP_NONE, null, false, false,
2627                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2628    }
2629
2630    /**
2631     * Initialize the application bind args. These are passed to each
2632     * process when the bindApplication() IPC is sent to the process. They're
2633     * lazily setup to make sure the services are running when they're asked for.
2634     */
2635    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2636        if (mAppBindArgs == null) {
2637            mAppBindArgs = new HashMap<>();
2638
2639            // Isolated processes won't get this optimization, so that we don't
2640            // violate the rules about which services they have access to.
2641            if (!isolated) {
2642                // Setup the application init args
2643                mAppBindArgs.put("package", ServiceManager.getService("package"));
2644                mAppBindArgs.put("window", ServiceManager.getService("window"));
2645                mAppBindArgs.put(Context.ALARM_SERVICE,
2646                        ServiceManager.getService(Context.ALARM_SERVICE));
2647            }
2648        }
2649        return mAppBindArgs;
2650    }
2651
2652    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2653        if (r != null && mFocusedActivity != r) {
2654            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2655            ActivityRecord last = mFocusedActivity;
2656            mFocusedActivity = r;
2657            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2658                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2659                if (mCurAppTimeTracker != r.appTimeTracker) {
2660                    // We are switching app tracking.  Complete the current one.
2661                    if (mCurAppTimeTracker != null) {
2662                        mCurAppTimeTracker.stop();
2663                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2664                                mCurAppTimeTracker).sendToTarget();
2665                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2666                        mCurAppTimeTracker = null;
2667                    }
2668                    if (r.appTimeTracker != null) {
2669                        mCurAppTimeTracker = r.appTimeTracker;
2670                        startTimeTrackingFocusedActivityLocked();
2671                    }
2672                } else {
2673                    startTimeTrackingFocusedActivityLocked();
2674                }
2675            } else {
2676                r.appTimeTracker = null;
2677            }
2678            if (r.task != null && r.task.voiceInteractor != null) {
2679                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2680            } else {
2681                finishRunningVoiceLocked();
2682                if (last != null && last.task.voiceSession != null) {
2683                    // We had been in a voice interaction session, but now focused has
2684                    // move to something different.  Just finish the session, we can't
2685                    // return to it and retain the proper state and synchronization with
2686                    // the voice interaction service.
2687                    finishVoiceTask(last.task.voiceSession);
2688                }
2689            }
2690            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2691                mWindowManager.setFocusedApp(r.appToken, true);
2692            }
2693            applyUpdateLockStateLocked(r);
2694            if (mFocusedActivity.userId != mLastFocusedUserId) {
2695                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2696                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2697                        mFocusedActivity.userId, 0));
2698                mLastFocusedUserId = mFocusedActivity.userId;
2699            }
2700        }
2701        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2702                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2703                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2704    }
2705
2706    final void clearFocusedActivity(ActivityRecord r) {
2707        if (mFocusedActivity == r) {
2708            ActivityStack stack = mStackSupervisor.getFocusedStack();
2709            if (stack != null) {
2710                ActivityRecord top = stack.topActivity();
2711                if (top != null && top.userId != mLastFocusedUserId) {
2712                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2713                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2714                                    top.userId, 0));
2715                    mLastFocusedUserId = top.userId;
2716                }
2717            }
2718            mFocusedActivity = null;
2719            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2720        }
2721    }
2722
2723    @Override
2724    public void setFocusedStack(int stackId) {
2725        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2726        synchronized (ActivityManagerService.this) {
2727            ActivityStack stack = mStackSupervisor.getStack(stackId);
2728            if (stack != null) {
2729                ActivityRecord r = stack.topRunningActivityLocked();
2730                if (r != null) {
2731                    setFocusedActivityLocked(r, "setFocusedStack");
2732                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2733                }
2734            }
2735        }
2736    }
2737
2738    @Override
2739    public void setFocusedTask(int taskId) {
2740        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2741        long callingId = Binder.clearCallingIdentity();
2742        try {
2743            synchronized (ActivityManagerService.this) {
2744                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2745                if (task != null) {
2746                    ActivityRecord r = task.topRunningActivityLocked();
2747                    if (r != null) {
2748                        setFocusedActivityLocked(r, "setFocusedTask");
2749                        mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2750                    }
2751                }
2752            }
2753        } finally {
2754            Binder.restoreCallingIdentity(callingId);
2755        }
2756    }
2757
2758    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2759    @Override
2760    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2761        synchronized (ActivityManagerService.this) {
2762            if (listener != null) {
2763                mTaskStackListeners.register(listener);
2764            }
2765        }
2766    }
2767
2768    @Override
2769    public void notifyActivityDrawn(IBinder token) {
2770        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2771        synchronized (this) {
2772            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2773            if (r != null) {
2774                r.task.stack.notifyActivityDrawnLocked(r);
2775            }
2776        }
2777    }
2778
2779    final void applyUpdateLockStateLocked(ActivityRecord r) {
2780        // Modifications to the UpdateLock state are done on our handler, outside
2781        // the activity manager's locks.  The new state is determined based on the
2782        // state *now* of the relevant activity record.  The object is passed to
2783        // the handler solely for logging detail, not to be consulted/modified.
2784        final boolean nextState = r != null && r.immersive;
2785        mHandler.sendMessage(
2786                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2787    }
2788
2789    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2790        Message msg = Message.obtain();
2791        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2792        msg.obj = r.task.askedCompatMode ? null : r;
2793        mUiHandler.sendMessage(msg);
2794    }
2795
2796    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2797            String what, Object obj, ProcessRecord srcApp) {
2798        app.lastActivityTime = now;
2799
2800        if (app.activities.size() > 0) {
2801            // Don't want to touch dependent processes that are hosting activities.
2802            return index;
2803        }
2804
2805        int lrui = mLruProcesses.lastIndexOf(app);
2806        if (lrui < 0) {
2807            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2808                    + what + " " + obj + " from " + srcApp);
2809            return index;
2810        }
2811
2812        if (lrui >= index) {
2813            // Don't want to cause this to move dependent processes *back* in the
2814            // list as if they were less frequently used.
2815            return index;
2816        }
2817
2818        if (lrui >= mLruProcessActivityStart) {
2819            // Don't want to touch dependent processes that are hosting activities.
2820            return index;
2821        }
2822
2823        mLruProcesses.remove(lrui);
2824        if (index > 0) {
2825            index--;
2826        }
2827        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2828                + " in LRU list: " + app);
2829        mLruProcesses.add(index, app);
2830        return index;
2831    }
2832
2833    private static void killProcessGroup(int uid, int pid) {
2834        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2835        Process.killProcessGroup(uid, pid);
2836        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2837    }
2838
2839    final void removeLruProcessLocked(ProcessRecord app) {
2840        int lrui = mLruProcesses.lastIndexOf(app);
2841        if (lrui >= 0) {
2842            if (!app.killed) {
2843                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2844                Process.killProcessQuiet(app.pid);
2845                killProcessGroup(app.info.uid, app.pid);
2846            }
2847            if (lrui <= mLruProcessActivityStart) {
2848                mLruProcessActivityStart--;
2849            }
2850            if (lrui <= mLruProcessServiceStart) {
2851                mLruProcessServiceStart--;
2852            }
2853            mLruProcesses.remove(lrui);
2854        }
2855    }
2856
2857    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2858            ProcessRecord client) {
2859        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2860                || app.treatLikeActivity;
2861        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2862        if (!activityChange && hasActivity) {
2863            // The process has activities, so we are only allowing activity-based adjustments
2864            // to move it.  It should be kept in the front of the list with other
2865            // processes that have activities, and we don't want those to change their
2866            // order except due to activity operations.
2867            return;
2868        }
2869
2870        mLruSeq++;
2871        final long now = SystemClock.uptimeMillis();
2872        app.lastActivityTime = now;
2873
2874        // First a quick reject: if the app is already at the position we will
2875        // put it, then there is nothing to do.
2876        if (hasActivity) {
2877            final int N = mLruProcesses.size();
2878            if (N > 0 && mLruProcesses.get(N-1) == app) {
2879                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2880                return;
2881            }
2882        } else {
2883            if (mLruProcessServiceStart > 0
2884                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2885                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2886                return;
2887            }
2888        }
2889
2890        int lrui = mLruProcesses.lastIndexOf(app);
2891
2892        if (app.persistent && lrui >= 0) {
2893            // We don't care about the position of persistent processes, as long as
2894            // they are in the list.
2895            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2896            return;
2897        }
2898
2899        /* In progress: compute new position first, so we can avoid doing work
2900           if the process is not actually going to move.  Not yet working.
2901        int addIndex;
2902        int nextIndex;
2903        boolean inActivity = false, inService = false;
2904        if (hasActivity) {
2905            // Process has activities, put it at the very tipsy-top.
2906            addIndex = mLruProcesses.size();
2907            nextIndex = mLruProcessServiceStart;
2908            inActivity = true;
2909        } else if (hasService) {
2910            // Process has services, put it at the top of the service list.
2911            addIndex = mLruProcessActivityStart;
2912            nextIndex = mLruProcessServiceStart;
2913            inActivity = true;
2914            inService = true;
2915        } else  {
2916            // Process not otherwise of interest, it goes to the top of the non-service area.
2917            addIndex = mLruProcessServiceStart;
2918            if (client != null) {
2919                int clientIndex = mLruProcesses.lastIndexOf(client);
2920                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2921                        + app);
2922                if (clientIndex >= 0 && addIndex > clientIndex) {
2923                    addIndex = clientIndex;
2924                }
2925            }
2926            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2927        }
2928
2929        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2930                + mLruProcessActivityStart + "): " + app);
2931        */
2932
2933        if (lrui >= 0) {
2934            if (lrui < mLruProcessActivityStart) {
2935                mLruProcessActivityStart--;
2936            }
2937            if (lrui < mLruProcessServiceStart) {
2938                mLruProcessServiceStart--;
2939            }
2940            /*
2941            if (addIndex > lrui) {
2942                addIndex--;
2943            }
2944            if (nextIndex > lrui) {
2945                nextIndex--;
2946            }
2947            */
2948            mLruProcesses.remove(lrui);
2949        }
2950
2951        /*
2952        mLruProcesses.add(addIndex, app);
2953        if (inActivity) {
2954            mLruProcessActivityStart++;
2955        }
2956        if (inService) {
2957            mLruProcessActivityStart++;
2958        }
2959        */
2960
2961        int nextIndex;
2962        if (hasActivity) {
2963            final int N = mLruProcesses.size();
2964            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2965                // Process doesn't have activities, but has clients with
2966                // activities...  move it up, but one below the top (the top
2967                // should always have a real activity).
2968                if (DEBUG_LRU) Slog.d(TAG_LRU,
2969                        "Adding to second-top of LRU activity list: " + app);
2970                mLruProcesses.add(N - 1, app);
2971                // To keep it from spamming the LRU list (by making a bunch of clients),
2972                // we will push down any other entries owned by the app.
2973                final int uid = app.info.uid;
2974                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2975                    ProcessRecord subProc = mLruProcesses.get(i);
2976                    if (subProc.info.uid == uid) {
2977                        // We want to push this one down the list.  If the process after
2978                        // it is for the same uid, however, don't do so, because we don't
2979                        // want them internally to be re-ordered.
2980                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2981                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2982                                    "Pushing uid " + uid + " swapping at " + i + ": "
2983                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2984                            ProcessRecord tmp = mLruProcesses.get(i);
2985                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2986                            mLruProcesses.set(i - 1, tmp);
2987                            i--;
2988                        }
2989                    } else {
2990                        // A gap, we can stop here.
2991                        break;
2992                    }
2993                }
2994            } else {
2995                // Process has activities, put it at the very tipsy-top.
2996                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2997                mLruProcesses.add(app);
2998            }
2999            nextIndex = mLruProcessServiceStart;
3000        } else if (hasService) {
3001            // Process has services, put it at the top of the service list.
3002            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3003            mLruProcesses.add(mLruProcessActivityStart, app);
3004            nextIndex = mLruProcessServiceStart;
3005            mLruProcessActivityStart++;
3006        } else  {
3007            // Process not otherwise of interest, it goes to the top of the non-service area.
3008            int index = mLruProcessServiceStart;
3009            if (client != null) {
3010                // If there is a client, don't allow the process to be moved up higher
3011                // in the list than that client.
3012                int clientIndex = mLruProcesses.lastIndexOf(client);
3013                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3014                        + " when updating " + app);
3015                if (clientIndex <= lrui) {
3016                    // Don't allow the client index restriction to push it down farther in the
3017                    // list than it already is.
3018                    clientIndex = lrui;
3019                }
3020                if (clientIndex >= 0 && index > clientIndex) {
3021                    index = clientIndex;
3022                }
3023            }
3024            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3025            mLruProcesses.add(index, app);
3026            nextIndex = index-1;
3027            mLruProcessActivityStart++;
3028            mLruProcessServiceStart++;
3029        }
3030
3031        // If the app is currently using a content provider or service,
3032        // bump those processes as well.
3033        for (int j=app.connections.size()-1; j>=0; j--) {
3034            ConnectionRecord cr = app.connections.valueAt(j);
3035            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3036                    && cr.binding.service.app != null
3037                    && cr.binding.service.app.lruSeq != mLruSeq
3038                    && !cr.binding.service.app.persistent) {
3039                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3040                        "service connection", cr, app);
3041            }
3042        }
3043        for (int j=app.conProviders.size()-1; j>=0; j--) {
3044            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3045            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3046                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3047                        "provider reference", cpr, app);
3048            }
3049        }
3050    }
3051
3052    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3053        if (uid == Process.SYSTEM_UID) {
3054            // The system gets to run in any process.  If there are multiple
3055            // processes with the same uid, just pick the first (this
3056            // should never happen).
3057            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3058            if (procs == null) return null;
3059            final int procCount = procs.size();
3060            for (int i = 0; i < procCount; i++) {
3061                final int procUid = procs.keyAt(i);
3062                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3063                    // Don't use an app process or different user process for system component.
3064                    continue;
3065                }
3066                return procs.valueAt(i);
3067            }
3068        }
3069        ProcessRecord proc = mProcessNames.get(processName, uid);
3070        if (false && proc != null && !keepIfLarge
3071                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3072                && proc.lastCachedPss >= 4000) {
3073            // Turn this condition on to cause killing to happen regularly, for testing.
3074            if (proc.baseProcessTracker != null) {
3075                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3076            }
3077            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3078        } else if (proc != null && !keepIfLarge
3079                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3080                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3081            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3082            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3083                if (proc.baseProcessTracker != null) {
3084                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3085                }
3086                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3087            }
3088        }
3089        return proc;
3090    }
3091
3092    void notifyPackageUse(String packageName) {
3093        IPackageManager pm = AppGlobals.getPackageManager();
3094        try {
3095            pm.notifyPackageUse(packageName);
3096        } catch (RemoteException e) {
3097        }
3098    }
3099
3100    boolean isNextTransitionForward() {
3101        int transit = mWindowManager.getPendingAppTransition();
3102        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3103                || transit == AppTransition.TRANSIT_TASK_OPEN
3104                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3105    }
3106
3107    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3108            String processName, String abiOverride, int uid, Runnable crashHandler) {
3109        synchronized(this) {
3110            ApplicationInfo info = new ApplicationInfo();
3111            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3112            // For isolated processes, the former contains the parent's uid and the latter the
3113            // actual uid of the isolated process.
3114            // In the special case introduced by this method (which is, starting an isolated
3115            // process directly from the SystemServer without an actual parent app process) the
3116            // closest thing to a parent's uid is SYSTEM_UID.
3117            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3118            // the |isolated| logic in the ProcessRecord constructor.
3119            info.uid = Process.SYSTEM_UID;
3120            info.processName = processName;
3121            info.className = entryPoint;
3122            info.packageName = "android";
3123            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3124                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3125                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3126                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3127                    crashHandler);
3128            return proc != null ? proc.pid : 0;
3129        }
3130    }
3131
3132    final ProcessRecord startProcessLocked(String processName,
3133            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3134            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3135            boolean isolated, boolean keepIfLarge) {
3136        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3137                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3138                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3139                null /* crashHandler */);
3140    }
3141
3142    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3143            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3144            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3145            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3146        long startTime = SystemClock.elapsedRealtime();
3147        ProcessRecord app;
3148        if (!isolated) {
3149            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3150            checkTime(startTime, "startProcess: after getProcessRecord");
3151
3152            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3153                // If we are in the background, then check to see if this process
3154                // is bad.  If so, we will just silently fail.
3155                if (mBadProcesses.get(info.processName, info.uid) != null) {
3156                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3157                            + "/" + info.processName);
3158                    return null;
3159                }
3160            } else {
3161                // When the user is explicitly starting a process, then clear its
3162                // crash count so that we won't make it bad until they see at
3163                // least one crash dialog again, and make the process good again
3164                // if it had been bad.
3165                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3166                        + "/" + info.processName);
3167                mProcessCrashTimes.remove(info.processName, info.uid);
3168                if (mBadProcesses.get(info.processName, info.uid) != null) {
3169                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3170                            UserHandle.getUserId(info.uid), info.uid,
3171                            info.processName);
3172                    mBadProcesses.remove(info.processName, info.uid);
3173                    if (app != null) {
3174                        app.bad = false;
3175                    }
3176                }
3177            }
3178        } else {
3179            // If this is an isolated process, it can't re-use an existing process.
3180            app = null;
3181        }
3182
3183        // app launch boost for big.little configurations
3184        // use cpusets to migrate freshly launched tasks to big cores
3185        synchronized(ActivityManagerService.this) {
3186            nativeMigrateToBoost();
3187            mIsBoosted = true;
3188            mBoostStartTime = SystemClock.uptimeMillis();
3189            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3190            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3191        }
3192
3193        // We don't have to do anything more if:
3194        // (1) There is an existing application record; and
3195        // (2) The caller doesn't think it is dead, OR there is no thread
3196        //     object attached to it so we know it couldn't have crashed; and
3197        // (3) There is a pid assigned to it, so it is either starting or
3198        //     already running.
3199        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3200                + " app=" + app + " knownToBeDead=" + knownToBeDead
3201                + " thread=" + (app != null ? app.thread : null)
3202                + " pid=" + (app != null ? app.pid : -1));
3203        if (app != null && app.pid > 0) {
3204            if (!knownToBeDead || app.thread == null) {
3205                // We already have the app running, or are waiting for it to
3206                // come up (we have a pid but not yet its thread), so keep it.
3207                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
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: done, added package to proc");
3211                return app;
3212            }
3213
3214            // An application record is attached to a previous process,
3215            // clean it up now.
3216            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3217            checkTime(startTime, "startProcess: bad proc running, killing");
3218            killProcessGroup(app.info.uid, app.pid);
3219            handleAppDiedLocked(app, true, true);
3220            checkTime(startTime, "startProcess: done killing old proc");
3221        }
3222
3223        String hostingNameStr = hostingName != null
3224                ? hostingName.flattenToShortString() : null;
3225
3226        if (app == null) {
3227            checkTime(startTime, "startProcess: creating new process record");
3228            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3229            if (app == null) {
3230                Slog.w(TAG, "Failed making new process record for "
3231                        + processName + "/" + info.uid + " isolated=" + isolated);
3232                return null;
3233            }
3234            app.crashHandler = crashHandler;
3235            checkTime(startTime, "startProcess: done creating new process record");
3236        } else {
3237            // If this is a new package in the process, add the package to the list
3238            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3239            checkTime(startTime, "startProcess: added package to existing proc");
3240        }
3241
3242        // If the system is not ready yet, then hold off on starting this
3243        // process until it is.
3244        if (!mProcessesReady
3245                && !isAllowedWhileBooting(info)
3246                && !allowWhileBooting) {
3247            if (!mProcessesOnHold.contains(app)) {
3248                mProcessesOnHold.add(app);
3249            }
3250            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3251                    "System not ready, putting on hold: " + app);
3252            checkTime(startTime, "startProcess: returning with proc on hold");
3253            return app;
3254        }
3255
3256        checkTime(startTime, "startProcess: stepping in to startProcess");
3257        startProcessLocked(
3258                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3259        checkTime(startTime, "startProcess: done starting proc!");
3260        return (app.pid != 0) ? app : null;
3261    }
3262
3263    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3264        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3265    }
3266
3267    private final void startProcessLocked(ProcessRecord app,
3268            String hostingType, String hostingNameStr) {
3269        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3270                null /* entryPoint */, null /* entryPointArgs */);
3271    }
3272
3273    private final void startProcessLocked(ProcessRecord app, String hostingType,
3274            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3275        long startTime = SystemClock.elapsedRealtime();
3276        if (app.pid > 0 && app.pid != MY_PID) {
3277            checkTime(startTime, "startProcess: removing from pids map");
3278            synchronized (mPidsSelfLocked) {
3279                mPidsSelfLocked.remove(app.pid);
3280                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3281            }
3282            checkTime(startTime, "startProcess: done removing from pids map");
3283            app.setPid(0);
3284        }
3285
3286        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3287                "startProcessLocked removing on hold: " + app);
3288        mProcessesOnHold.remove(app);
3289
3290        checkTime(startTime, "startProcess: starting to update cpu stats");
3291        updateCpuStats();
3292        checkTime(startTime, "startProcess: done updating cpu stats");
3293
3294        try {
3295            try {
3296                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3297                    // This is caught below as if we had failed to fork zygote
3298                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3299                }
3300            } catch (RemoteException e) {
3301                throw e.rethrowAsRuntimeException();
3302            }
3303
3304            int uid = app.uid;
3305            int[] gids = null;
3306            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3307            if (!app.isolated) {
3308                int[] permGids = null;
3309                try {
3310                    checkTime(startTime, "startProcess: getting gids from package manager");
3311                    final IPackageManager pm = AppGlobals.getPackageManager();
3312                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3313                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3314                            MountServiceInternal.class);
3315                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3316                            app.info.packageName);
3317                } catch (RemoteException e) {
3318                    throw e.rethrowAsRuntimeException();
3319                }
3320
3321                /*
3322                 * Add shared application and profile GIDs so applications can share some
3323                 * resources like shared libraries and access user-wide resources
3324                 */
3325                if (ArrayUtils.isEmpty(permGids)) {
3326                    gids = new int[2];
3327                } else {
3328                    gids = new int[permGids.length + 2];
3329                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3330                }
3331                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3332                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3333            }
3334            checkTime(startTime, "startProcess: building args");
3335            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3336                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3337                        && mTopComponent != null
3338                        && app.processName.equals(mTopComponent.getPackageName())) {
3339                    uid = 0;
3340                }
3341                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3342                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3343                    uid = 0;
3344                }
3345            }
3346            int debugFlags = 0;
3347            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3348                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3349                // Also turn on CheckJNI for debuggable apps. It's quite
3350                // awkward to turn on otherwise.
3351                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3352            }
3353            // Run the app in safe mode if its manifest requests so or the
3354            // system is booted in safe mode.
3355            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3356                mSafeMode == true) {
3357                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3358            }
3359            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3360                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3361            }
3362            String jitDebugProperty = SystemProperties.get("debug.usejit");
3363            if ("true".equals(jitDebugProperty)) {
3364                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3365            } else if (!"false".equals(jitDebugProperty)) {
3366                // If we didn't force disable by setting false, defer to the dalvik vm options.
3367                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3368                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3369                }
3370            }
3371            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3372            if ("true".equals(genDebugInfoProperty)) {
3373                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3374            }
3375            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3376                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3377            }
3378            if ("1".equals(SystemProperties.get("debug.assert"))) {
3379                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3380            }
3381
3382            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3383            if (requiredAbi == null) {
3384                requiredAbi = Build.SUPPORTED_ABIS[0];
3385            }
3386
3387            String instructionSet = null;
3388            if (app.info.primaryCpuAbi != null) {
3389                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3390            }
3391
3392            app.gids = gids;
3393            app.requiredAbi = requiredAbi;
3394            app.instructionSet = instructionSet;
3395
3396            // Start the process.  It will either succeed and return a result containing
3397            // the PID of the new process, or else throw a RuntimeException.
3398            boolean isActivityProcess = (entryPoint == null);
3399            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3400            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3401                    app.processName);
3402            checkTime(startTime, "startProcess: asking zygote to start proc");
3403            Process.ProcessStartResult startResult = Process.start(entryPoint,
3404                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3405                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3406                    app.info.dataDir, entryPointArgs);
3407            checkTime(startTime, "startProcess: returned from zygote!");
3408            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3409
3410            if (app.isolated) {
3411                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3412            }
3413            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3414            checkTime(startTime, "startProcess: done updating battery stats");
3415
3416            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3417                    UserHandle.getUserId(uid), startResult.pid, uid,
3418                    app.processName, hostingType,
3419                    hostingNameStr != null ? hostingNameStr : "");
3420
3421            if (app.persistent) {
3422                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3423            }
3424
3425            checkTime(startTime, "startProcess: building log message");
3426            StringBuilder buf = mStringBuilder;
3427            buf.setLength(0);
3428            buf.append("Start proc ");
3429            buf.append(startResult.pid);
3430            buf.append(':');
3431            buf.append(app.processName);
3432            buf.append('/');
3433            UserHandle.formatUid(buf, uid);
3434            if (!isActivityProcess) {
3435                buf.append(" [");
3436                buf.append(entryPoint);
3437                buf.append("]");
3438            }
3439            buf.append(" for ");
3440            buf.append(hostingType);
3441            if (hostingNameStr != null) {
3442                buf.append(" ");
3443                buf.append(hostingNameStr);
3444            }
3445            Slog.i(TAG, buf.toString());
3446            app.setPid(startResult.pid);
3447            app.usingWrapper = startResult.usingWrapper;
3448            app.removed = false;
3449            app.killed = false;
3450            app.killedByAm = false;
3451            checkTime(startTime, "startProcess: starting to update pids map");
3452            synchronized (mPidsSelfLocked) {
3453                this.mPidsSelfLocked.put(startResult.pid, app);
3454                if (isActivityProcess) {
3455                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3456                    msg.obj = app;
3457                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3458                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3459                }
3460            }
3461            checkTime(startTime, "startProcess: done updating pids map");
3462        } catch (RuntimeException e) {
3463            // XXX do better error recovery.
3464            app.setPid(0);
3465            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3466            if (app.isolated) {
3467                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3468            }
3469            Slog.e(TAG, "Failure starting process " + app.processName, e);
3470        }
3471    }
3472
3473    void updateUsageStats(ActivityRecord component, boolean resumed) {
3474        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3475                "updateUsageStats: comp=" + component + "res=" + resumed);
3476        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3477        if (resumed) {
3478            if (mUsageStatsService != null) {
3479                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3480                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3481            }
3482            synchronized (stats) {
3483                stats.noteActivityResumedLocked(component.app.uid);
3484            }
3485        } else {
3486            if (mUsageStatsService != null) {
3487                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3488                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3489            }
3490            synchronized (stats) {
3491                stats.noteActivityPausedLocked(component.app.uid);
3492            }
3493        }
3494    }
3495
3496    Intent getHomeIntent() {
3497        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3498        intent.setComponent(mTopComponent);
3499        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3500            intent.addCategory(Intent.CATEGORY_HOME);
3501        }
3502        return intent;
3503    }
3504
3505    boolean startHomeActivityLocked(int userId, String reason) {
3506        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3507                && mTopAction == null) {
3508            // We are running in factory test mode, but unable to find
3509            // the factory test app, so just sit around displaying the
3510            // error message and don't try to start anything.
3511            return false;
3512        }
3513        Intent intent = getHomeIntent();
3514        ActivityInfo aInfo =
3515            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3516        if (aInfo != null) {
3517            intent.setComponent(new ComponentName(
3518                    aInfo.applicationInfo.packageName, aInfo.name));
3519            // Don't do this if the home app is currently being
3520            // instrumented.
3521            aInfo = new ActivityInfo(aInfo);
3522            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3523            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3524                    aInfo.applicationInfo.uid, true);
3525            if (app == null || app.instrumentationClass == null) {
3526                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3527                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3528            }
3529        }
3530
3531        return true;
3532    }
3533
3534    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3535        ActivityInfo ai = null;
3536        ComponentName comp = intent.getComponent();
3537        try {
3538            if (comp != null) {
3539                // Factory test.
3540                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3541            } else {
3542                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3543                        intent,
3544                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3545                        flags, userId);
3546
3547                if (info != null) {
3548                    ai = info.activityInfo;
3549                }
3550            }
3551        } catch (RemoteException e) {
3552            // ignore
3553        }
3554
3555        return ai;
3556    }
3557
3558    /**
3559     * Starts the "new version setup screen" if appropriate.
3560     */
3561    void startSetupActivityLocked() {
3562        // Only do this once per boot.
3563        if (mCheckedForSetup) {
3564            return;
3565        }
3566
3567        // We will show this screen if the current one is a different
3568        // version than the last one shown, and we are not running in
3569        // low-level factory test mode.
3570        final ContentResolver resolver = mContext.getContentResolver();
3571        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3572                Settings.Global.getInt(resolver,
3573                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3574            mCheckedForSetup = true;
3575
3576            // See if we should be showing the platform update setup UI.
3577            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3578            List<ResolveInfo> ris = mContext.getPackageManager()
3579                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3580
3581            // We don't allow third party apps to replace this.
3582            ResolveInfo ri = null;
3583            for (int i=0; ris != null && i<ris.size(); i++) {
3584                if ((ris.get(i).activityInfo.applicationInfo.flags
3585                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3586                    ri = ris.get(i);
3587                    break;
3588                }
3589            }
3590
3591            if (ri != null) {
3592                String vers = ri.activityInfo.metaData != null
3593                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3594                        : null;
3595                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3596                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3597                            Intent.METADATA_SETUP_VERSION);
3598                }
3599                String lastVers = Settings.Secure.getString(
3600                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3601                if (vers != null && !vers.equals(lastVers)) {
3602                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3603                    intent.setComponent(new ComponentName(
3604                            ri.activityInfo.packageName, ri.activityInfo.name));
3605                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3606                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3607                            null, null, null);
3608                }
3609            }
3610        }
3611    }
3612
3613    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3614        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3615    }
3616
3617    void enforceNotIsolatedCaller(String caller) {
3618        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3619            throw new SecurityException("Isolated process not allowed to call " + caller);
3620        }
3621    }
3622
3623    void enforceShellRestriction(String restriction, int userHandle) {
3624        if (Binder.getCallingUid() == Process.SHELL_UID) {
3625            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3626                throw new SecurityException("Shell does not have permission to access user "
3627                        + userHandle);
3628            }
3629        }
3630    }
3631
3632    @Override
3633    public int getFrontActivityScreenCompatMode() {
3634        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3635        synchronized (this) {
3636            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3637        }
3638    }
3639
3640    @Override
3641    public void setFrontActivityScreenCompatMode(int mode) {
3642        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3643                "setFrontActivityScreenCompatMode");
3644        synchronized (this) {
3645            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3646        }
3647    }
3648
3649    @Override
3650    public int getPackageScreenCompatMode(String packageName) {
3651        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3652        synchronized (this) {
3653            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3654        }
3655    }
3656
3657    @Override
3658    public void setPackageScreenCompatMode(String packageName, int mode) {
3659        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3660                "setPackageScreenCompatMode");
3661        synchronized (this) {
3662            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3663        }
3664    }
3665
3666    @Override
3667    public boolean getPackageAskScreenCompat(String packageName) {
3668        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3669        synchronized (this) {
3670            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3671        }
3672    }
3673
3674    @Override
3675    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3676        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3677                "setPackageAskScreenCompat");
3678        synchronized (this) {
3679            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3680        }
3681    }
3682
3683    private boolean hasUsageStatsPermission(String callingPackage) {
3684        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3685                Binder.getCallingUid(), callingPackage);
3686        if (mode == AppOpsManager.MODE_DEFAULT) {
3687            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3688                    == PackageManager.PERMISSION_GRANTED;
3689        }
3690        return mode == AppOpsManager.MODE_ALLOWED;
3691    }
3692
3693    @Override
3694    public int getPackageProcessState(String packageName, String callingPackage) {
3695        if (!hasUsageStatsPermission(callingPackage)) {
3696            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3697                    "getPackageProcessState");
3698        }
3699
3700        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3701        synchronized (this) {
3702            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3703                final ProcessRecord proc = mLruProcesses.get(i);
3704                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3705                        || procState > proc.setProcState) {
3706                    boolean found = false;
3707                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3708                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3709                            procState = proc.setProcState;
3710                            found = true;
3711                        }
3712                    }
3713                    if (proc.pkgDeps != null && !found) {
3714                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3715                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3716                                procState = proc.setProcState;
3717                                break;
3718                            }
3719                        }
3720                    }
3721                }
3722            }
3723        }
3724        return procState;
3725    }
3726
3727    @Override
3728    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3729        synchronized (this) {
3730            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3731            if (app == null) {
3732                return false;
3733            }
3734            if (app.trimMemoryLevel < level && app.thread != null &&
3735                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3736                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3737                try {
3738                    app.thread.scheduleTrimMemory(level);
3739                    app.trimMemoryLevel = level;
3740                    return true;
3741                } catch (RemoteException e) {
3742                    // Fallthrough to failure case.
3743                }
3744            }
3745        }
3746        return false;
3747    }
3748
3749    private void dispatchProcessesChanged() {
3750        int N;
3751        synchronized (this) {
3752            N = mPendingProcessChanges.size();
3753            if (mActiveProcessChanges.length < N) {
3754                mActiveProcessChanges = new ProcessChangeItem[N];
3755            }
3756            mPendingProcessChanges.toArray(mActiveProcessChanges);
3757            mPendingProcessChanges.clear();
3758            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3759                    "*** Delivering " + N + " process changes");
3760        }
3761
3762        int i = mProcessObservers.beginBroadcast();
3763        while (i > 0) {
3764            i--;
3765            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3766            if (observer != null) {
3767                try {
3768                    for (int j=0; j<N; j++) {
3769                        ProcessChangeItem item = mActiveProcessChanges[j];
3770                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3771                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3772                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3773                                    + item.uid + ": " + item.foregroundActivities);
3774                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3775                                    item.foregroundActivities);
3776                        }
3777                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3778                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3779                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3780                                    + ": " + item.processState);
3781                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3782                        }
3783                    }
3784                } catch (RemoteException e) {
3785                }
3786            }
3787        }
3788        mProcessObservers.finishBroadcast();
3789
3790        synchronized (this) {
3791            for (int j=0; j<N; j++) {
3792                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3793            }
3794        }
3795    }
3796
3797    private void dispatchProcessDied(int pid, int uid) {
3798        int i = mProcessObservers.beginBroadcast();
3799        while (i > 0) {
3800            i--;
3801            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3802            if (observer != null) {
3803                try {
3804                    observer.onProcessDied(pid, uid);
3805                } catch (RemoteException e) {
3806                }
3807            }
3808        }
3809        mProcessObservers.finishBroadcast();
3810    }
3811
3812    private void dispatchUidsChanged() {
3813        int N;
3814        synchronized (this) {
3815            N = mPendingUidChanges.size();
3816            if (mActiveUidChanges.length < N) {
3817                mActiveUidChanges = new UidRecord.ChangeItem[N];
3818            }
3819            for (int i=0; i<N; i++) {
3820                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3821                mActiveUidChanges[i] = change;
3822                if (change.uidRecord != null) {
3823                    change.uidRecord.pendingChange = null;
3824                    change.uidRecord = null;
3825                }
3826            }
3827            mPendingUidChanges.clear();
3828            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3829                    "*** Delivering " + N + " uid changes");
3830        }
3831
3832        if (mLocalPowerManager != null) {
3833            for (int j=0; j<N; j++) {
3834                UidRecord.ChangeItem item = mActiveUidChanges[j];
3835                if (item.change == UidRecord.CHANGE_GONE
3836                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3837                    mLocalPowerManager.uidGone(item.uid);
3838                } else {
3839                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3840                }
3841            }
3842        }
3843
3844        int i = mUidObservers.beginBroadcast();
3845        while (i > 0) {
3846            i--;
3847            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3848            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3849            if (observer != null) {
3850                try {
3851                    for (int j=0; j<N; j++) {
3852                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3853                        final int change = item.change;
3854                        UidRecord validateUid = null;
3855                        if (VALIDATE_UID_STATES && i == 0) {
3856                            validateUid = mValidateUids.get(item.uid);
3857                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3858                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3859                                validateUid = new UidRecord(item.uid);
3860                                mValidateUids.put(item.uid, validateUid);
3861                            }
3862                        }
3863                        if (change == UidRecord.CHANGE_IDLE
3864                                || change == UidRecord.CHANGE_GONE_IDLE) {
3865                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3866                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3867                                        "UID idle uid=" + item.uid);
3868                                observer.onUidIdle(item.uid);
3869                            }
3870                            if (VALIDATE_UID_STATES && i == 0) {
3871                                if (validateUid != null) {
3872                                    validateUid.idle = true;
3873                                }
3874                            }
3875                        } else if (change == UidRecord.CHANGE_ACTIVE) {
3876                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3877                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3878                                        "UID active uid=" + item.uid);
3879                                observer.onUidActive(item.uid);
3880                            }
3881                            if (VALIDATE_UID_STATES && i == 0) {
3882                                validateUid.idle = false;
3883                            }
3884                        }
3885                        if (change == UidRecord.CHANGE_GONE
3886                                || change == UidRecord.CHANGE_GONE_IDLE) {
3887                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
3888                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3889                                        "UID gone uid=" + item.uid);
3890                                observer.onUidGone(item.uid);
3891                            }
3892                            if (VALIDATE_UID_STATES && i == 0) {
3893                                if (validateUid != null) {
3894                                    mValidateUids.remove(item.uid);
3895                                }
3896                            }
3897                        } else {
3898                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
3899                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3900                                        "UID CHANGED uid=" + item.uid
3901                                                + ": " + item.processState);
3902                                observer.onUidStateChanged(item.uid, item.processState);
3903                            }
3904                            if (VALIDATE_UID_STATES && i == 0) {
3905                                validateUid.curProcState = validateUid.setProcState
3906                                        = item.processState;
3907                            }
3908                        }
3909                    }
3910                } catch (RemoteException e) {
3911                }
3912            }
3913        }
3914        mUidObservers.finishBroadcast();
3915
3916        synchronized (this) {
3917            for (int j=0; j<N; j++) {
3918                mAvailUidChanges.add(mActiveUidChanges[j]);
3919            }
3920        }
3921    }
3922
3923    @Override
3924    public final int startActivity(IApplicationThread caller, String callingPackage,
3925            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3926            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
3927        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3928                resultWho, requestCode, startFlags, profilerInfo, bOptions,
3929                UserHandle.getCallingUserId());
3930    }
3931
3932    @Override
3933    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3934            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3935            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3936        enforceNotIsolatedCaller("startActivity");
3937        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3938                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
3939        // TODO: Switch to user app stacks here.
3940        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3941                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3942                profilerInfo, null, null, bOptions, false, userId, null, null);
3943    }
3944
3945    @Override
3946    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3947            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3948            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
3949            int userId) {
3950
3951        // This is very dangerous -- it allows you to perform a start activity (including
3952        // permission grants) as any app that may launch one of your own activities.  So
3953        // we will only allow this to be done from activities that are part of the core framework,
3954        // and then only when they are running as the system.
3955        final ActivityRecord sourceRecord;
3956        final int targetUid;
3957        final String targetPackage;
3958        synchronized (this) {
3959            if (resultTo == null) {
3960                throw new SecurityException("Must be called from an activity");
3961            }
3962            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3963            if (sourceRecord == null) {
3964                throw new SecurityException("Called with bad activity token: " + resultTo);
3965            }
3966            if (!sourceRecord.info.packageName.equals("android")) {
3967                throw new SecurityException(
3968                        "Must be called from an activity that is declared in the android package");
3969            }
3970            if (sourceRecord.app == null) {
3971                throw new SecurityException("Called without a process attached to activity");
3972            }
3973            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3974                // This is still okay, as long as this activity is running under the
3975                // uid of the original calling activity.
3976                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3977                    throw new SecurityException(
3978                            "Calling activity in uid " + sourceRecord.app.uid
3979                                    + " must be system uid or original calling uid "
3980                                    + sourceRecord.launchedFromUid);
3981                }
3982            }
3983            if (ignoreTargetSecurity) {
3984                if (intent.getComponent() == null) {
3985                    throw new SecurityException(
3986                            "Component must be specified with ignoreTargetSecurity");
3987                }
3988                if (intent.getSelector() != null) {
3989                    throw new SecurityException(
3990                            "Selector not allowed with ignoreTargetSecurity");
3991                }
3992            }
3993            targetUid = sourceRecord.launchedFromUid;
3994            targetPackage = sourceRecord.launchedFromPackage;
3995        }
3996
3997        if (userId == UserHandle.USER_NULL) {
3998            userId = UserHandle.getUserId(sourceRecord.app.uid);
3999        }
4000
4001        // TODO: Switch to user app stacks here.
4002        try {
4003            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
4004                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4005                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4006            return ret;
4007        } catch (SecurityException e) {
4008            // XXX need to figure out how to propagate to original app.
4009            // A SecurityException here is generally actually a fault of the original
4010            // calling activity (such as a fairly granting permissions), so propagate it
4011            // back to them.
4012            /*
4013            StringBuilder msg = new StringBuilder();
4014            msg.append("While launching");
4015            msg.append(intent.toString());
4016            msg.append(": ");
4017            msg.append(e.getMessage());
4018            */
4019            throw e;
4020        }
4021    }
4022
4023    @Override
4024    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4025            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4026            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4027        enforceNotIsolatedCaller("startActivityAndWait");
4028        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4029                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4030        WaitResult res = new WaitResult();
4031        // TODO: Switch to user app stacks here.
4032        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4033                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4034                bOptions, false, userId, null, null);
4035        return res;
4036    }
4037
4038    @Override
4039    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4040            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4041            int startFlags, Configuration config, Bundle bOptions, int userId) {
4042        enforceNotIsolatedCaller("startActivityWithConfig");
4043        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4044                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4045        // TODO: Switch to user app stacks here.
4046        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4047                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4048                null, null, config, bOptions, false, userId, null, null);
4049        return ret;
4050    }
4051
4052    @Override
4053    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4054            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4055            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4056            throws TransactionTooLargeException {
4057        enforceNotIsolatedCaller("startActivityIntentSender");
4058        // Refuse possible leaked file descriptors
4059        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4060            throw new IllegalArgumentException("File descriptors passed in Intent");
4061        }
4062
4063        IIntentSender sender = intent.getTarget();
4064        if (!(sender instanceof PendingIntentRecord)) {
4065            throw new IllegalArgumentException("Bad PendingIntent object");
4066        }
4067
4068        PendingIntentRecord pir = (PendingIntentRecord)sender;
4069
4070        synchronized (this) {
4071            // If this is coming from the currently resumed activity, it is
4072            // effectively saying that app switches are allowed at this point.
4073            final ActivityStack stack = getFocusedStack();
4074            if (stack.mResumedActivity != null &&
4075                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4076                mAppSwitchesAllowedTime = 0;
4077            }
4078        }
4079        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4080                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4081        return ret;
4082    }
4083
4084    @Override
4085    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4086            Intent intent, String resolvedType, IVoiceInteractionSession session,
4087            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4088            Bundle bOptions, int userId) {
4089        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4090                != PackageManager.PERMISSION_GRANTED) {
4091            String msg = "Permission Denial: startVoiceActivity() from pid="
4092                    + Binder.getCallingPid()
4093                    + ", uid=" + Binder.getCallingUid()
4094                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4095            Slog.w(TAG, msg);
4096            throw new SecurityException(msg);
4097        }
4098        if (session == null || interactor == null) {
4099            throw new NullPointerException("null session or interactor");
4100        }
4101        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4102                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4103        // TODO: Switch to user app stacks here.
4104        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4105                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4106                null, bOptions, false, userId, null, null);
4107    }
4108
4109    @Override
4110    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4111        synchronized (this) {
4112            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4113                if (keepAwake) {
4114                    mVoiceWakeLock.acquire();
4115                } else {
4116                    mVoiceWakeLock.release();
4117                }
4118            }
4119        }
4120    }
4121
4122    @Override
4123    public boolean startNextMatchingActivity(IBinder callingActivity,
4124            Intent intent, Bundle bOptions) {
4125        // Refuse possible leaked file descriptors
4126        if (intent != null && intent.hasFileDescriptors() == true) {
4127            throw new IllegalArgumentException("File descriptors passed in Intent");
4128        }
4129        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4130
4131        synchronized (this) {
4132            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4133            if (r == null) {
4134                ActivityOptions.abort(options);
4135                return false;
4136            }
4137            if (r.app == null || r.app.thread == null) {
4138                // The caller is not running...  d'oh!
4139                ActivityOptions.abort(options);
4140                return false;
4141            }
4142            intent = new Intent(intent);
4143            // The caller is not allowed to change the data.
4144            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4145            // And we are resetting to find the next component...
4146            intent.setComponent(null);
4147
4148            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4149
4150            ActivityInfo aInfo = null;
4151            try {
4152                List<ResolveInfo> resolves =
4153                    AppGlobals.getPackageManager().queryIntentActivities(
4154                            intent, r.resolvedType,
4155                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4156                            UserHandle.getCallingUserId());
4157
4158                // Look for the original activity in the list...
4159                final int N = resolves != null ? resolves.size() : 0;
4160                for (int i=0; i<N; i++) {
4161                    ResolveInfo rInfo = resolves.get(i);
4162                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4163                            && rInfo.activityInfo.name.equals(r.info.name)) {
4164                        // We found the current one...  the next matching is
4165                        // after it.
4166                        i++;
4167                        if (i<N) {
4168                            aInfo = resolves.get(i).activityInfo;
4169                        }
4170                        if (debug) {
4171                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4172                                    + "/" + r.info.name);
4173                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4174                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4175                        }
4176                        break;
4177                    }
4178                }
4179            } catch (RemoteException e) {
4180            }
4181
4182            if (aInfo == null) {
4183                // Nobody who is next!
4184                ActivityOptions.abort(options);
4185                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4186                return false;
4187            }
4188
4189            intent.setComponent(new ComponentName(
4190                    aInfo.applicationInfo.packageName, aInfo.name));
4191            intent.setFlags(intent.getFlags()&~(
4192                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4193                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4194                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4195                    Intent.FLAG_ACTIVITY_NEW_TASK));
4196
4197            // Okay now we need to start the new activity, replacing the
4198            // currently running activity.  This is a little tricky because
4199            // we want to start the new one as if the current one is finished,
4200            // but not finish the current one first so that there is no flicker.
4201            // And thus...
4202            final boolean wasFinishing = r.finishing;
4203            r.finishing = true;
4204
4205            // Propagate reply information over to the new activity.
4206            final ActivityRecord resultTo = r.resultTo;
4207            final String resultWho = r.resultWho;
4208            final int requestCode = r.requestCode;
4209            r.resultTo = null;
4210            if (resultTo != null) {
4211                resultTo.removeResultsLocked(r, resultWho, requestCode);
4212            }
4213
4214            final long origId = Binder.clearCallingIdentity();
4215            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4216                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4217                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4218                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4219            Binder.restoreCallingIdentity(origId);
4220
4221            r.finishing = wasFinishing;
4222            if (res != ActivityManager.START_SUCCESS) {
4223                return false;
4224            }
4225            return true;
4226        }
4227    }
4228
4229    @Override
4230    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4231        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4232            String msg = "Permission Denial: startActivityFromRecents called without " +
4233                    START_TASKS_FROM_RECENTS;
4234            Slog.w(TAG, msg);
4235            throw new SecurityException(msg);
4236        }
4237        final long origId = Binder.clearCallingIdentity();
4238        try {
4239            return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4240        } finally {
4241            Binder.restoreCallingIdentity(origId);
4242        }
4243    }
4244
4245    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4246        final TaskRecord task;
4247        final int callingUid;
4248        final String callingPackage;
4249        final Intent intent;
4250        final int userId;
4251        synchronized (this) {
4252            if (launchStackId == HOME_STACK_ID) {
4253                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4254                        + taskId + " can't be launch in the home stack.");
4255            }
4256
4257            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4258            if (task == null) {
4259                throw new IllegalArgumentException(
4260                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4261            }
4262
4263            if (launchStackId != INVALID_STACK_ID) {
4264                if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4265                    ActivityOptions activityOptions = new ActivityOptions(bOptions);
4266                    mWindowManager.setDockedStackCreateMode(activityOptions.getDockCreateMode());
4267                }
4268                if (task.stack.mStackId != launchStackId) {
4269                    mStackSupervisor.moveTaskToStackLocked(
4270                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents");
4271                }
4272            }
4273
4274            if (task.getRootActivity() != null) {
4275                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4276                return ActivityManager.START_TASK_TO_FRONT;
4277            }
4278            callingUid = task.mCallingUid;
4279            callingPackage = task.mCallingPackage;
4280            intent = task.intent;
4281            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4282            userId = task.userId;
4283        }
4284        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4285                bOptions, userId, null, task);
4286    }
4287
4288    final int startActivityInPackage(int uid, String callingPackage,
4289            Intent intent, String resolvedType, IBinder resultTo,
4290            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4291            IActivityContainer container, TaskRecord inTask) {
4292
4293        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4294                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4295
4296        // TODO: Switch to user app stacks here.
4297        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4298                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4299                null, null, null, bOptions, false, userId, container, inTask);
4300        return ret;
4301    }
4302
4303    @Override
4304    public final int startActivities(IApplicationThread caller, String callingPackage,
4305            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4306            int userId) {
4307        enforceNotIsolatedCaller("startActivities");
4308        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4309                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4310        // TODO: Switch to user app stacks here.
4311        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4312                resolvedTypes, resultTo, bOptions, userId);
4313        return ret;
4314    }
4315
4316    final int startActivitiesInPackage(int uid, String callingPackage,
4317            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4318            Bundle bOptions, int userId) {
4319
4320        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4321                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4322        // TODO: Switch to user app stacks here.
4323        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4324                resultTo, bOptions, userId);
4325        return ret;
4326    }
4327
4328    @Override
4329    public void reportActivityFullyDrawn(IBinder token) {
4330        synchronized (this) {
4331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4332            if (r == null) {
4333                return;
4334            }
4335            r.reportFullyDrawnLocked();
4336        }
4337    }
4338
4339    @Override
4340    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4341        synchronized (this) {
4342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4343            if (r == null) {
4344                return;
4345            }
4346            if (r.task != null && r.task.mResizeable) {
4347                // Fixed screen orientation isn't supported with resizeable activities.
4348                return;
4349            }
4350            final long origId = Binder.clearCallingIdentity();
4351            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4352            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4353                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4354            if (config != null) {
4355                r.frozenBeforeDestroy = true;
4356                if (!updateConfigurationLocked(config, r, false)) {
4357                    mStackSupervisor.resumeTopActivitiesLocked();
4358                }
4359            }
4360            Binder.restoreCallingIdentity(origId);
4361        }
4362    }
4363
4364    @Override
4365    public int getRequestedOrientation(IBinder token) {
4366        synchronized (this) {
4367            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4368            if (r == null) {
4369                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4370            }
4371            return mWindowManager.getAppOrientation(r.appToken);
4372        }
4373    }
4374
4375    /**
4376     * This is the internal entry point for handling Activity.finish().
4377     *
4378     * @param token The Binder token referencing the Activity we want to finish.
4379     * @param resultCode Result code, if any, from this Activity.
4380     * @param resultData Result data (Intent), if any, from this Activity.
4381     * @param finishTask Whether to finish the task associated with this Activity.
4382     *
4383     * @return Returns true if the activity successfully finished, or false if it is still running.
4384     */
4385    @Override
4386    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4387            int finishTask) {
4388        // Refuse possible leaked file descriptors
4389        if (resultData != null && resultData.hasFileDescriptors() == true) {
4390            throw new IllegalArgumentException("File descriptors passed in Intent");
4391        }
4392
4393        synchronized(this) {
4394            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4395            if (r == null) {
4396                return true;
4397            }
4398            // Keep track of the root activity of the task before we finish it
4399            TaskRecord tr = r.task;
4400            ActivityRecord rootR = tr.getRootActivity();
4401            if (rootR == null) {
4402                Slog.w(TAG, "Finishing task with all activities already finished");
4403            }
4404            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4405            // finish.
4406            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4407                    mStackSupervisor.isLastLockedTask(tr)) {
4408                Slog.i(TAG, "Not finishing task in lock task mode");
4409                mStackSupervisor.showLockTaskToast();
4410                return false;
4411            }
4412            if (mController != null) {
4413                // Find the first activity that is not finishing.
4414                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4415                if (next != null) {
4416                    // ask watcher if this is allowed
4417                    boolean resumeOK = true;
4418                    try {
4419                        resumeOK = mController.activityResuming(next.packageName);
4420                    } catch (RemoteException e) {
4421                        mController = null;
4422                        Watchdog.getInstance().setActivityController(null);
4423                    }
4424
4425                    if (!resumeOK) {
4426                        Slog.i(TAG, "Not finishing activity because controller resumed");
4427                        return false;
4428                    }
4429                }
4430            }
4431            final long origId = Binder.clearCallingIdentity();
4432            try {
4433                boolean res;
4434                final boolean finishWithRootActivity =
4435                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4436                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4437                        || (finishWithRootActivity && r == rootR)) {
4438                    // If requested, remove the task that is associated to this activity only if it
4439                    // was the root activity in the task. The result code and data is ignored
4440                    // because we don't support returning them across task boundaries. Also, to
4441                    // keep backwards compatibility we remove the task from recents when finishing
4442                    // task with root activity.
4443                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4444                    if (!res) {
4445                        Slog.i(TAG, "Removing task failed to finish activity");
4446                    }
4447                } else {
4448                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4449                            resultData, "app-request", true);
4450                    if (!res) {
4451                        Slog.i(TAG, "Failed to finish by app-request");
4452                    }
4453                }
4454                return res;
4455            } finally {
4456                Binder.restoreCallingIdentity(origId);
4457            }
4458        }
4459    }
4460
4461    @Override
4462    public final void finishHeavyWeightApp() {
4463        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4464                != PackageManager.PERMISSION_GRANTED) {
4465            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4466                    + Binder.getCallingPid()
4467                    + ", uid=" + Binder.getCallingUid()
4468                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4469            Slog.w(TAG, msg);
4470            throw new SecurityException(msg);
4471        }
4472
4473        synchronized(this) {
4474            if (mHeavyWeightProcess == null) {
4475                return;
4476            }
4477
4478            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4479            for (int i = 0; i < activities.size(); i++) {
4480                ActivityRecord r = activities.get(i);
4481                if (!r.finishing && r.isInStackLocked()) {
4482                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4483                            null, "finish-heavy", true);
4484                }
4485            }
4486
4487            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4488                    mHeavyWeightProcess.userId, 0));
4489            mHeavyWeightProcess = null;
4490        }
4491    }
4492
4493    @Override
4494    public void crashApplication(int uid, int initialPid, String packageName,
4495            String message) {
4496        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4497                != PackageManager.PERMISSION_GRANTED) {
4498            String msg = "Permission Denial: crashApplication() from pid="
4499                    + Binder.getCallingPid()
4500                    + ", uid=" + Binder.getCallingUid()
4501                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4502            Slog.w(TAG, msg);
4503            throw new SecurityException(msg);
4504        }
4505
4506        synchronized(this) {
4507            ProcessRecord proc = null;
4508
4509            // Figure out which process to kill.  We don't trust that initialPid
4510            // still has any relation to current pids, so must scan through the
4511            // list.
4512            synchronized (mPidsSelfLocked) {
4513                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4514                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4515                    if (p.uid != uid) {
4516                        continue;
4517                    }
4518                    if (p.pid == initialPid) {
4519                        proc = p;
4520                        break;
4521                    }
4522                    if (p.pkgList.containsKey(packageName)) {
4523                        proc = p;
4524                    }
4525                }
4526            }
4527
4528            if (proc == null) {
4529                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4530                        + " initialPid=" + initialPid
4531                        + " packageName=" + packageName);
4532                return;
4533            }
4534
4535            if (proc.thread != null) {
4536                if (proc.pid == Process.myPid()) {
4537                    Log.w(TAG, "crashApplication: trying to crash self!");
4538                    return;
4539                }
4540                long ident = Binder.clearCallingIdentity();
4541                try {
4542                    proc.thread.scheduleCrash(message);
4543                } catch (RemoteException e) {
4544                }
4545                Binder.restoreCallingIdentity(ident);
4546            }
4547        }
4548    }
4549
4550    @Override
4551    public final void finishSubActivity(IBinder token, String resultWho,
4552            int requestCode) {
4553        synchronized(this) {
4554            final long origId = Binder.clearCallingIdentity();
4555            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4556            if (r != null) {
4557                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4558            }
4559            Binder.restoreCallingIdentity(origId);
4560        }
4561    }
4562
4563    @Override
4564    public boolean finishActivityAffinity(IBinder token) {
4565        synchronized(this) {
4566            final long origId = Binder.clearCallingIdentity();
4567            try {
4568                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4569                if (r == null) {
4570                    return false;
4571                }
4572
4573                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4574                // can finish.
4575                final TaskRecord task = r.task;
4576                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4577                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4578                    mStackSupervisor.showLockTaskToast();
4579                    return false;
4580                }
4581                return task.stack.finishActivityAffinityLocked(r);
4582            } finally {
4583                Binder.restoreCallingIdentity(origId);
4584            }
4585        }
4586    }
4587
4588    @Override
4589    public void finishVoiceTask(IVoiceInteractionSession session) {
4590        synchronized(this) {
4591            final long origId = Binder.clearCallingIdentity();
4592            try {
4593                mStackSupervisor.finishVoiceTask(session);
4594            } finally {
4595                Binder.restoreCallingIdentity(origId);
4596            }
4597        }
4598
4599    }
4600
4601    @Override
4602    public boolean releaseActivityInstance(IBinder token) {
4603        synchronized(this) {
4604            final long origId = Binder.clearCallingIdentity();
4605            try {
4606                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4607                if (r == null) {
4608                    return false;
4609                }
4610                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4611            } finally {
4612                Binder.restoreCallingIdentity(origId);
4613            }
4614        }
4615    }
4616
4617    @Override
4618    public void releaseSomeActivities(IApplicationThread appInt) {
4619        synchronized(this) {
4620            final long origId = Binder.clearCallingIdentity();
4621            try {
4622                ProcessRecord app = getRecordForAppLocked(appInt);
4623                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4624            } finally {
4625                Binder.restoreCallingIdentity(origId);
4626            }
4627        }
4628    }
4629
4630    @Override
4631    public boolean willActivityBeVisible(IBinder token) {
4632        synchronized(this) {
4633            ActivityStack stack = ActivityRecord.getStackLocked(token);
4634            if (stack != null) {
4635                return stack.willActivityBeVisibleLocked(token);
4636            }
4637            return false;
4638        }
4639    }
4640
4641    @Override
4642    public void overridePendingTransition(IBinder token, String packageName,
4643            int enterAnim, int exitAnim) {
4644        synchronized(this) {
4645            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4646            if (self == null) {
4647                return;
4648            }
4649
4650            final long origId = Binder.clearCallingIdentity();
4651
4652            if (self.state == ActivityState.RESUMED
4653                    || self.state == ActivityState.PAUSING) {
4654                mWindowManager.overridePendingAppTransition(packageName,
4655                        enterAnim, exitAnim, null);
4656            }
4657
4658            Binder.restoreCallingIdentity(origId);
4659        }
4660    }
4661
4662    /**
4663     * Main function for removing an existing process from the activity manager
4664     * as a result of that process going away.  Clears out all connections
4665     * to the process.
4666     */
4667    private final void handleAppDiedLocked(ProcessRecord app,
4668            boolean restarting, boolean allowRestart) {
4669        int pid = app.pid;
4670        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4671        if (!kept && !restarting) {
4672            removeLruProcessLocked(app);
4673            if (pid > 0) {
4674                ProcessList.remove(pid);
4675            }
4676        }
4677
4678        if (mProfileProc == app) {
4679            clearProfilerLocked();
4680        }
4681
4682        // Remove this application's activities from active lists.
4683        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4684
4685        app.activities.clear();
4686
4687        if (app.instrumentationClass != null) {
4688            Slog.w(TAG, "Crash of app " + app.processName
4689                  + " running instrumentation " + app.instrumentationClass);
4690            Bundle info = new Bundle();
4691            info.putString("shortMsg", "Process crashed.");
4692            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4693        }
4694
4695        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4696            // If there was nothing to resume, and we are not already
4697            // restarting this process, but there is a visible activity that
4698            // is hosted by the process...  then make sure all visible
4699            // activities are running, taking care of restarting this
4700            // process.
4701            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4702        }
4703    }
4704
4705    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4706        IBinder threadBinder = thread.asBinder();
4707        // Find the application record.
4708        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4709            ProcessRecord rec = mLruProcesses.get(i);
4710            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4711                return i;
4712            }
4713        }
4714        return -1;
4715    }
4716
4717    final ProcessRecord getRecordForAppLocked(
4718            IApplicationThread thread) {
4719        if (thread == null) {
4720            return null;
4721        }
4722
4723        int appIndex = getLRURecordIndexForAppLocked(thread);
4724        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4725    }
4726
4727    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4728        // If there are no longer any background processes running,
4729        // and the app that died was not running instrumentation,
4730        // then tell everyone we are now low on memory.
4731        boolean haveBg = false;
4732        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4733            ProcessRecord rec = mLruProcesses.get(i);
4734            if (rec.thread != null
4735                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4736                haveBg = true;
4737                break;
4738            }
4739        }
4740
4741        if (!haveBg) {
4742            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4743            if (doReport) {
4744                long now = SystemClock.uptimeMillis();
4745                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4746                    doReport = false;
4747                } else {
4748                    mLastMemUsageReportTime = now;
4749                }
4750            }
4751            final ArrayList<ProcessMemInfo> memInfos
4752                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4753            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4754            long now = SystemClock.uptimeMillis();
4755            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4756                ProcessRecord rec = mLruProcesses.get(i);
4757                if (rec == dyingProc || rec.thread == null) {
4758                    continue;
4759                }
4760                if (doReport) {
4761                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4762                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4763                }
4764                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4765                    // The low memory report is overriding any current
4766                    // state for a GC request.  Make sure to do
4767                    // heavy/important/visible/foreground processes first.
4768                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4769                        rec.lastRequestedGc = 0;
4770                    } else {
4771                        rec.lastRequestedGc = rec.lastLowMemory;
4772                    }
4773                    rec.reportLowMemory = true;
4774                    rec.lastLowMemory = now;
4775                    mProcessesToGc.remove(rec);
4776                    addProcessToGcListLocked(rec);
4777                }
4778            }
4779            if (doReport) {
4780                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4781                mHandler.sendMessage(msg);
4782            }
4783            scheduleAppGcsLocked();
4784        }
4785    }
4786
4787    final void appDiedLocked(ProcessRecord app) {
4788       appDiedLocked(app, app.pid, app.thread, false);
4789    }
4790
4791    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4792            boolean fromBinderDied) {
4793        // First check if this ProcessRecord is actually active for the pid.
4794        synchronized (mPidsSelfLocked) {
4795            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4796            if (curProc != app) {
4797                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4798                return;
4799            }
4800        }
4801
4802        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4803        synchronized (stats) {
4804            stats.noteProcessDiedLocked(app.info.uid, pid);
4805        }
4806
4807        if (!app.killed) {
4808            if (!fromBinderDied) {
4809                Process.killProcessQuiet(pid);
4810            }
4811            killProcessGroup(app.info.uid, pid);
4812            app.killed = true;
4813        }
4814
4815        // Clean up already done if the process has been re-started.
4816        if (app.pid == pid && app.thread != null &&
4817                app.thread.asBinder() == thread.asBinder()) {
4818            boolean doLowMem = app.instrumentationClass == null;
4819            boolean doOomAdj = doLowMem;
4820            if (!app.killedByAm) {
4821                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4822                        + ") has died");
4823                mAllowLowerMemLevel = true;
4824            } else {
4825                // Note that we always want to do oom adj to update our state with the
4826                // new number of procs.
4827                mAllowLowerMemLevel = false;
4828                doLowMem = false;
4829            }
4830            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4831            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4832                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4833            handleAppDiedLocked(app, false, true);
4834
4835            if (doOomAdj) {
4836                updateOomAdjLocked();
4837            }
4838            if (doLowMem) {
4839                doLowMemReportIfNeededLocked(app);
4840            }
4841        } else if (app.pid != pid) {
4842            // A new process has already been started.
4843            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4844                    + ") has died and restarted (pid " + app.pid + ").");
4845            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4846        } else if (DEBUG_PROCESSES) {
4847            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4848                    + thread.asBinder());
4849        }
4850    }
4851
4852    /**
4853     * If a stack trace dump file is configured, dump process stack traces.
4854     * @param clearTraces causes the dump file to be erased prior to the new
4855     *    traces being written, if true; when false, the new traces will be
4856     *    appended to any existing file content.
4857     * @param firstPids of dalvik VM processes to dump stack traces for first
4858     * @param lastPids of dalvik VM processes to dump stack traces for last
4859     * @param nativeProcs optional list of native process names to dump stack crawls
4860     * @return file containing stack traces, or null if no dump file is configured
4861     */
4862    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4863            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4864        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4865        if (tracesPath == null || tracesPath.length() == 0) {
4866            return null;
4867        }
4868
4869        File tracesFile = new File(tracesPath);
4870        try {
4871            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4872            tracesFile.createNewFile();
4873            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4874        } catch (IOException e) {
4875            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4876            return null;
4877        }
4878
4879        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4880        return tracesFile;
4881    }
4882
4883    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4884            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4885        // Use a FileObserver to detect when traces finish writing.
4886        // The order of traces is considered important to maintain for legibility.
4887        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4888            @Override
4889            public synchronized void onEvent(int event, String path) { notify(); }
4890        };
4891
4892        try {
4893            observer.startWatching();
4894
4895            // First collect all of the stacks of the most important pids.
4896            if (firstPids != null) {
4897                try {
4898                    int num = firstPids.size();
4899                    for (int i = 0; i < num; i++) {
4900                        synchronized (observer) {
4901                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4902                            observer.wait(200);  // Wait for write-close, give up after 200msec
4903                        }
4904                    }
4905                } catch (InterruptedException e) {
4906                    Slog.wtf(TAG, e);
4907                }
4908            }
4909
4910            // Next collect the stacks of the native pids
4911            if (nativeProcs != null) {
4912                int[] pids = Process.getPidsForCommands(nativeProcs);
4913                if (pids != null) {
4914                    for (int pid : pids) {
4915                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4916                    }
4917                }
4918            }
4919
4920            // Lastly, measure CPU usage.
4921            if (processCpuTracker != null) {
4922                processCpuTracker.init();
4923                System.gc();
4924                processCpuTracker.update();
4925                try {
4926                    synchronized (processCpuTracker) {
4927                        processCpuTracker.wait(500); // measure over 1/2 second.
4928                    }
4929                } catch (InterruptedException e) {
4930                }
4931                processCpuTracker.update();
4932
4933                // We'll take the stack crawls of just the top apps using CPU.
4934                final int N = processCpuTracker.countWorkingStats();
4935                int numProcs = 0;
4936                for (int i=0; i<N && numProcs<5; i++) {
4937                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4938                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4939                        numProcs++;
4940                        try {
4941                            synchronized (observer) {
4942                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4943                                observer.wait(200);  // Wait for write-close, give up after 200msec
4944                            }
4945                        } catch (InterruptedException e) {
4946                            Slog.wtf(TAG, e);
4947                        }
4948
4949                    }
4950                }
4951            }
4952        } finally {
4953            observer.stopWatching();
4954        }
4955    }
4956
4957    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4958        if (true || IS_USER_BUILD) {
4959            return;
4960        }
4961        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4962        if (tracesPath == null || tracesPath.length() == 0) {
4963            return;
4964        }
4965
4966        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4967        StrictMode.allowThreadDiskWrites();
4968        try {
4969            final File tracesFile = new File(tracesPath);
4970            final File tracesDir = tracesFile.getParentFile();
4971            final File tracesTmp = new File(tracesDir, "__tmp__");
4972            try {
4973                if (tracesFile.exists()) {
4974                    tracesTmp.delete();
4975                    tracesFile.renameTo(tracesTmp);
4976                }
4977                StringBuilder sb = new StringBuilder();
4978                Time tobj = new Time();
4979                tobj.set(System.currentTimeMillis());
4980                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4981                sb.append(": ");
4982                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4983                sb.append(" since ");
4984                sb.append(msg);
4985                FileOutputStream fos = new FileOutputStream(tracesFile);
4986                fos.write(sb.toString().getBytes());
4987                if (app == null) {
4988                    fos.write("\n*** No application process!".getBytes());
4989                }
4990                fos.close();
4991                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4992            } catch (IOException e) {
4993                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4994                return;
4995            }
4996
4997            if (app != null) {
4998                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4999                firstPids.add(app.pid);
5000                dumpStackTraces(tracesPath, firstPids, null, null, null);
5001            }
5002
5003            File lastTracesFile = null;
5004            File curTracesFile = null;
5005            for (int i=9; i>=0; i--) {
5006                String name = String.format(Locale.US, "slow%02d.txt", i);
5007                curTracesFile = new File(tracesDir, name);
5008                if (curTracesFile.exists()) {
5009                    if (lastTracesFile != null) {
5010                        curTracesFile.renameTo(lastTracesFile);
5011                    } else {
5012                        curTracesFile.delete();
5013                    }
5014                }
5015                lastTracesFile = curTracesFile;
5016            }
5017            tracesFile.renameTo(curTracesFile);
5018            if (tracesTmp.exists()) {
5019                tracesTmp.renameTo(tracesFile);
5020            }
5021        } finally {
5022            StrictMode.setThreadPolicy(oldPolicy);
5023        }
5024    }
5025
5026    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5027            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5028        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5029        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5030
5031        if (mController != null) {
5032            try {
5033                // 0 == continue, -1 = kill process immediately
5034                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5035                if (res < 0 && app.pid != MY_PID) {
5036                    app.kill("anr", true);
5037                }
5038            } catch (RemoteException e) {
5039                mController = null;
5040                Watchdog.getInstance().setActivityController(null);
5041            }
5042        }
5043
5044        long anrTime = SystemClock.uptimeMillis();
5045        if (MONITOR_CPU_USAGE) {
5046            updateCpuStatsNow();
5047        }
5048
5049        synchronized (this) {
5050            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5051            if (mShuttingDown) {
5052                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5053                return;
5054            } else if (app.notResponding) {
5055                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5056                return;
5057            } else if (app.crashing) {
5058                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5059                return;
5060            }
5061
5062            // In case we come through here for the same app before completing
5063            // this one, mark as anring now so we will bail out.
5064            app.notResponding = true;
5065
5066            // Log the ANR to the event log.
5067            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5068                    app.processName, app.info.flags, annotation);
5069
5070            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5071            firstPids.add(app.pid);
5072
5073            int parentPid = app.pid;
5074            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5075            if (parentPid != app.pid) firstPids.add(parentPid);
5076
5077            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5078
5079            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5080                ProcessRecord r = mLruProcesses.get(i);
5081                if (r != null && r.thread != null) {
5082                    int pid = r.pid;
5083                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5084                        if (r.persistent) {
5085                            firstPids.add(pid);
5086                        } else {
5087                            lastPids.put(pid, Boolean.TRUE);
5088                        }
5089                    }
5090                }
5091            }
5092        }
5093
5094        // Log the ANR to the main log.
5095        StringBuilder info = new StringBuilder();
5096        info.setLength(0);
5097        info.append("ANR in ").append(app.processName);
5098        if (activity != null && activity.shortComponentName != null) {
5099            info.append(" (").append(activity.shortComponentName).append(")");
5100        }
5101        info.append("\n");
5102        info.append("PID: ").append(app.pid).append("\n");
5103        if (annotation != null) {
5104            info.append("Reason: ").append(annotation).append("\n");
5105        }
5106        if (parent != null && parent != activity) {
5107            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5108        }
5109
5110        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5111
5112        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5113                NATIVE_STACKS_OF_INTEREST);
5114
5115        String cpuInfo = null;
5116        if (MONITOR_CPU_USAGE) {
5117            updateCpuStatsNow();
5118            synchronized (mProcessCpuTracker) {
5119                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5120            }
5121            info.append(processCpuTracker.printCurrentLoad());
5122            info.append(cpuInfo);
5123        }
5124
5125        info.append(processCpuTracker.printCurrentState(anrTime));
5126
5127        Slog.e(TAG, info.toString());
5128        if (tracesFile == null) {
5129            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5130            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5131        }
5132
5133        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5134                cpuInfo, tracesFile, null);
5135
5136        if (mController != null) {
5137            try {
5138                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5139                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5140                if (res != 0) {
5141                    if (res < 0 && app.pid != MY_PID) {
5142                        app.kill("anr", true);
5143                    } else {
5144                        synchronized (this) {
5145                            mServices.scheduleServiceTimeoutLocked(app);
5146                        }
5147                    }
5148                    return;
5149                }
5150            } catch (RemoteException e) {
5151                mController = null;
5152                Watchdog.getInstance().setActivityController(null);
5153            }
5154        }
5155
5156        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5157        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5158                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5159
5160        synchronized (this) {
5161            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5162
5163            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5164                app.kill("bg anr", true);
5165                return;
5166            }
5167
5168            // Set the app's notResponding state, and look up the errorReportReceiver
5169            makeAppNotRespondingLocked(app,
5170                    activity != null ? activity.shortComponentName : null,
5171                    annotation != null ? "ANR " + annotation : "ANR",
5172                    info.toString());
5173
5174            // Bring up the infamous App Not Responding dialog
5175            Message msg = Message.obtain();
5176            HashMap<String, Object> map = new HashMap<String, Object>();
5177            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5178            msg.obj = map;
5179            msg.arg1 = aboveSystem ? 1 : 0;
5180            map.put("app", app);
5181            if (activity != null) {
5182                map.put("activity", activity);
5183            }
5184
5185            mUiHandler.sendMessage(msg);
5186        }
5187    }
5188
5189    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5190        if (!mLaunchWarningShown) {
5191            mLaunchWarningShown = true;
5192            mUiHandler.post(new Runnable() {
5193                @Override
5194                public void run() {
5195                    synchronized (ActivityManagerService.this) {
5196                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5197                        d.show();
5198                        mUiHandler.postDelayed(new Runnable() {
5199                            @Override
5200                            public void run() {
5201                                synchronized (ActivityManagerService.this) {
5202                                    d.dismiss();
5203                                    mLaunchWarningShown = false;
5204                                }
5205                            }
5206                        }, 4000);
5207                    }
5208                }
5209            });
5210        }
5211    }
5212
5213    @Override
5214    public boolean clearApplicationUserData(final String packageName,
5215            final IPackageDataObserver observer, int userId) {
5216        enforceNotIsolatedCaller("clearApplicationUserData");
5217        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5218            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5219        }
5220        int uid = Binder.getCallingUid();
5221        int pid = Binder.getCallingPid();
5222        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5223                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5224        long callingId = Binder.clearCallingIdentity();
5225        try {
5226            IPackageManager pm = AppGlobals.getPackageManager();
5227            int pkgUid = -1;
5228            synchronized(this) {
5229                try {
5230                    pkgUid = pm.getPackageUid(packageName, userId);
5231                } catch (RemoteException e) {
5232                }
5233                if (pkgUid == -1) {
5234                    Slog.w(TAG, "Invalid packageName: " + packageName);
5235                    if (observer != null) {
5236                        try {
5237                            observer.onRemoveCompleted(packageName, false);
5238                        } catch (RemoteException e) {
5239                            Slog.i(TAG, "Observer no longer exists.");
5240                        }
5241                    }
5242                    return false;
5243                }
5244                if (uid == pkgUid || checkComponentPermission(
5245                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5246                        pid, uid, -1, true)
5247                        == PackageManager.PERMISSION_GRANTED) {
5248                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5249                } else {
5250                    throw new SecurityException("PID " + pid + " does not have permission "
5251                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5252                                    + " of package " + packageName);
5253                }
5254
5255                // Remove all tasks match the cleared application package and user
5256                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5257                    final TaskRecord tr = mRecentTasks.get(i);
5258                    final String taskPackageName =
5259                            tr.getBaseIntent().getComponent().getPackageName();
5260                    if (tr.userId != userId) continue;
5261                    if (!taskPackageName.equals(packageName)) continue;
5262                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5263                }
5264            }
5265
5266            try {
5267                // Clear application user data
5268                pm.clearApplicationUserData(packageName, observer, userId);
5269
5270                synchronized(this) {
5271                    // Remove all permissions granted from/to this package
5272                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5273                }
5274
5275                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5276                        Uri.fromParts("package", packageName, null));
5277                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5278                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5279                        null, null, 0, null, null, null, null, false, false, userId);
5280            } catch (RemoteException e) {
5281            }
5282        } finally {
5283            Binder.restoreCallingIdentity(callingId);
5284        }
5285        return true;
5286    }
5287
5288    @Override
5289    public void killBackgroundProcesses(final String packageName, int userId) {
5290        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5291                != PackageManager.PERMISSION_GRANTED &&
5292                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5293                        != PackageManager.PERMISSION_GRANTED) {
5294            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5295                    + Binder.getCallingPid()
5296                    + ", uid=" + Binder.getCallingUid()
5297                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5298            Slog.w(TAG, msg);
5299            throw new SecurityException(msg);
5300        }
5301
5302        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5303                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5304        long callingId = Binder.clearCallingIdentity();
5305        try {
5306            IPackageManager pm = AppGlobals.getPackageManager();
5307            synchronized(this) {
5308                int appId = -1;
5309                try {
5310                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5311                } catch (RemoteException e) {
5312                }
5313                if (appId == -1) {
5314                    Slog.w(TAG, "Invalid packageName: " + packageName);
5315                    return;
5316                }
5317                killPackageProcessesLocked(packageName, appId, userId,
5318                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5319            }
5320        } finally {
5321            Binder.restoreCallingIdentity(callingId);
5322        }
5323    }
5324
5325    @Override
5326    public void killAllBackgroundProcesses() {
5327        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5328                != PackageManager.PERMISSION_GRANTED) {
5329            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5330                    + Binder.getCallingPid()
5331                    + ", uid=" + Binder.getCallingUid()
5332                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5333            Slog.w(TAG, msg);
5334            throw new SecurityException(msg);
5335        }
5336
5337        long callingId = Binder.clearCallingIdentity();
5338        try {
5339            synchronized(this) {
5340                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5341                final int NP = mProcessNames.getMap().size();
5342                for (int ip=0; ip<NP; ip++) {
5343                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5344                    final int NA = apps.size();
5345                    for (int ia=0; ia<NA; ia++) {
5346                        ProcessRecord app = apps.valueAt(ia);
5347                        if (app.persistent) {
5348                            // we don't kill persistent processes
5349                            continue;
5350                        }
5351                        if (app.removed) {
5352                            procs.add(app);
5353                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5354                            app.removed = true;
5355                            procs.add(app);
5356                        }
5357                    }
5358                }
5359
5360                int N = procs.size();
5361                for (int i=0; i<N; i++) {
5362                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5363                }
5364                mAllowLowerMemLevel = true;
5365                updateOomAdjLocked();
5366                doLowMemReportIfNeededLocked(null);
5367            }
5368        } finally {
5369            Binder.restoreCallingIdentity(callingId);
5370        }
5371    }
5372
5373    @Override
5374    public void forceStopPackage(final String packageName, int userId) {
5375        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5376                != PackageManager.PERMISSION_GRANTED) {
5377            String msg = "Permission Denial: forceStopPackage() from pid="
5378                    + Binder.getCallingPid()
5379                    + ", uid=" + Binder.getCallingUid()
5380                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5381            Slog.w(TAG, msg);
5382            throw new SecurityException(msg);
5383        }
5384        final int callingPid = Binder.getCallingPid();
5385        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5386                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5387        long callingId = Binder.clearCallingIdentity();
5388        try {
5389            IPackageManager pm = AppGlobals.getPackageManager();
5390            synchronized(this) {
5391                int[] users = userId == UserHandle.USER_ALL
5392                        ? mUserController.getUsers() : new int[] { userId };
5393                for (int user : users) {
5394                    int pkgUid = -1;
5395                    try {
5396                        pkgUid = pm.getPackageUid(packageName, user);
5397                    } catch (RemoteException e) {
5398                    }
5399                    if (pkgUid == -1) {
5400                        Slog.w(TAG, "Invalid packageName: " + packageName);
5401                        continue;
5402                    }
5403                    try {
5404                        pm.setPackageStoppedState(packageName, true, user);
5405                    } catch (RemoteException e) {
5406                    } catch (IllegalArgumentException e) {
5407                        Slog.w(TAG, "Failed trying to unstop package "
5408                                + packageName + ": " + e);
5409                    }
5410                    if (mUserController.isUserRunningLocked(user, 0)) {
5411                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5412                    }
5413                }
5414            }
5415        } finally {
5416            Binder.restoreCallingIdentity(callingId);
5417        }
5418    }
5419
5420    @Override
5421    public void addPackageDependency(String packageName) {
5422        synchronized (this) {
5423            int callingPid = Binder.getCallingPid();
5424            if (callingPid == Process.myPid()) {
5425                //  Yeah, um, no.
5426                return;
5427            }
5428            ProcessRecord proc;
5429            synchronized (mPidsSelfLocked) {
5430                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5431            }
5432            if (proc != null) {
5433                if (proc.pkgDeps == null) {
5434                    proc.pkgDeps = new ArraySet<String>(1);
5435                }
5436                proc.pkgDeps.add(packageName);
5437            }
5438        }
5439    }
5440
5441    /*
5442     * The pkg name and app id have to be specified.
5443     */
5444    @Override
5445    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5446        if (pkg == null) {
5447            return;
5448        }
5449        // Make sure the uid is valid.
5450        if (appid < 0) {
5451            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5452            return;
5453        }
5454        int callerUid = Binder.getCallingUid();
5455        // Only the system server can kill an application
5456        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5457            // Post an aysnc message to kill the application
5458            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5459            msg.arg1 = appid;
5460            msg.arg2 = 0;
5461            Bundle bundle = new Bundle();
5462            bundle.putString("pkg", pkg);
5463            bundle.putString("reason", reason);
5464            msg.obj = bundle;
5465            mHandler.sendMessage(msg);
5466        } else {
5467            throw new SecurityException(callerUid + " cannot kill pkg: " +
5468                    pkg);
5469        }
5470    }
5471
5472    @Override
5473    public void closeSystemDialogs(String reason) {
5474        enforceNotIsolatedCaller("closeSystemDialogs");
5475
5476        final int pid = Binder.getCallingPid();
5477        final int uid = Binder.getCallingUid();
5478        final long origId = Binder.clearCallingIdentity();
5479        try {
5480            synchronized (this) {
5481                // Only allow this from foreground processes, so that background
5482                // applications can't abuse it to prevent system UI from being shown.
5483                if (uid >= Process.FIRST_APPLICATION_UID) {
5484                    ProcessRecord proc;
5485                    synchronized (mPidsSelfLocked) {
5486                        proc = mPidsSelfLocked.get(pid);
5487                    }
5488                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5489                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5490                                + " from background process " + proc);
5491                        return;
5492                    }
5493                }
5494                closeSystemDialogsLocked(reason);
5495            }
5496        } finally {
5497            Binder.restoreCallingIdentity(origId);
5498        }
5499    }
5500
5501    void closeSystemDialogsLocked(String reason) {
5502        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5503        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5504                | Intent.FLAG_RECEIVER_FOREGROUND);
5505        if (reason != null) {
5506            intent.putExtra("reason", reason);
5507        }
5508        mWindowManager.closeSystemDialogs(reason);
5509
5510        mStackSupervisor.closeSystemDialogsLocked();
5511
5512        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5513                AppOpsManager.OP_NONE, null, false, false,
5514                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5515    }
5516
5517    @Override
5518    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5519        enforceNotIsolatedCaller("getProcessMemoryInfo");
5520        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5521        for (int i=pids.length-1; i>=0; i--) {
5522            ProcessRecord proc;
5523            int oomAdj;
5524            synchronized (this) {
5525                synchronized (mPidsSelfLocked) {
5526                    proc = mPidsSelfLocked.get(pids[i]);
5527                    oomAdj = proc != null ? proc.setAdj : 0;
5528                }
5529            }
5530            infos[i] = new Debug.MemoryInfo();
5531            Debug.getMemoryInfo(pids[i], infos[i]);
5532            if (proc != null) {
5533                synchronized (this) {
5534                    if (proc.thread != null && proc.setAdj == oomAdj) {
5535                        // Record this for posterity if the process has been stable.
5536                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5537                                infos[i].getTotalUss(), false, proc.pkgList);
5538                    }
5539                }
5540            }
5541        }
5542        return infos;
5543    }
5544
5545    @Override
5546    public long[] getProcessPss(int[] pids) {
5547        enforceNotIsolatedCaller("getProcessPss");
5548        long[] pss = new long[pids.length];
5549        for (int i=pids.length-1; i>=0; i--) {
5550            ProcessRecord proc;
5551            int oomAdj;
5552            synchronized (this) {
5553                synchronized (mPidsSelfLocked) {
5554                    proc = mPidsSelfLocked.get(pids[i]);
5555                    oomAdj = proc != null ? proc.setAdj : 0;
5556                }
5557            }
5558            long[] tmpUss = new long[1];
5559            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5560            if (proc != null) {
5561                synchronized (this) {
5562                    if (proc.thread != null && proc.setAdj == oomAdj) {
5563                        // Record this for posterity if the process has been stable.
5564                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5565                    }
5566                }
5567            }
5568        }
5569        return pss;
5570    }
5571
5572    @Override
5573    public void killApplicationProcess(String processName, int uid) {
5574        if (processName == null) {
5575            return;
5576        }
5577
5578        int callerUid = Binder.getCallingUid();
5579        // Only the system server can kill an application
5580        if (callerUid == Process.SYSTEM_UID) {
5581            synchronized (this) {
5582                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5583                if (app != null && app.thread != null) {
5584                    try {
5585                        app.thread.scheduleSuicide();
5586                    } catch (RemoteException e) {
5587                        // If the other end already died, then our work here is done.
5588                    }
5589                } else {
5590                    Slog.w(TAG, "Process/uid not found attempting kill of "
5591                            + processName + " / " + uid);
5592                }
5593            }
5594        } else {
5595            throw new SecurityException(callerUid + " cannot kill app process: " +
5596                    processName);
5597        }
5598    }
5599
5600    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5601        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5602                false, true, false, false, UserHandle.getUserId(uid), reason);
5603        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5604                Uri.fromParts("package", packageName, null));
5605        if (!mProcessesReady) {
5606            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5607                    | Intent.FLAG_RECEIVER_FOREGROUND);
5608        }
5609        intent.putExtra(Intent.EXTRA_UID, uid);
5610        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5611        broadcastIntentLocked(null, null, intent,
5612                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5613                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5614    }
5615
5616
5617    private final boolean killPackageProcessesLocked(String packageName, int appId,
5618            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5619            boolean doit, boolean evenPersistent, String reason) {
5620        ArrayList<ProcessRecord> procs = new ArrayList<>();
5621
5622        // Remove all processes this package may have touched: all with the
5623        // same UID (except for the system or root user), and all whose name
5624        // matches the package name.
5625        final int NP = mProcessNames.getMap().size();
5626        for (int ip=0; ip<NP; ip++) {
5627            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5628            final int NA = apps.size();
5629            for (int ia=0; ia<NA; ia++) {
5630                ProcessRecord app = apps.valueAt(ia);
5631                if (app.persistent && !evenPersistent) {
5632                    // we don't kill persistent processes
5633                    continue;
5634                }
5635                if (app.removed) {
5636                    if (doit) {
5637                        procs.add(app);
5638                    }
5639                    continue;
5640                }
5641
5642                // Skip process if it doesn't meet our oom adj requirement.
5643                if (app.setAdj < minOomAdj) {
5644                    continue;
5645                }
5646
5647                // If no package is specified, we call all processes under the
5648                // give user id.
5649                if (packageName == null) {
5650                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5651                        continue;
5652                    }
5653                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5654                        continue;
5655                    }
5656                // Package has been specified, we want to hit all processes
5657                // that match it.  We need to qualify this by the processes
5658                // that are running under the specified app and user ID.
5659                } else {
5660                    final boolean isDep = app.pkgDeps != null
5661                            && app.pkgDeps.contains(packageName);
5662                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5663                        continue;
5664                    }
5665                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5666                        continue;
5667                    }
5668                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5669                        continue;
5670                    }
5671                }
5672
5673                // Process has passed all conditions, kill it!
5674                if (!doit) {
5675                    return true;
5676                }
5677                app.removed = true;
5678                procs.add(app);
5679            }
5680        }
5681
5682        int N = procs.size();
5683        for (int i=0; i<N; i++) {
5684            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5685        }
5686        updateOomAdjLocked();
5687        return N > 0;
5688    }
5689
5690    private void cleanupDisabledPackageComponentsLocked(
5691            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5692
5693        Set<String> disabledClasses = null;
5694        boolean packageDisabled = false;
5695        IPackageManager pm = AppGlobals.getPackageManager();
5696
5697        if (changedClasses == null) {
5698            // Nothing changed...
5699            return;
5700        }
5701
5702        // Determine enable/disable state of the package and its components.
5703        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5704        for (int i = changedClasses.length - 1; i >= 0; i--) {
5705            final String changedClass = changedClasses[i];
5706
5707            if (changedClass.equals(packageName)) {
5708                try {
5709                    // Entire package setting changed
5710                    enabled = pm.getApplicationEnabledSetting(packageName,
5711                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5712                } catch (Exception e) {
5713                    // No such package/component; probably racing with uninstall.  In any
5714                    // event it means we have nothing further to do here.
5715                    return;
5716                }
5717                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5718                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5719                if (packageDisabled) {
5720                    // Entire package is disabled.
5721                    // No need to continue to check component states.
5722                    disabledClasses = null;
5723                    break;
5724                }
5725            } else {
5726                try {
5727                    enabled = pm.getComponentEnabledSetting(
5728                            new ComponentName(packageName, changedClass),
5729                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5730                } catch (Exception e) {
5731                    // As above, probably racing with uninstall.
5732                    return;
5733                }
5734                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5735                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5736                    if (disabledClasses == null) {
5737                        disabledClasses = new ArraySet<>(changedClasses.length);
5738                    }
5739                    disabledClasses.add(changedClass);
5740                }
5741            }
5742        }
5743
5744        if (!packageDisabled && disabledClasses == null) {
5745            // Nothing to do here...
5746            return;
5747        }
5748
5749        // Clean-up disabled activities.
5750        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5751                packageName, disabledClasses, true, false, userId) && mBooted) {
5752            mStackSupervisor.resumeTopActivitiesLocked();
5753            mStackSupervisor.scheduleIdleLocked();
5754        }
5755
5756        // Clean-up disabled tasks
5757        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5758
5759        // Clean-up disabled services.
5760        mServices.bringDownDisabledPackageServicesLocked(
5761                packageName, disabledClasses, userId, false, killProcess, true);
5762
5763        // Clean-up disabled providers.
5764        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5765        mProviderMap.collectPackageProvidersLocked(
5766                packageName, disabledClasses, true, false, userId, providers);
5767        for (int i = providers.size() - 1; i >= 0; i--) {
5768            removeDyingProviderLocked(null, providers.get(i), true);
5769        }
5770
5771        // Clean-up disabled broadcast receivers.
5772        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5773            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5774                    packageName, disabledClasses, userId, true);
5775        }
5776
5777    }
5778
5779    final boolean forceStopPackageLocked(String packageName, int appId,
5780            boolean callerWillRestart, boolean purgeCache, boolean doit,
5781            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5782        int i;
5783
5784        if (userId == UserHandle.USER_ALL && packageName == null) {
5785            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5786        }
5787
5788        if (appId < 0 && packageName != null) {
5789            try {
5790                appId = UserHandle.getAppId(
5791                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5792            } catch (RemoteException e) {
5793            }
5794        }
5795
5796        if (doit) {
5797            if (packageName != null) {
5798                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5799                        + " user=" + userId + ": " + reason);
5800            } else {
5801                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5802            }
5803
5804            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5805            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5806                SparseArray<Long> ba = pmap.valueAt(ip);
5807                for (i = ba.size() - 1; i >= 0; i--) {
5808                    boolean remove = false;
5809                    final int entUid = ba.keyAt(i);
5810                    if (packageName != null) {
5811                        if (userId == UserHandle.USER_ALL) {
5812                            if (UserHandle.getAppId(entUid) == appId) {
5813                                remove = true;
5814                            }
5815                        } else {
5816                            if (entUid == UserHandle.getUid(userId, appId)) {
5817                                remove = true;
5818                            }
5819                        }
5820                    } else if (UserHandle.getUserId(entUid) == userId) {
5821                        remove = true;
5822                    }
5823                    if (remove) {
5824                        ba.removeAt(i);
5825                    }
5826                }
5827                if (ba.size() == 0) {
5828                    pmap.removeAt(ip);
5829                }
5830            }
5831        }
5832
5833        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5834                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5835                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5836
5837        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5838                packageName, null, doit, evenPersistent, userId)) {
5839            if (!doit) {
5840                return true;
5841            }
5842            didSomething = true;
5843        }
5844
5845        if (mServices.bringDownDisabledPackageServicesLocked(
5846                packageName, null, userId, evenPersistent, true, doit)) {
5847            if (!doit) {
5848                return true;
5849            }
5850            didSomething = true;
5851        }
5852
5853        if (packageName == null) {
5854            // Remove all sticky broadcasts from this user.
5855            mStickyBroadcasts.remove(userId);
5856        }
5857
5858        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5859        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5860                userId, providers)) {
5861            if (!doit) {
5862                return true;
5863            }
5864            didSomething = true;
5865        }
5866        for (i = providers.size() - 1; i >= 0; i--) {
5867            removeDyingProviderLocked(null, providers.get(i), true);
5868        }
5869
5870        // Remove transient permissions granted from/to this package/user
5871        removeUriPermissionsForPackageLocked(packageName, userId, false);
5872
5873        if (doit) {
5874            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5875                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5876                        packageName, null, userId, doit);
5877            }
5878        }
5879
5880        if (packageName == null || uninstalling) {
5881            // Remove pending intents.  For now we only do this when force
5882            // stopping users, because we have some problems when doing this
5883            // for packages -- app widgets are not currently cleaned up for
5884            // such packages, so they can be left with bad pending intents.
5885            if (mIntentSenderRecords.size() > 0) {
5886                Iterator<WeakReference<PendingIntentRecord>> it
5887                        = mIntentSenderRecords.values().iterator();
5888                while (it.hasNext()) {
5889                    WeakReference<PendingIntentRecord> wpir = it.next();
5890                    if (wpir == null) {
5891                        it.remove();
5892                        continue;
5893                    }
5894                    PendingIntentRecord pir = wpir.get();
5895                    if (pir == null) {
5896                        it.remove();
5897                        continue;
5898                    }
5899                    if (packageName == null) {
5900                        // Stopping user, remove all objects for the user.
5901                        if (pir.key.userId != userId) {
5902                            // Not the same user, skip it.
5903                            continue;
5904                        }
5905                    } else {
5906                        if (UserHandle.getAppId(pir.uid) != appId) {
5907                            // Different app id, skip it.
5908                            continue;
5909                        }
5910                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5911                            // Different user, skip it.
5912                            continue;
5913                        }
5914                        if (!pir.key.packageName.equals(packageName)) {
5915                            // Different package, skip it.
5916                            continue;
5917                        }
5918                    }
5919                    if (!doit) {
5920                        return true;
5921                    }
5922                    didSomething = true;
5923                    it.remove();
5924                    pir.canceled = true;
5925                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5926                        pir.key.activity.pendingResults.remove(pir.ref);
5927                    }
5928                }
5929            }
5930        }
5931
5932        if (doit) {
5933            if (purgeCache && packageName != null) {
5934                AttributeCache ac = AttributeCache.instance();
5935                if (ac != null) {
5936                    ac.removePackage(packageName);
5937                }
5938            }
5939            if (mBooted) {
5940                mStackSupervisor.resumeTopActivitiesLocked();
5941                mStackSupervisor.scheduleIdleLocked();
5942            }
5943        }
5944
5945        return didSomething;
5946    }
5947
5948    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5949        ProcessRecord old = mProcessNames.remove(name, uid);
5950        if (old != null) {
5951            old.uidRecord.numProcs--;
5952            if (old.uidRecord.numProcs == 0) {
5953                // No more processes using this uid, tell clients it is gone.
5954                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5955                        "No more processes in " + old.uidRecord);
5956                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
5957                mActiveUids.remove(uid);
5958            }
5959            old.uidRecord = null;
5960        }
5961        mIsolatedProcesses.remove(uid);
5962        return old;
5963    }
5964
5965    private final void addProcessNameLocked(ProcessRecord proc) {
5966        // We shouldn't already have a process under this name, but just in case we
5967        // need to clean up whatever may be there now.
5968        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5969        if (old == proc && proc.persistent) {
5970            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5971            Slog.w(TAG, "Re-adding persistent process " + proc);
5972        } else if (old != null) {
5973            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5974        }
5975        UidRecord uidRec = mActiveUids.get(proc.uid);
5976        if (uidRec == null) {
5977            uidRec = new UidRecord(proc.uid);
5978            // This is the first appearance of the uid, report it now!
5979            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5980                    "Creating new process uid: " + uidRec);
5981            mActiveUids.put(proc.uid, uidRec);
5982            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
5983        }
5984        proc.uidRecord = uidRec;
5985        uidRec.numProcs++;
5986        mProcessNames.put(proc.processName, proc.uid, proc);
5987        if (proc.isolated) {
5988            mIsolatedProcesses.put(proc.uid, proc);
5989        }
5990    }
5991
5992    private final boolean removeProcessLocked(ProcessRecord app,
5993            boolean callerWillRestart, boolean allowRestart, String reason) {
5994        final String name = app.processName;
5995        final int uid = app.uid;
5996        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5997            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5998
5999        removeProcessNameLocked(name, uid);
6000        if (mHeavyWeightProcess == app) {
6001            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6002                    mHeavyWeightProcess.userId, 0));
6003            mHeavyWeightProcess = null;
6004        }
6005        boolean needRestart = false;
6006        if (app.pid > 0 && app.pid != MY_PID) {
6007            int pid = app.pid;
6008            synchronized (mPidsSelfLocked) {
6009                mPidsSelfLocked.remove(pid);
6010                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6011            }
6012            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6013            if (app.isolated) {
6014                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6015            }
6016            boolean willRestart = false;
6017            if (app.persistent && !app.isolated) {
6018                if (!callerWillRestart) {
6019                    willRestart = true;
6020                } else {
6021                    needRestart = true;
6022                }
6023            }
6024            app.kill(reason, true);
6025            handleAppDiedLocked(app, willRestart, allowRestart);
6026            if (willRestart) {
6027                removeLruProcessLocked(app);
6028                addAppLocked(app.info, false, null /* ABI override */);
6029            }
6030        } else {
6031            mRemovedProcesses.add(app);
6032        }
6033
6034        return needRestart;
6035    }
6036
6037    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6038        cleanupAppInLaunchingProvidersLocked(app, true);
6039        removeProcessLocked(app, false, true, "timeout publishing content providers");
6040    }
6041
6042    private final void processStartTimedOutLocked(ProcessRecord app) {
6043        final int pid = app.pid;
6044        boolean gone = false;
6045        synchronized (mPidsSelfLocked) {
6046            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6047            if (knownApp != null && knownApp.thread == null) {
6048                mPidsSelfLocked.remove(pid);
6049                gone = true;
6050            }
6051        }
6052
6053        if (gone) {
6054            Slog.w(TAG, "Process " + app + " failed to attach");
6055            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6056                    pid, app.uid, app.processName);
6057            removeProcessNameLocked(app.processName, app.uid);
6058            if (mHeavyWeightProcess == app) {
6059                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6060                        mHeavyWeightProcess.userId, 0));
6061                mHeavyWeightProcess = null;
6062            }
6063            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6064            if (app.isolated) {
6065                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6066            }
6067            // Take care of any launching providers waiting for this process.
6068            cleanupAppInLaunchingProvidersLocked(app, true);
6069            // Take care of any services that are waiting for the process.
6070            mServices.processStartTimedOutLocked(app);
6071            app.kill("start timeout", true);
6072            removeLruProcessLocked(app);
6073            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6074                Slog.w(TAG, "Unattached app died before backup, skipping");
6075                try {
6076                    IBackupManager bm = IBackupManager.Stub.asInterface(
6077                            ServiceManager.getService(Context.BACKUP_SERVICE));
6078                    bm.agentDisconnected(app.info.packageName);
6079                } catch (RemoteException e) {
6080                    // Can't happen; the backup manager is local
6081                }
6082            }
6083            if (isPendingBroadcastProcessLocked(pid)) {
6084                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6085                skipPendingBroadcastLocked(pid);
6086            }
6087        } else {
6088            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6089        }
6090    }
6091
6092    private final boolean attachApplicationLocked(IApplicationThread thread,
6093            int pid) {
6094
6095        // Find the application record that is being attached...  either via
6096        // the pid if we are running in multiple processes, or just pull the
6097        // next app record if we are emulating process with anonymous threads.
6098        ProcessRecord app;
6099        if (pid != MY_PID && pid >= 0) {
6100            synchronized (mPidsSelfLocked) {
6101                app = mPidsSelfLocked.get(pid);
6102            }
6103        } else {
6104            app = null;
6105        }
6106
6107        if (app == null) {
6108            Slog.w(TAG, "No pending application record for pid " + pid
6109                    + " (IApplicationThread " + thread + "); dropping process");
6110            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6111            if (pid > 0 && pid != MY_PID) {
6112                Process.killProcessQuiet(pid);
6113                //TODO: killProcessGroup(app.info.uid, pid);
6114            } else {
6115                try {
6116                    thread.scheduleExit();
6117                } catch (Exception e) {
6118                    // Ignore exceptions.
6119                }
6120            }
6121            return false;
6122        }
6123
6124        // If this application record is still attached to a previous
6125        // process, clean it up now.
6126        if (app.thread != null) {
6127            handleAppDiedLocked(app, true, true);
6128        }
6129
6130        // Tell the process all about itself.
6131
6132        if (DEBUG_ALL) Slog.v(
6133                TAG, "Binding process pid " + pid + " to record " + app);
6134
6135        final String processName = app.processName;
6136        try {
6137            AppDeathRecipient adr = new AppDeathRecipient(
6138                    app, pid, thread);
6139            thread.asBinder().linkToDeath(adr, 0);
6140            app.deathRecipient = adr;
6141        } catch (RemoteException e) {
6142            app.resetPackageList(mProcessStats);
6143            startProcessLocked(app, "link fail", processName);
6144            return false;
6145        }
6146
6147        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6148
6149        app.makeActive(thread, mProcessStats);
6150        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6151        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6152        app.forcingToForeground = null;
6153        updateProcessForegroundLocked(app, false, false);
6154        app.hasShownUi = false;
6155        app.debugging = false;
6156        app.cached = false;
6157        app.killedByAm = false;
6158
6159        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6160
6161        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6162        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6163
6164        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6165            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6166            msg.obj = app;
6167            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6168        }
6169
6170        if (!normalMode) {
6171            Slog.i(TAG, "Launching preboot mode app: " + app);
6172        }
6173
6174        if (DEBUG_ALL) Slog.v(
6175            TAG, "New app record " + app
6176            + " thread=" + thread.asBinder() + " pid=" + pid);
6177        try {
6178            int testMode = IApplicationThread.DEBUG_OFF;
6179            if (mDebugApp != null && mDebugApp.equals(processName)) {
6180                testMode = mWaitForDebugger
6181                    ? IApplicationThread.DEBUG_WAIT
6182                    : IApplicationThread.DEBUG_ON;
6183                app.debugging = true;
6184                if (mDebugTransient) {
6185                    mDebugApp = mOrigDebugApp;
6186                    mWaitForDebugger = mOrigWaitForDebugger;
6187                }
6188            }
6189            String profileFile = app.instrumentationProfileFile;
6190            ParcelFileDescriptor profileFd = null;
6191            int samplingInterval = 0;
6192            boolean profileAutoStop = false;
6193            if (mProfileApp != null && mProfileApp.equals(processName)) {
6194                mProfileProc = app;
6195                profileFile = mProfileFile;
6196                profileFd = mProfileFd;
6197                samplingInterval = mSamplingInterval;
6198                profileAutoStop = mAutoStopProfiler;
6199            }
6200            boolean enableTrackAllocation = false;
6201            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6202                enableTrackAllocation = true;
6203                mTrackAllocationApp = null;
6204            }
6205
6206            // If the app is being launched for restore or full backup, set it up specially
6207            boolean isRestrictedBackupMode = false;
6208            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6209                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6210                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6211                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6212            }
6213
6214            notifyPackageUse(app.instrumentationInfo != null
6215                    ? app.instrumentationInfo.packageName
6216                    : app.info.packageName);
6217            if (app.instrumentationClass != null) {
6218                notifyPackageUse(app.instrumentationClass.getPackageName());
6219            }
6220            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6221                    + processName + " with config " + mConfiguration);
6222            ApplicationInfo appInfo = app.instrumentationInfo != null
6223                    ? app.instrumentationInfo : app.info;
6224            app.compat = compatibilityInfoForPackageLocked(appInfo);
6225            if (profileFd != null) {
6226                profileFd = profileFd.dup();
6227            }
6228            ProfilerInfo profilerInfo = profileFile == null ? null
6229                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6230            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6231                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6232                    app.instrumentationUiAutomationConnection, testMode,
6233                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6234                    isRestrictedBackupMode || !normalMode, app.persistent,
6235                    new Configuration(mConfiguration), app.compat,
6236                    getCommonServicesLocked(app.isolated),
6237                    mCoreSettingsObserver.getCoreSettingsLocked());
6238            updateLruProcessLocked(app, false, null);
6239            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6240        } catch (Exception e) {
6241            // todo: Yikes!  What should we do?  For now we will try to
6242            // start another process, but that could easily get us in
6243            // an infinite loop of restarting processes...
6244            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6245
6246            app.resetPackageList(mProcessStats);
6247            app.unlinkDeathRecipient();
6248            startProcessLocked(app, "bind fail", processName);
6249            return false;
6250        }
6251
6252        // Remove this record from the list of starting applications.
6253        mPersistentStartingProcesses.remove(app);
6254        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6255                "Attach application locked removing on hold: " + app);
6256        mProcessesOnHold.remove(app);
6257
6258        boolean badApp = false;
6259        boolean didSomething = false;
6260
6261        // See if the top visible activity is waiting to run in this process...
6262        if (normalMode) {
6263            try {
6264                if (mStackSupervisor.attachApplicationLocked(app)) {
6265                    didSomething = true;
6266                }
6267            } catch (Exception e) {
6268                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6269                badApp = true;
6270            }
6271        }
6272
6273        // Find any services that should be running in this process...
6274        if (!badApp) {
6275            try {
6276                didSomething |= mServices.attachApplicationLocked(app, processName);
6277            } catch (Exception e) {
6278                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6279                badApp = true;
6280            }
6281        }
6282
6283        // Check if a next-broadcast receiver is in this process...
6284        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6285            try {
6286                didSomething |= sendPendingBroadcastsLocked(app);
6287            } catch (Exception e) {
6288                // If the app died trying to launch the receiver we declare it 'bad'
6289                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6290                badApp = true;
6291            }
6292        }
6293
6294        // Check whether the next backup agent is in this process...
6295        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6296            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6297                    "New app is backup target, launching agent for " + app);
6298            notifyPackageUse(mBackupTarget.appInfo.packageName);
6299            try {
6300                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6301                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6302                        mBackupTarget.backupMode);
6303            } catch (Exception e) {
6304                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6305                badApp = true;
6306            }
6307        }
6308
6309        if (badApp) {
6310            app.kill("error during init", true);
6311            handleAppDiedLocked(app, false, true);
6312            return false;
6313        }
6314
6315        if (!didSomething) {
6316            updateOomAdjLocked();
6317        }
6318
6319        return true;
6320    }
6321
6322    @Override
6323    public final void attachApplication(IApplicationThread thread) {
6324        synchronized (this) {
6325            int callingPid = Binder.getCallingPid();
6326            final long origId = Binder.clearCallingIdentity();
6327            attachApplicationLocked(thread, callingPid);
6328            Binder.restoreCallingIdentity(origId);
6329        }
6330    }
6331
6332    @Override
6333    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6334        final long origId = Binder.clearCallingIdentity();
6335        synchronized (this) {
6336            ActivityStack stack = ActivityRecord.getStackLocked(token);
6337            if (stack != null) {
6338                ActivityRecord r =
6339                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6340                if (stopProfiling) {
6341                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6342                        try {
6343                            mProfileFd.close();
6344                        } catch (IOException e) {
6345                        }
6346                        clearProfilerLocked();
6347                    }
6348                }
6349            }
6350        }
6351        Binder.restoreCallingIdentity(origId);
6352    }
6353
6354    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6355        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6356                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6357    }
6358
6359    void enableScreenAfterBoot() {
6360        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6361                SystemClock.uptimeMillis());
6362        mWindowManager.enableScreenAfterBoot();
6363
6364        synchronized (this) {
6365            updateEventDispatchingLocked();
6366        }
6367    }
6368
6369    @Override
6370    public void showBootMessage(final CharSequence msg, final boolean always) {
6371        if (Binder.getCallingUid() != Process.myUid()) {
6372            // These days only the core system can call this, so apps can't get in
6373            // the way of what we show about running them.
6374        }
6375        mWindowManager.showBootMessage(msg, always);
6376    }
6377
6378    @Override
6379    public void keyguardWaitingForActivityDrawn() {
6380        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6381        final long token = Binder.clearCallingIdentity();
6382        try {
6383            synchronized (this) {
6384                if (DEBUG_LOCKSCREEN) logLockScreen("");
6385                mWindowManager.keyguardWaitingForActivityDrawn();
6386                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6387                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6388                    updateSleepIfNeededLocked();
6389                }
6390            }
6391        } finally {
6392            Binder.restoreCallingIdentity(token);
6393        }
6394    }
6395
6396    @Override
6397    public void keyguardGoingAway(boolean disableWindowAnimations,
6398            boolean keyguardGoingToNotificationShade) {
6399        enforceNotIsolatedCaller("keyguardGoingAway");
6400        final long token = Binder.clearCallingIdentity();
6401        try {
6402            synchronized (this) {
6403                if (DEBUG_LOCKSCREEN) logLockScreen("");
6404                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6405                        keyguardGoingToNotificationShade);
6406                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6407                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6408                    updateSleepIfNeededLocked();
6409                }
6410            }
6411        } finally {
6412            Binder.restoreCallingIdentity(token);
6413        }
6414    }
6415
6416    final void finishBooting() {
6417        synchronized (this) {
6418            if (!mBootAnimationComplete) {
6419                mCallFinishBooting = true;
6420                return;
6421            }
6422            mCallFinishBooting = false;
6423        }
6424
6425        ArraySet<String> completedIsas = new ArraySet<String>();
6426        for (String abi : Build.SUPPORTED_ABIS) {
6427            Process.establishZygoteConnectionForAbi(abi);
6428            final String instructionSet = VMRuntime.getInstructionSet(abi);
6429            if (!completedIsas.contains(instructionSet)) {
6430                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6431                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6432                }
6433                completedIsas.add(instructionSet);
6434            }
6435        }
6436
6437        IntentFilter pkgFilter = new IntentFilter();
6438        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6439        pkgFilter.addDataScheme("package");
6440        mContext.registerReceiver(new BroadcastReceiver() {
6441            @Override
6442            public void onReceive(Context context, Intent intent) {
6443                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6444                if (pkgs != null) {
6445                    for (String pkg : pkgs) {
6446                        synchronized (ActivityManagerService.this) {
6447                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6448                                    0, "query restart")) {
6449                                setResultCode(Activity.RESULT_OK);
6450                                return;
6451                            }
6452                        }
6453                    }
6454                }
6455            }
6456        }, pkgFilter);
6457
6458        IntentFilter dumpheapFilter = new IntentFilter();
6459        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6460        mContext.registerReceiver(new BroadcastReceiver() {
6461            @Override
6462            public void onReceive(Context context, Intent intent) {
6463                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6464                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6465                } else {
6466                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6467                }
6468            }
6469        }, dumpheapFilter);
6470
6471        // Let system services know.
6472        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6473
6474        synchronized (this) {
6475            // Ensure that any processes we had put on hold are now started
6476            // up.
6477            final int NP = mProcessesOnHold.size();
6478            if (NP > 0) {
6479                ArrayList<ProcessRecord> procs =
6480                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6481                for (int ip=0; ip<NP; ip++) {
6482                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6483                            + procs.get(ip));
6484                    startProcessLocked(procs.get(ip), "on-hold", null);
6485                }
6486            }
6487
6488            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6489                // Start looking for apps that are abusing wake locks.
6490                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6491                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6492                // Tell anyone interested that we are done booting!
6493                SystemProperties.set("sys.boot_completed", "1");
6494
6495                // And trigger dev.bootcomplete if we are not showing encryption progress
6496                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6497                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6498                    SystemProperties.set("dev.bootcomplete", "1");
6499                }
6500                mUserController.sendBootCompletedLocked(
6501                        new IIntentReceiver.Stub() {
6502                            @Override
6503                            public void performReceive(Intent intent, int resultCode,
6504                                    String data, Bundle extras, boolean ordered,
6505                                    boolean sticky, int sendingUser) {
6506                                synchronized (ActivityManagerService.this) {
6507                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6508                                            true, false);
6509                                }
6510                            }
6511                        });
6512                scheduleStartProfilesLocked();
6513            }
6514        }
6515    }
6516
6517    @Override
6518    public void bootAnimationComplete() {
6519        final boolean callFinishBooting;
6520        synchronized (this) {
6521            callFinishBooting = mCallFinishBooting;
6522            mBootAnimationComplete = true;
6523        }
6524        if (callFinishBooting) {
6525            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6526            finishBooting();
6527            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6528        }
6529    }
6530
6531    final void ensureBootCompleted() {
6532        boolean booting;
6533        boolean enableScreen;
6534        synchronized (this) {
6535            booting = mBooting;
6536            mBooting = false;
6537            enableScreen = !mBooted;
6538            mBooted = true;
6539        }
6540
6541        if (booting) {
6542            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6543            finishBooting();
6544            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6545        }
6546
6547        if (enableScreen) {
6548            enableScreenAfterBoot();
6549        }
6550    }
6551
6552    @Override
6553    public final void activityResumed(IBinder token) {
6554        final long origId = Binder.clearCallingIdentity();
6555        synchronized(this) {
6556            ActivityStack stack = ActivityRecord.getStackLocked(token);
6557            if (stack != null) {
6558                ActivityRecord.activityResumedLocked(token);
6559            }
6560        }
6561        Binder.restoreCallingIdentity(origId);
6562    }
6563
6564    @Override
6565    public final void activityPaused(IBinder token) {
6566        final long origId = Binder.clearCallingIdentity();
6567        synchronized(this) {
6568            ActivityStack stack = ActivityRecord.getStackLocked(token);
6569            if (stack != null) {
6570                stack.activityPausedLocked(token, false);
6571            }
6572        }
6573        Binder.restoreCallingIdentity(origId);
6574    }
6575
6576    @Override
6577    public final void activityStopped(IBinder token, Bundle icicle,
6578            PersistableBundle persistentState, CharSequence description) {
6579        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6580
6581        // Refuse possible leaked file descriptors
6582        if (icicle != null && icicle.hasFileDescriptors()) {
6583            throw new IllegalArgumentException("File descriptors passed in Bundle");
6584        }
6585
6586        final long origId = Binder.clearCallingIdentity();
6587
6588        synchronized (this) {
6589            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6590            if (r != null) {
6591                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6592            }
6593        }
6594
6595        trimApplications();
6596
6597        Binder.restoreCallingIdentity(origId);
6598    }
6599
6600    @Override
6601    public final void activityDestroyed(IBinder token) {
6602        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6603        synchronized (this) {
6604            ActivityStack stack = ActivityRecord.getStackLocked(token);
6605            if (stack != null) {
6606                stack.activityDestroyedLocked(token, "activityDestroyed");
6607            }
6608        }
6609    }
6610
6611    @Override
6612    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6613            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6614        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6615                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6616        synchronized (this) {
6617            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6618            if (record == null) {
6619                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6620                        + "found for: " + token);
6621            }
6622            record.setSizeConfigurations(horizontalSizeConfiguration,
6623                    verticalSizeConfigurations, smallestSizeConfigurations);
6624        }
6625    }
6626
6627    @Override
6628    public final void backgroundResourcesReleased(IBinder token) {
6629        final long origId = Binder.clearCallingIdentity();
6630        try {
6631            synchronized (this) {
6632                ActivityStack stack = ActivityRecord.getStackLocked(token);
6633                if (stack != null) {
6634                    stack.backgroundResourcesReleased();
6635                }
6636            }
6637        } finally {
6638            Binder.restoreCallingIdentity(origId);
6639        }
6640    }
6641
6642    @Override
6643    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6644        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6645    }
6646
6647    @Override
6648    public final void notifyEnterAnimationComplete(IBinder token) {
6649        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6650    }
6651
6652    @Override
6653    public String getCallingPackage(IBinder token) {
6654        synchronized (this) {
6655            ActivityRecord r = getCallingRecordLocked(token);
6656            return r != null ? r.info.packageName : null;
6657        }
6658    }
6659
6660    @Override
6661    public ComponentName getCallingActivity(IBinder token) {
6662        synchronized (this) {
6663            ActivityRecord r = getCallingRecordLocked(token);
6664            return r != null ? r.intent.getComponent() : null;
6665        }
6666    }
6667
6668    private ActivityRecord getCallingRecordLocked(IBinder token) {
6669        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6670        if (r == null) {
6671            return null;
6672        }
6673        return r.resultTo;
6674    }
6675
6676    @Override
6677    public ComponentName getActivityClassForToken(IBinder token) {
6678        synchronized(this) {
6679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6680            if (r == null) {
6681                return null;
6682            }
6683            return r.intent.getComponent();
6684        }
6685    }
6686
6687    @Override
6688    public String getPackageForToken(IBinder token) {
6689        synchronized(this) {
6690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6691            if (r == null) {
6692                return null;
6693            }
6694            return r.packageName;
6695        }
6696    }
6697
6698    @Override
6699    public boolean isRootVoiceInteraction(IBinder token) {
6700        synchronized(this) {
6701            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6702            if (r == null) {
6703                return false;
6704            }
6705            return r.rootVoiceInteraction;
6706        }
6707    }
6708
6709    @Override
6710    public IIntentSender getIntentSender(int type,
6711            String packageName, IBinder token, String resultWho,
6712            int requestCode, Intent[] intents, String[] resolvedTypes,
6713            int flags, Bundle bOptions, int userId) {
6714        enforceNotIsolatedCaller("getIntentSender");
6715        // Refuse possible leaked file descriptors
6716        if (intents != null) {
6717            if (intents.length < 1) {
6718                throw new IllegalArgumentException("Intents array length must be >= 1");
6719            }
6720            for (int i=0; i<intents.length; i++) {
6721                Intent intent = intents[i];
6722                if (intent != null) {
6723                    if (intent.hasFileDescriptors()) {
6724                        throw new IllegalArgumentException("File descriptors passed in Intent");
6725                    }
6726                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6727                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6728                        throw new IllegalArgumentException(
6729                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6730                    }
6731                    intents[i] = new Intent(intent);
6732                }
6733            }
6734            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6735                throw new IllegalArgumentException(
6736                        "Intent array length does not match resolvedTypes length");
6737            }
6738        }
6739        if (bOptions != null) {
6740            if (bOptions.hasFileDescriptors()) {
6741                throw new IllegalArgumentException("File descriptors passed in options");
6742            }
6743        }
6744
6745        synchronized(this) {
6746            int callingUid = Binder.getCallingUid();
6747            int origUserId = userId;
6748            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6749                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6750                    ALLOW_NON_FULL, "getIntentSender", null);
6751            if (origUserId == UserHandle.USER_CURRENT) {
6752                // We don't want to evaluate this until the pending intent is
6753                // actually executed.  However, we do want to always do the
6754                // security checking for it above.
6755                userId = UserHandle.USER_CURRENT;
6756            }
6757            try {
6758                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6759                    int uid = AppGlobals.getPackageManager()
6760                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6761                    if (!UserHandle.isSameApp(callingUid, uid)) {
6762                        String msg = "Permission Denial: getIntentSender() from pid="
6763                            + Binder.getCallingPid()
6764                            + ", uid=" + Binder.getCallingUid()
6765                            + ", (need uid=" + uid + ")"
6766                            + " is not allowed to send as package " + packageName;
6767                        Slog.w(TAG, msg);
6768                        throw new SecurityException(msg);
6769                    }
6770                }
6771
6772                return getIntentSenderLocked(type, packageName, callingUid, userId,
6773                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6774
6775            } catch (RemoteException e) {
6776                throw new SecurityException(e);
6777            }
6778        }
6779    }
6780
6781    IIntentSender getIntentSenderLocked(int type, String packageName,
6782            int callingUid, int userId, IBinder token, String resultWho,
6783            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6784            Bundle bOptions) {
6785        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6786        ActivityRecord activity = null;
6787        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6788            activity = ActivityRecord.isInStackLocked(token);
6789            if (activity == null) {
6790                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6791                return null;
6792            }
6793            if (activity.finishing) {
6794                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6795                return null;
6796            }
6797        }
6798
6799        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6800        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6801        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6802        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6803                |PendingIntent.FLAG_UPDATE_CURRENT);
6804
6805        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6806                type, packageName, activity, resultWho,
6807                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6808        WeakReference<PendingIntentRecord> ref;
6809        ref = mIntentSenderRecords.get(key);
6810        PendingIntentRecord rec = ref != null ? ref.get() : null;
6811        if (rec != null) {
6812            if (!cancelCurrent) {
6813                if (updateCurrent) {
6814                    if (rec.key.requestIntent != null) {
6815                        rec.key.requestIntent.replaceExtras(intents != null ?
6816                                intents[intents.length - 1] : null);
6817                    }
6818                    if (intents != null) {
6819                        intents[intents.length-1] = rec.key.requestIntent;
6820                        rec.key.allIntents = intents;
6821                        rec.key.allResolvedTypes = resolvedTypes;
6822                    } else {
6823                        rec.key.allIntents = null;
6824                        rec.key.allResolvedTypes = null;
6825                    }
6826                }
6827                return rec;
6828            }
6829            rec.canceled = true;
6830            mIntentSenderRecords.remove(key);
6831        }
6832        if (noCreate) {
6833            return rec;
6834        }
6835        rec = new PendingIntentRecord(this, key, callingUid);
6836        mIntentSenderRecords.put(key, rec.ref);
6837        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6838            if (activity.pendingResults == null) {
6839                activity.pendingResults
6840                        = new HashSet<WeakReference<PendingIntentRecord>>();
6841            }
6842            activity.pendingResults.add(rec.ref);
6843        }
6844        return rec;
6845    }
6846
6847    @Override
6848    public void cancelIntentSender(IIntentSender sender) {
6849        if (!(sender instanceof PendingIntentRecord)) {
6850            return;
6851        }
6852        synchronized(this) {
6853            PendingIntentRecord rec = (PendingIntentRecord)sender;
6854            try {
6855                int uid = AppGlobals.getPackageManager()
6856                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6857                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6858                    String msg = "Permission Denial: cancelIntentSender() from pid="
6859                        + Binder.getCallingPid()
6860                        + ", uid=" + Binder.getCallingUid()
6861                        + " is not allowed to cancel packges "
6862                        + rec.key.packageName;
6863                    Slog.w(TAG, msg);
6864                    throw new SecurityException(msg);
6865                }
6866            } catch (RemoteException e) {
6867                throw new SecurityException(e);
6868            }
6869            cancelIntentSenderLocked(rec, true);
6870        }
6871    }
6872
6873    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6874        rec.canceled = true;
6875        mIntentSenderRecords.remove(rec.key);
6876        if (cleanActivity && rec.key.activity != null) {
6877            rec.key.activity.pendingResults.remove(rec.ref);
6878        }
6879    }
6880
6881    @Override
6882    public String getPackageForIntentSender(IIntentSender pendingResult) {
6883        if (!(pendingResult instanceof PendingIntentRecord)) {
6884            return null;
6885        }
6886        try {
6887            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6888            return res.key.packageName;
6889        } catch (ClassCastException e) {
6890        }
6891        return null;
6892    }
6893
6894    @Override
6895    public int getUidForIntentSender(IIntentSender sender) {
6896        if (sender instanceof PendingIntentRecord) {
6897            try {
6898                PendingIntentRecord res = (PendingIntentRecord)sender;
6899                return res.uid;
6900            } catch (ClassCastException e) {
6901            }
6902        }
6903        return -1;
6904    }
6905
6906    @Override
6907    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6908        if (!(pendingResult instanceof PendingIntentRecord)) {
6909            return false;
6910        }
6911        try {
6912            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6913            if (res.key.allIntents == null) {
6914                return false;
6915            }
6916            for (int i=0; i<res.key.allIntents.length; i++) {
6917                Intent intent = res.key.allIntents[i];
6918                if (intent.getPackage() != null && intent.getComponent() != null) {
6919                    return false;
6920                }
6921            }
6922            return true;
6923        } catch (ClassCastException e) {
6924        }
6925        return false;
6926    }
6927
6928    @Override
6929    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6930        if (!(pendingResult instanceof PendingIntentRecord)) {
6931            return false;
6932        }
6933        try {
6934            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6935            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6936                return true;
6937            }
6938            return false;
6939        } catch (ClassCastException e) {
6940        }
6941        return false;
6942    }
6943
6944    @Override
6945    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6946        if (!(pendingResult instanceof PendingIntentRecord)) {
6947            return null;
6948        }
6949        try {
6950            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6951            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6952        } catch (ClassCastException e) {
6953        }
6954        return null;
6955    }
6956
6957    @Override
6958    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6959        if (!(pendingResult instanceof PendingIntentRecord)) {
6960            return null;
6961        }
6962        try {
6963            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6964            synchronized (this) {
6965                return getTagForIntentSenderLocked(res, prefix);
6966            }
6967        } catch (ClassCastException e) {
6968        }
6969        return null;
6970    }
6971
6972    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6973        final Intent intent = res.key.requestIntent;
6974        if (intent != null) {
6975            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6976                    || res.lastTagPrefix.equals(prefix))) {
6977                return res.lastTag;
6978            }
6979            res.lastTagPrefix = prefix;
6980            final StringBuilder sb = new StringBuilder(128);
6981            if (prefix != null) {
6982                sb.append(prefix);
6983            }
6984            if (intent.getAction() != null) {
6985                sb.append(intent.getAction());
6986            } else if (intent.getComponent() != null) {
6987                intent.getComponent().appendShortString(sb);
6988            } else {
6989                sb.append("?");
6990            }
6991            return res.lastTag = sb.toString();
6992        }
6993        return null;
6994    }
6995
6996    @Override
6997    public void setProcessLimit(int max) {
6998        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6999                "setProcessLimit()");
7000        synchronized (this) {
7001            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7002            mProcessLimitOverride = max;
7003        }
7004        trimApplications();
7005    }
7006
7007    @Override
7008    public int getProcessLimit() {
7009        synchronized (this) {
7010            return mProcessLimitOverride;
7011        }
7012    }
7013
7014    void foregroundTokenDied(ForegroundToken token) {
7015        synchronized (ActivityManagerService.this) {
7016            synchronized (mPidsSelfLocked) {
7017                ForegroundToken cur
7018                    = mForegroundProcesses.get(token.pid);
7019                if (cur != token) {
7020                    return;
7021                }
7022                mForegroundProcesses.remove(token.pid);
7023                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7024                if (pr == null) {
7025                    return;
7026                }
7027                pr.forcingToForeground = null;
7028                updateProcessForegroundLocked(pr, false, false);
7029            }
7030            updateOomAdjLocked();
7031        }
7032    }
7033
7034    @Override
7035    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7036        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7037                "setProcessForeground()");
7038        synchronized(this) {
7039            boolean changed = false;
7040
7041            synchronized (mPidsSelfLocked) {
7042                ProcessRecord pr = mPidsSelfLocked.get(pid);
7043                if (pr == null && isForeground) {
7044                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7045                    return;
7046                }
7047                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7048                if (oldToken != null) {
7049                    oldToken.token.unlinkToDeath(oldToken, 0);
7050                    mForegroundProcesses.remove(pid);
7051                    if (pr != null) {
7052                        pr.forcingToForeground = null;
7053                    }
7054                    changed = true;
7055                }
7056                if (isForeground && token != null) {
7057                    ForegroundToken newToken = new ForegroundToken() {
7058                        @Override
7059                        public void binderDied() {
7060                            foregroundTokenDied(this);
7061                        }
7062                    };
7063                    newToken.pid = pid;
7064                    newToken.token = token;
7065                    try {
7066                        token.linkToDeath(newToken, 0);
7067                        mForegroundProcesses.put(pid, newToken);
7068                        pr.forcingToForeground = token;
7069                        changed = true;
7070                    } catch (RemoteException e) {
7071                        // If the process died while doing this, we will later
7072                        // do the cleanup with the process death link.
7073                    }
7074                }
7075            }
7076
7077            if (changed) {
7078                updateOomAdjLocked();
7079            }
7080        }
7081    }
7082
7083    // =========================================================
7084    // PROCESS INFO
7085    // =========================================================
7086
7087    static class ProcessInfoService extends IProcessInfoService.Stub {
7088        final ActivityManagerService mActivityManagerService;
7089        ProcessInfoService(ActivityManagerService activityManagerService) {
7090            mActivityManagerService = activityManagerService;
7091        }
7092
7093        @Override
7094        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7095            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7096        }
7097    }
7098
7099    /**
7100     * For each PID in the given input array, write the current process state
7101     * for that process into the output array, or -1 to indicate that no
7102     * process with the given PID exists.
7103     */
7104    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7105        if (pids == null) {
7106            throw new NullPointerException("pids");
7107        } else if (states == null) {
7108            throw new NullPointerException("states");
7109        } else if (pids.length != states.length) {
7110            throw new IllegalArgumentException("input and output arrays have different lengths!");
7111        }
7112
7113        synchronized (mPidsSelfLocked) {
7114            for (int i = 0; i < pids.length; i++) {
7115                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7116                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7117                        pr.curProcState;
7118            }
7119        }
7120    }
7121
7122    // =========================================================
7123    // PERMISSIONS
7124    // =========================================================
7125
7126    static class PermissionController extends IPermissionController.Stub {
7127        ActivityManagerService mActivityManagerService;
7128        PermissionController(ActivityManagerService activityManagerService) {
7129            mActivityManagerService = activityManagerService;
7130        }
7131
7132        @Override
7133        public boolean checkPermission(String permission, int pid, int uid) {
7134            return mActivityManagerService.checkPermission(permission, pid,
7135                    uid) == PackageManager.PERMISSION_GRANTED;
7136        }
7137
7138        @Override
7139        public String[] getPackagesForUid(int uid) {
7140            return mActivityManagerService.mContext.getPackageManager()
7141                    .getPackagesForUid(uid);
7142        }
7143
7144        @Override
7145        public boolean isRuntimePermission(String permission) {
7146            try {
7147                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7148                        .getPermissionInfo(permission, 0);
7149                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7150            } catch (NameNotFoundException nnfe) {
7151                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7152            }
7153            return false;
7154        }
7155    }
7156
7157    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7158        @Override
7159        public int checkComponentPermission(String permission, int pid, int uid,
7160                int owningUid, boolean exported) {
7161            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7162                    owningUid, exported);
7163        }
7164
7165        @Override
7166        public Object getAMSLock() {
7167            return ActivityManagerService.this;
7168        }
7169    }
7170
7171    /**
7172     * This can be called with or without the global lock held.
7173     */
7174    int checkComponentPermission(String permission, int pid, int uid,
7175            int owningUid, boolean exported) {
7176        if (pid == MY_PID) {
7177            return PackageManager.PERMISSION_GRANTED;
7178        }
7179        return ActivityManager.checkComponentPermission(permission, uid,
7180                owningUid, exported);
7181    }
7182
7183    /**
7184     * As the only public entry point for permissions checking, this method
7185     * can enforce the semantic that requesting a check on a null global
7186     * permission is automatically denied.  (Internally a null permission
7187     * string is used when calling {@link #checkComponentPermission} in cases
7188     * when only uid-based security is needed.)
7189     *
7190     * This can be called with or without the global lock held.
7191     */
7192    @Override
7193    public int checkPermission(String permission, int pid, int uid) {
7194        if (permission == null) {
7195            return PackageManager.PERMISSION_DENIED;
7196        }
7197        return checkComponentPermission(permission, pid, uid, -1, true);
7198    }
7199
7200    @Override
7201    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7202        if (permission == null) {
7203            return PackageManager.PERMISSION_DENIED;
7204        }
7205
7206        // We might be performing an operation on behalf of an indirect binder
7207        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7208        // client identity accordingly before proceeding.
7209        Identity tlsIdentity = sCallerIdentity.get();
7210        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7211            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7212                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7213            uid = tlsIdentity.uid;
7214            pid = tlsIdentity.pid;
7215        }
7216
7217        return checkComponentPermission(permission, pid, uid, -1, true);
7218    }
7219
7220    /**
7221     * Binder IPC calls go through the public entry point.
7222     * This can be called with or without the global lock held.
7223     */
7224    int checkCallingPermission(String permission) {
7225        return checkPermission(permission,
7226                Binder.getCallingPid(),
7227                UserHandle.getAppId(Binder.getCallingUid()));
7228    }
7229
7230    /**
7231     * This can be called with or without the global lock held.
7232     */
7233    void enforceCallingPermission(String permission, String func) {
7234        if (checkCallingPermission(permission)
7235                == PackageManager.PERMISSION_GRANTED) {
7236            return;
7237        }
7238
7239        String msg = "Permission Denial: " + func + " from pid="
7240                + Binder.getCallingPid()
7241                + ", uid=" + Binder.getCallingUid()
7242                + " requires " + permission;
7243        Slog.w(TAG, msg);
7244        throw new SecurityException(msg);
7245    }
7246
7247    /**
7248     * Determine if UID is holding permissions required to access {@link Uri} in
7249     * the given {@link ProviderInfo}. Final permission checking is always done
7250     * in {@link ContentProvider}.
7251     */
7252    private final boolean checkHoldingPermissionsLocked(
7253            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7254        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7255                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7256        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7257            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7258                    != PERMISSION_GRANTED) {
7259                return false;
7260            }
7261        }
7262        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7263    }
7264
7265    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7266            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7267        if (pi.applicationInfo.uid == uid) {
7268            return true;
7269        } else if (!pi.exported) {
7270            return false;
7271        }
7272
7273        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7274        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7275        try {
7276            // check if target holds top-level <provider> permissions
7277            if (!readMet && pi.readPermission != null && considerUidPermissions
7278                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7279                readMet = true;
7280            }
7281            if (!writeMet && pi.writePermission != null && considerUidPermissions
7282                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7283                writeMet = true;
7284            }
7285
7286            // track if unprotected read/write is allowed; any denied
7287            // <path-permission> below removes this ability
7288            boolean allowDefaultRead = pi.readPermission == null;
7289            boolean allowDefaultWrite = pi.writePermission == null;
7290
7291            // check if target holds any <path-permission> that match uri
7292            final PathPermission[] pps = pi.pathPermissions;
7293            if (pps != null) {
7294                final String path = grantUri.uri.getPath();
7295                int i = pps.length;
7296                while (i > 0 && (!readMet || !writeMet)) {
7297                    i--;
7298                    PathPermission pp = pps[i];
7299                    if (pp.match(path)) {
7300                        if (!readMet) {
7301                            final String pprperm = pp.getReadPermission();
7302                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7303                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7304                                    + ": match=" + pp.match(path)
7305                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7306                            if (pprperm != null) {
7307                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7308                                        == PERMISSION_GRANTED) {
7309                                    readMet = true;
7310                                } else {
7311                                    allowDefaultRead = false;
7312                                }
7313                            }
7314                        }
7315                        if (!writeMet) {
7316                            final String ppwperm = pp.getWritePermission();
7317                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7318                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7319                                    + ": match=" + pp.match(path)
7320                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7321                            if (ppwperm != null) {
7322                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7323                                        == PERMISSION_GRANTED) {
7324                                    writeMet = true;
7325                                } else {
7326                                    allowDefaultWrite = false;
7327                                }
7328                            }
7329                        }
7330                    }
7331                }
7332            }
7333
7334            // grant unprotected <provider> read/write, if not blocked by
7335            // <path-permission> above
7336            if (allowDefaultRead) readMet = true;
7337            if (allowDefaultWrite) writeMet = true;
7338
7339        } catch (RemoteException e) {
7340            return false;
7341        }
7342
7343        return readMet && writeMet;
7344    }
7345
7346    public int getAppStartMode(int uid, String packageName) {
7347        synchronized (this) {
7348            boolean bg = checkAllowBackgroundLocked(uid, packageName, -1);
7349            return bg ? ActivityManager.APP_START_MODE_NORMAL
7350                    : ActivityManager.APP_START_MODE_DISABLED;
7351        }
7352    }
7353
7354    boolean checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7355        UidRecord uidRec = mActiveUids.get(uid);
7356        if (uidRec == null || uidRec.idle) {
7357            if (callingPid >= 0) {
7358                ProcessRecord proc;
7359                synchronized (mPidsSelfLocked) {
7360                    proc = mPidsSelfLocked.get(callingPid);
7361                }
7362                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7363                    // Whoever is instigating this is in the foreground, so we will allow it
7364                    // to go through.
7365                    return true;
7366                }
7367            }
7368            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7369                    != AppOpsManager.MODE_ALLOWED) {
7370                return false;
7371            }
7372        }
7373        return true;
7374    }
7375
7376    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7377        ProviderInfo pi = null;
7378        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7379        if (cpr != null) {
7380            pi = cpr.info;
7381        } else {
7382            try {
7383                pi = AppGlobals.getPackageManager().resolveContentProvider(
7384                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7385            } catch (RemoteException ex) {
7386            }
7387        }
7388        return pi;
7389    }
7390
7391    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7392        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7393        if (targetUris != null) {
7394            return targetUris.get(grantUri);
7395        }
7396        return null;
7397    }
7398
7399    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7400            String targetPkg, int targetUid, GrantUri grantUri) {
7401        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7402        if (targetUris == null) {
7403            targetUris = Maps.newArrayMap();
7404            mGrantedUriPermissions.put(targetUid, targetUris);
7405        }
7406
7407        UriPermission perm = targetUris.get(grantUri);
7408        if (perm == null) {
7409            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7410            targetUris.put(grantUri, perm);
7411        }
7412
7413        return perm;
7414    }
7415
7416    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7417            final int modeFlags) {
7418        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7419        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7420                : UriPermission.STRENGTH_OWNED;
7421
7422        // Root gets to do everything.
7423        if (uid == 0) {
7424            return true;
7425        }
7426
7427        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7428        if (perms == null) return false;
7429
7430        // First look for exact match
7431        final UriPermission exactPerm = perms.get(grantUri);
7432        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7433            return true;
7434        }
7435
7436        // No exact match, look for prefixes
7437        final int N = perms.size();
7438        for (int i = 0; i < N; i++) {
7439            final UriPermission perm = perms.valueAt(i);
7440            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7441                    && perm.getStrength(modeFlags) >= minStrength) {
7442                return true;
7443            }
7444        }
7445
7446        return false;
7447    }
7448
7449    /**
7450     * @param uri This uri must NOT contain an embedded userId.
7451     * @param userId The userId in which the uri is to be resolved.
7452     */
7453    @Override
7454    public int checkUriPermission(Uri uri, int pid, int uid,
7455            final int modeFlags, int userId, IBinder callerToken) {
7456        enforceNotIsolatedCaller("checkUriPermission");
7457
7458        // Another redirected-binder-call permissions check as in
7459        // {@link checkPermissionWithToken}.
7460        Identity tlsIdentity = sCallerIdentity.get();
7461        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7462            uid = tlsIdentity.uid;
7463            pid = tlsIdentity.pid;
7464        }
7465
7466        // Our own process gets to do everything.
7467        if (pid == MY_PID) {
7468            return PackageManager.PERMISSION_GRANTED;
7469        }
7470        synchronized (this) {
7471            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7472                    ? PackageManager.PERMISSION_GRANTED
7473                    : PackageManager.PERMISSION_DENIED;
7474        }
7475    }
7476
7477    /**
7478     * Check if the targetPkg can be granted permission to access uri by
7479     * the callingUid using the given modeFlags.  Throws a security exception
7480     * if callingUid is not allowed to do this.  Returns the uid of the target
7481     * if the URI permission grant should be performed; returns -1 if it is not
7482     * needed (for example targetPkg already has permission to access the URI).
7483     * If you already know the uid of the target, you can supply it in
7484     * lastTargetUid else set that to -1.
7485     */
7486    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7487            final int modeFlags, int lastTargetUid) {
7488        if (!Intent.isAccessUriMode(modeFlags)) {
7489            return -1;
7490        }
7491
7492        if (targetPkg != null) {
7493            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7494                    "Checking grant " + targetPkg + " permission to " + grantUri);
7495        }
7496
7497        final IPackageManager pm = AppGlobals.getPackageManager();
7498
7499        // If this is not a content: uri, we can't do anything with it.
7500        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7501            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7502                    "Can't grant URI permission for non-content URI: " + grantUri);
7503            return -1;
7504        }
7505
7506        final String authority = grantUri.uri.getAuthority();
7507        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7508        if (pi == null) {
7509            Slog.w(TAG, "No content provider found for permission check: " +
7510                    grantUri.uri.toSafeString());
7511            return -1;
7512        }
7513
7514        int targetUid = lastTargetUid;
7515        if (targetUid < 0 && targetPkg != null) {
7516            try {
7517                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7518                if (targetUid < 0) {
7519                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7520                            "Can't grant URI permission no uid for: " + targetPkg);
7521                    return -1;
7522                }
7523            } catch (RemoteException ex) {
7524                return -1;
7525            }
7526        }
7527
7528        if (targetUid >= 0) {
7529            // First...  does the target actually need this permission?
7530            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7531                // No need to grant the target this permission.
7532                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7533                        "Target " + targetPkg + " already has full permission to " + grantUri);
7534                return -1;
7535            }
7536        } else {
7537            // First...  there is no target package, so can anyone access it?
7538            boolean allowed = pi.exported;
7539            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7540                if (pi.readPermission != null) {
7541                    allowed = false;
7542                }
7543            }
7544            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7545                if (pi.writePermission != null) {
7546                    allowed = false;
7547                }
7548            }
7549            if (allowed) {
7550                return -1;
7551            }
7552        }
7553
7554        /* There is a special cross user grant if:
7555         * - The target is on another user.
7556         * - Apps on the current user can access the uri without any uid permissions.
7557         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7558         * grant uri permissions.
7559         */
7560        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7561                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7562                modeFlags, false /*without considering the uid permissions*/);
7563
7564        // Second...  is the provider allowing granting of URI permissions?
7565        if (!specialCrossUserGrant) {
7566            if (!pi.grantUriPermissions) {
7567                throw new SecurityException("Provider " + pi.packageName
7568                        + "/" + pi.name
7569                        + " does not allow granting of Uri permissions (uri "
7570                        + grantUri + ")");
7571            }
7572            if (pi.uriPermissionPatterns != null) {
7573                final int N = pi.uriPermissionPatterns.length;
7574                boolean allowed = false;
7575                for (int i=0; i<N; i++) {
7576                    if (pi.uriPermissionPatterns[i] != null
7577                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7578                        allowed = true;
7579                        break;
7580                    }
7581                }
7582                if (!allowed) {
7583                    throw new SecurityException("Provider " + pi.packageName
7584                            + "/" + pi.name
7585                            + " does not allow granting of permission to path of Uri "
7586                            + grantUri);
7587                }
7588            }
7589        }
7590
7591        // Third...  does the caller itself have permission to access
7592        // this uri?
7593        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7594            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7595                // Require they hold a strong enough Uri permission
7596                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7597                    throw new SecurityException("Uid " + callingUid
7598                            + " does not have permission to uri " + grantUri);
7599                }
7600            }
7601        }
7602        return targetUid;
7603    }
7604
7605    /**
7606     * @param uri This uri must NOT contain an embedded userId.
7607     * @param userId The userId in which the uri is to be resolved.
7608     */
7609    @Override
7610    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7611            final int modeFlags, int userId) {
7612        enforceNotIsolatedCaller("checkGrantUriPermission");
7613        synchronized(this) {
7614            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7615                    new GrantUri(userId, uri, false), modeFlags, -1);
7616        }
7617    }
7618
7619    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7620            final int modeFlags, UriPermissionOwner owner) {
7621        if (!Intent.isAccessUriMode(modeFlags)) {
7622            return;
7623        }
7624
7625        // So here we are: the caller has the assumed permission
7626        // to the uri, and the target doesn't.  Let's now give this to
7627        // the target.
7628
7629        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7630                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7631
7632        final String authority = grantUri.uri.getAuthority();
7633        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7634        if (pi == null) {
7635            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7636            return;
7637        }
7638
7639        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7640            grantUri.prefix = true;
7641        }
7642        final UriPermission perm = findOrCreateUriPermissionLocked(
7643                pi.packageName, targetPkg, targetUid, grantUri);
7644        perm.grantModes(modeFlags, owner);
7645    }
7646
7647    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7648            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7649        if (targetPkg == null) {
7650            throw new NullPointerException("targetPkg");
7651        }
7652        int targetUid;
7653        final IPackageManager pm = AppGlobals.getPackageManager();
7654        try {
7655            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7656        } catch (RemoteException ex) {
7657            return;
7658        }
7659
7660        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7661                targetUid);
7662        if (targetUid < 0) {
7663            return;
7664        }
7665
7666        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7667                owner);
7668    }
7669
7670    static class NeededUriGrants extends ArrayList<GrantUri> {
7671        final String targetPkg;
7672        final int targetUid;
7673        final int flags;
7674
7675        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7676            this.targetPkg = targetPkg;
7677            this.targetUid = targetUid;
7678            this.flags = flags;
7679        }
7680    }
7681
7682    /**
7683     * Like checkGrantUriPermissionLocked, but takes an Intent.
7684     */
7685    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7686            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7687        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7688                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7689                + " clip=" + (intent != null ? intent.getClipData() : null)
7690                + " from " + intent + "; flags=0x"
7691                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7692
7693        if (targetPkg == null) {
7694            throw new NullPointerException("targetPkg");
7695        }
7696
7697        if (intent == null) {
7698            return null;
7699        }
7700        Uri data = intent.getData();
7701        ClipData clip = intent.getClipData();
7702        if (data == null && clip == null) {
7703            return null;
7704        }
7705        // Default userId for uris in the intent (if they don't specify it themselves)
7706        int contentUserHint = intent.getContentUserHint();
7707        if (contentUserHint == UserHandle.USER_CURRENT) {
7708            contentUserHint = UserHandle.getUserId(callingUid);
7709        }
7710        final IPackageManager pm = AppGlobals.getPackageManager();
7711        int targetUid;
7712        if (needed != null) {
7713            targetUid = needed.targetUid;
7714        } else {
7715            try {
7716                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7717            } catch (RemoteException ex) {
7718                return null;
7719            }
7720            if (targetUid < 0) {
7721                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7722                        "Can't grant URI permission no uid for: " + targetPkg
7723                        + " on user " + targetUserId);
7724                return null;
7725            }
7726        }
7727        if (data != null) {
7728            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7729            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7730                    targetUid);
7731            if (targetUid > 0) {
7732                if (needed == null) {
7733                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7734                }
7735                needed.add(grantUri);
7736            }
7737        }
7738        if (clip != null) {
7739            for (int i=0; i<clip.getItemCount(); i++) {
7740                Uri uri = clip.getItemAt(i).getUri();
7741                if (uri != null) {
7742                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7743                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7744                            targetUid);
7745                    if (targetUid > 0) {
7746                        if (needed == null) {
7747                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7748                        }
7749                        needed.add(grantUri);
7750                    }
7751                } else {
7752                    Intent clipIntent = clip.getItemAt(i).getIntent();
7753                    if (clipIntent != null) {
7754                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7755                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7756                        if (newNeeded != null) {
7757                            needed = newNeeded;
7758                        }
7759                    }
7760                }
7761            }
7762        }
7763
7764        return needed;
7765    }
7766
7767    /**
7768     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7769     */
7770    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7771            UriPermissionOwner owner) {
7772        if (needed != null) {
7773            for (int i=0; i<needed.size(); i++) {
7774                GrantUri grantUri = needed.get(i);
7775                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7776                        grantUri, needed.flags, owner);
7777            }
7778        }
7779    }
7780
7781    void grantUriPermissionFromIntentLocked(int callingUid,
7782            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7783        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7784                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7785        if (needed == null) {
7786            return;
7787        }
7788
7789        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7790    }
7791
7792    /**
7793     * @param uri This uri must NOT contain an embedded userId.
7794     * @param userId The userId in which the uri is to be resolved.
7795     */
7796    @Override
7797    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7798            final int modeFlags, int userId) {
7799        enforceNotIsolatedCaller("grantUriPermission");
7800        GrantUri grantUri = new GrantUri(userId, uri, false);
7801        synchronized(this) {
7802            final ProcessRecord r = getRecordForAppLocked(caller);
7803            if (r == null) {
7804                throw new SecurityException("Unable to find app for caller "
7805                        + caller
7806                        + " when granting permission to uri " + grantUri);
7807            }
7808            if (targetPkg == null) {
7809                throw new IllegalArgumentException("null target");
7810            }
7811            if (grantUri == null) {
7812                throw new IllegalArgumentException("null uri");
7813            }
7814
7815            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7816                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7817                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7818                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7819
7820            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7821                    UserHandle.getUserId(r.uid));
7822        }
7823    }
7824
7825    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7826        if (perm.modeFlags == 0) {
7827            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7828                    perm.targetUid);
7829            if (perms != null) {
7830                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7831                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7832
7833                perms.remove(perm.uri);
7834                if (perms.isEmpty()) {
7835                    mGrantedUriPermissions.remove(perm.targetUid);
7836                }
7837            }
7838        }
7839    }
7840
7841    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7842        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7843                "Revoking all granted permissions to " + grantUri);
7844
7845        final IPackageManager pm = AppGlobals.getPackageManager();
7846        final String authority = grantUri.uri.getAuthority();
7847        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7848        if (pi == null) {
7849            Slog.w(TAG, "No content provider found for permission revoke: "
7850                    + grantUri.toSafeString());
7851            return;
7852        }
7853
7854        // Does the caller have this permission on the URI?
7855        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7856            // If they don't have direct access to the URI, then revoke any
7857            // ownerless URI permissions that have been granted to them.
7858            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7859            if (perms != null) {
7860                boolean persistChanged = false;
7861                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7862                    final UriPermission perm = it.next();
7863                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7864                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7865                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7866                                "Revoking non-owned " + perm.targetUid
7867                                + " permission to " + perm.uri);
7868                        persistChanged |= perm.revokeModes(
7869                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7870                        if (perm.modeFlags == 0) {
7871                            it.remove();
7872                        }
7873                    }
7874                }
7875                if (perms.isEmpty()) {
7876                    mGrantedUriPermissions.remove(callingUid);
7877                }
7878                if (persistChanged) {
7879                    schedulePersistUriGrants();
7880                }
7881            }
7882            return;
7883        }
7884
7885        boolean persistChanged = false;
7886
7887        // Go through all of the permissions and remove any that match.
7888        int N = mGrantedUriPermissions.size();
7889        for (int i = 0; i < N; i++) {
7890            final int targetUid = mGrantedUriPermissions.keyAt(i);
7891            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7892
7893            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7894                final UriPermission perm = it.next();
7895                if (perm.uri.sourceUserId == grantUri.sourceUserId
7896                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7897                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7898                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7899                    persistChanged |= perm.revokeModes(
7900                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7901                    if (perm.modeFlags == 0) {
7902                        it.remove();
7903                    }
7904                }
7905            }
7906
7907            if (perms.isEmpty()) {
7908                mGrantedUriPermissions.remove(targetUid);
7909                N--;
7910                i--;
7911            }
7912        }
7913
7914        if (persistChanged) {
7915            schedulePersistUriGrants();
7916        }
7917    }
7918
7919    /**
7920     * @param uri This uri must NOT contain an embedded userId.
7921     * @param userId The userId in which the uri is to be resolved.
7922     */
7923    @Override
7924    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7925            int userId) {
7926        enforceNotIsolatedCaller("revokeUriPermission");
7927        synchronized(this) {
7928            final ProcessRecord r = getRecordForAppLocked(caller);
7929            if (r == null) {
7930                throw new SecurityException("Unable to find app for caller "
7931                        + caller
7932                        + " when revoking permission to uri " + uri);
7933            }
7934            if (uri == null) {
7935                Slog.w(TAG, "revokeUriPermission: null uri");
7936                return;
7937            }
7938
7939            if (!Intent.isAccessUriMode(modeFlags)) {
7940                return;
7941            }
7942
7943            final String authority = uri.getAuthority();
7944            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7945            if (pi == null) {
7946                Slog.w(TAG, "No content provider found for permission revoke: "
7947                        + uri.toSafeString());
7948                return;
7949            }
7950
7951            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7952        }
7953    }
7954
7955    /**
7956     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7957     * given package.
7958     *
7959     * @param packageName Package name to match, or {@code null} to apply to all
7960     *            packages.
7961     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7962     *            to all users.
7963     * @param persistable If persistable grants should be removed.
7964     */
7965    private void removeUriPermissionsForPackageLocked(
7966            String packageName, int userHandle, boolean persistable) {
7967        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7968            throw new IllegalArgumentException("Must narrow by either package or user");
7969        }
7970
7971        boolean persistChanged = false;
7972
7973        int N = mGrantedUriPermissions.size();
7974        for (int i = 0; i < N; i++) {
7975            final int targetUid = mGrantedUriPermissions.keyAt(i);
7976            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7977
7978            // Only inspect grants matching user
7979            if (userHandle == UserHandle.USER_ALL
7980                    || userHandle == UserHandle.getUserId(targetUid)) {
7981                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7982                    final UriPermission perm = it.next();
7983
7984                    // Only inspect grants matching package
7985                    if (packageName == null || perm.sourcePkg.equals(packageName)
7986                            || perm.targetPkg.equals(packageName)) {
7987                        persistChanged |= perm.revokeModes(persistable
7988                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7989
7990                        // Only remove when no modes remain; any persisted grants
7991                        // will keep this alive.
7992                        if (perm.modeFlags == 0) {
7993                            it.remove();
7994                        }
7995                    }
7996                }
7997
7998                if (perms.isEmpty()) {
7999                    mGrantedUriPermissions.remove(targetUid);
8000                    N--;
8001                    i--;
8002                }
8003            }
8004        }
8005
8006        if (persistChanged) {
8007            schedulePersistUriGrants();
8008        }
8009    }
8010
8011    @Override
8012    public IBinder newUriPermissionOwner(String name) {
8013        enforceNotIsolatedCaller("newUriPermissionOwner");
8014        synchronized(this) {
8015            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8016            return owner.getExternalTokenLocked();
8017        }
8018    }
8019
8020    /**
8021     * @param uri This uri must NOT contain an embedded userId.
8022     * @param sourceUserId The userId in which the uri is to be resolved.
8023     * @param targetUserId The userId of the app that receives the grant.
8024     */
8025    @Override
8026    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8027            final int modeFlags, int sourceUserId, int targetUserId) {
8028        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8029                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8030                "grantUriPermissionFromOwner", null);
8031        synchronized(this) {
8032            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8033            if (owner == null) {
8034                throw new IllegalArgumentException("Unknown owner: " + token);
8035            }
8036            if (fromUid != Binder.getCallingUid()) {
8037                if (Binder.getCallingUid() != Process.myUid()) {
8038                    // Only system code can grant URI permissions on behalf
8039                    // of other users.
8040                    throw new SecurityException("nice try");
8041                }
8042            }
8043            if (targetPkg == null) {
8044                throw new IllegalArgumentException("null target");
8045            }
8046            if (uri == null) {
8047                throw new IllegalArgumentException("null uri");
8048            }
8049
8050            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8051                    modeFlags, owner, targetUserId);
8052        }
8053    }
8054
8055    /**
8056     * @param uri This uri must NOT contain an embedded userId.
8057     * @param userId The userId in which the uri is to be resolved.
8058     */
8059    @Override
8060    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8061        synchronized(this) {
8062            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8063            if (owner == null) {
8064                throw new IllegalArgumentException("Unknown owner: " + token);
8065            }
8066
8067            if (uri == null) {
8068                owner.removeUriPermissionsLocked(mode);
8069            } else {
8070                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8071            }
8072        }
8073    }
8074
8075    private void schedulePersistUriGrants() {
8076        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8077            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8078                    10 * DateUtils.SECOND_IN_MILLIS);
8079        }
8080    }
8081
8082    private void writeGrantedUriPermissions() {
8083        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8084
8085        // Snapshot permissions so we can persist without lock
8086        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8087        synchronized (this) {
8088            final int size = mGrantedUriPermissions.size();
8089            for (int i = 0; i < size; i++) {
8090                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8091                for (UriPermission perm : perms.values()) {
8092                    if (perm.persistedModeFlags != 0) {
8093                        persist.add(perm.snapshot());
8094                    }
8095                }
8096            }
8097        }
8098
8099        FileOutputStream fos = null;
8100        try {
8101            fos = mGrantFile.startWrite();
8102
8103            XmlSerializer out = new FastXmlSerializer();
8104            out.setOutput(fos, StandardCharsets.UTF_8.name());
8105            out.startDocument(null, true);
8106            out.startTag(null, TAG_URI_GRANTS);
8107            for (UriPermission.Snapshot perm : persist) {
8108                out.startTag(null, TAG_URI_GRANT);
8109                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8110                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8111                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8112                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8113                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8114                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8115                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8116                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8117                out.endTag(null, TAG_URI_GRANT);
8118            }
8119            out.endTag(null, TAG_URI_GRANTS);
8120            out.endDocument();
8121
8122            mGrantFile.finishWrite(fos);
8123        } catch (IOException e) {
8124            if (fos != null) {
8125                mGrantFile.failWrite(fos);
8126            }
8127        }
8128    }
8129
8130    private void readGrantedUriPermissionsLocked() {
8131        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8132
8133        final long now = System.currentTimeMillis();
8134
8135        FileInputStream fis = null;
8136        try {
8137            fis = mGrantFile.openRead();
8138            final XmlPullParser in = Xml.newPullParser();
8139            in.setInput(fis, StandardCharsets.UTF_8.name());
8140
8141            int type;
8142            while ((type = in.next()) != END_DOCUMENT) {
8143                final String tag = in.getName();
8144                if (type == START_TAG) {
8145                    if (TAG_URI_GRANT.equals(tag)) {
8146                        final int sourceUserId;
8147                        final int targetUserId;
8148                        final int userHandle = readIntAttribute(in,
8149                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8150                        if (userHandle != UserHandle.USER_NULL) {
8151                            // For backwards compatibility.
8152                            sourceUserId = userHandle;
8153                            targetUserId = userHandle;
8154                        } else {
8155                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8156                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8157                        }
8158                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8159                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8160                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8161                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8162                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8163                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8164
8165                        // Sanity check that provider still belongs to source package
8166                        final ProviderInfo pi = getProviderInfoLocked(
8167                                uri.getAuthority(), sourceUserId);
8168                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8169                            int targetUid = -1;
8170                            try {
8171                                targetUid = AppGlobals.getPackageManager()
8172                                        .getPackageUid(targetPkg, targetUserId);
8173                            } catch (RemoteException e) {
8174                            }
8175                            if (targetUid != -1) {
8176                                final UriPermission perm = findOrCreateUriPermissionLocked(
8177                                        sourcePkg, targetPkg, targetUid,
8178                                        new GrantUri(sourceUserId, uri, prefix));
8179                                perm.initPersistedModes(modeFlags, createdTime);
8180                            }
8181                        } else {
8182                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8183                                    + " but instead found " + pi);
8184                        }
8185                    }
8186                }
8187            }
8188        } catch (FileNotFoundException e) {
8189            // Missing grants is okay
8190        } catch (IOException e) {
8191            Slog.wtf(TAG, "Failed reading Uri grants", e);
8192        } catch (XmlPullParserException e) {
8193            Slog.wtf(TAG, "Failed reading Uri grants", e);
8194        } finally {
8195            IoUtils.closeQuietly(fis);
8196        }
8197    }
8198
8199    /**
8200     * @param uri This uri must NOT contain an embedded userId.
8201     * @param userId The userId in which the uri is to be resolved.
8202     */
8203    @Override
8204    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8205        enforceNotIsolatedCaller("takePersistableUriPermission");
8206
8207        Preconditions.checkFlagsArgument(modeFlags,
8208                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8209
8210        synchronized (this) {
8211            final int callingUid = Binder.getCallingUid();
8212            boolean persistChanged = false;
8213            GrantUri grantUri = new GrantUri(userId, uri, false);
8214
8215            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8216                    new GrantUri(userId, uri, false));
8217            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8218                    new GrantUri(userId, uri, true));
8219
8220            final boolean exactValid = (exactPerm != null)
8221                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8222            final boolean prefixValid = (prefixPerm != null)
8223                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8224
8225            if (!(exactValid || prefixValid)) {
8226                throw new SecurityException("No persistable permission grants found for UID "
8227                        + callingUid + " and Uri " + grantUri.toSafeString());
8228            }
8229
8230            if (exactValid) {
8231                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8232            }
8233            if (prefixValid) {
8234                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8235            }
8236
8237            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8238
8239            if (persistChanged) {
8240                schedulePersistUriGrants();
8241            }
8242        }
8243    }
8244
8245    /**
8246     * @param uri This uri must NOT contain an embedded userId.
8247     * @param userId The userId in which the uri is to be resolved.
8248     */
8249    @Override
8250    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8251        enforceNotIsolatedCaller("releasePersistableUriPermission");
8252
8253        Preconditions.checkFlagsArgument(modeFlags,
8254                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8255
8256        synchronized (this) {
8257            final int callingUid = Binder.getCallingUid();
8258            boolean persistChanged = false;
8259
8260            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8261                    new GrantUri(userId, uri, false));
8262            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8263                    new GrantUri(userId, uri, true));
8264            if (exactPerm == null && prefixPerm == null) {
8265                throw new SecurityException("No permission grants found for UID " + callingUid
8266                        + " and Uri " + uri.toSafeString());
8267            }
8268
8269            if (exactPerm != null) {
8270                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8271                removeUriPermissionIfNeededLocked(exactPerm);
8272            }
8273            if (prefixPerm != null) {
8274                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8275                removeUriPermissionIfNeededLocked(prefixPerm);
8276            }
8277
8278            if (persistChanged) {
8279                schedulePersistUriGrants();
8280            }
8281        }
8282    }
8283
8284    /**
8285     * Prune any older {@link UriPermission} for the given UID until outstanding
8286     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8287     *
8288     * @return if any mutations occured that require persisting.
8289     */
8290    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8291        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8292        if (perms == null) return false;
8293        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8294
8295        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8296        for (UriPermission perm : perms.values()) {
8297            if (perm.persistedModeFlags != 0) {
8298                persisted.add(perm);
8299            }
8300        }
8301
8302        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8303        if (trimCount <= 0) return false;
8304
8305        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8306        for (int i = 0; i < trimCount; i++) {
8307            final UriPermission perm = persisted.get(i);
8308
8309            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8310                    "Trimming grant created at " + perm.persistedCreateTime);
8311
8312            perm.releasePersistableModes(~0);
8313            removeUriPermissionIfNeededLocked(perm);
8314        }
8315
8316        return true;
8317    }
8318
8319    @Override
8320    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8321            String packageName, boolean incoming) {
8322        enforceNotIsolatedCaller("getPersistedUriPermissions");
8323        Preconditions.checkNotNull(packageName, "packageName");
8324
8325        final int callingUid = Binder.getCallingUid();
8326        final IPackageManager pm = AppGlobals.getPackageManager();
8327        try {
8328            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8329            if (packageUid != callingUid) {
8330                throw new SecurityException(
8331                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8332            }
8333        } catch (RemoteException e) {
8334            throw new SecurityException("Failed to verify package name ownership");
8335        }
8336
8337        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8338        synchronized (this) {
8339            if (incoming) {
8340                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8341                        callingUid);
8342                if (perms == null) {
8343                    Slog.w(TAG, "No permission grants found for " + packageName);
8344                } else {
8345                    for (UriPermission perm : perms.values()) {
8346                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8347                            result.add(perm.buildPersistedPublicApiObject());
8348                        }
8349                    }
8350                }
8351            } else {
8352                final int size = mGrantedUriPermissions.size();
8353                for (int i = 0; i < size; i++) {
8354                    final ArrayMap<GrantUri, UriPermission> perms =
8355                            mGrantedUriPermissions.valueAt(i);
8356                    for (UriPermission perm : perms.values()) {
8357                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8358                            result.add(perm.buildPersistedPublicApiObject());
8359                        }
8360                    }
8361                }
8362            }
8363        }
8364        return new ParceledListSlice<android.content.UriPermission>(result);
8365    }
8366
8367    @Override
8368    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8369        synchronized (this) {
8370            ProcessRecord app =
8371                who != null ? getRecordForAppLocked(who) : null;
8372            if (app == null) return;
8373
8374            Message msg = Message.obtain();
8375            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8376            msg.obj = app;
8377            msg.arg1 = waiting ? 1 : 0;
8378            mUiHandler.sendMessage(msg);
8379        }
8380    }
8381
8382    @Override
8383    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8384        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8385        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8386        outInfo.availMem = Process.getFreeMemory();
8387        outInfo.totalMem = Process.getTotalMemory();
8388        outInfo.threshold = homeAppMem;
8389        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8390        outInfo.hiddenAppThreshold = cachedAppMem;
8391        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8392                ProcessList.SERVICE_ADJ);
8393        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8394                ProcessList.VISIBLE_APP_ADJ);
8395        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8396                ProcessList.FOREGROUND_APP_ADJ);
8397    }
8398
8399    // =========================================================
8400    // TASK MANAGEMENT
8401    // =========================================================
8402
8403    @Override
8404    public List<IAppTask> getAppTasks(String callingPackage) {
8405        int callingUid = Binder.getCallingUid();
8406        long ident = Binder.clearCallingIdentity();
8407
8408        synchronized(this) {
8409            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8410            try {
8411                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8412
8413                final int N = mRecentTasks.size();
8414                for (int i = 0; i < N; i++) {
8415                    TaskRecord tr = mRecentTasks.get(i);
8416                    // Skip tasks that do not match the caller.  We don't need to verify
8417                    // callingPackage, because we are also limiting to callingUid and know
8418                    // that will limit to the correct security sandbox.
8419                    if (tr.effectiveUid != callingUid) {
8420                        continue;
8421                    }
8422                    Intent intent = tr.getBaseIntent();
8423                    if (intent == null ||
8424                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8425                        continue;
8426                    }
8427                    ActivityManager.RecentTaskInfo taskInfo =
8428                            createRecentTaskInfoFromTaskRecord(tr);
8429                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8430                    list.add(taskImpl);
8431                }
8432            } finally {
8433                Binder.restoreCallingIdentity(ident);
8434            }
8435            return list;
8436        }
8437    }
8438
8439    @Override
8440    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8441        final int callingUid = Binder.getCallingUid();
8442        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8443
8444        synchronized(this) {
8445            if (DEBUG_ALL) Slog.v(
8446                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8447
8448            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8449                    callingUid);
8450
8451            // TODO: Improve with MRU list from all ActivityStacks.
8452            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8453        }
8454
8455        return list;
8456    }
8457
8458    /**
8459     * Creates a new RecentTaskInfo from a TaskRecord.
8460     */
8461    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8462        // Update the task description to reflect any changes in the task stack
8463        tr.updateTaskDescription();
8464
8465        // Compose the recent task info
8466        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8467        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8468        rti.persistentId = tr.taskId;
8469        rti.baseIntent = new Intent(tr.getBaseIntent());
8470        rti.origActivity = tr.origActivity;
8471        rti.realActivity = tr.realActivity;
8472        rti.description = tr.lastDescription;
8473        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8474        rti.userId = tr.userId;
8475        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8476        rti.firstActiveTime = tr.firstActiveTime;
8477        rti.lastActiveTime = tr.lastActiveTime;
8478        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8479        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8480        rti.numActivities = 0;
8481        if (tr.mBounds != null) {
8482            rti.bounds = new Rect(tr.mBounds);
8483        }
8484
8485        ActivityRecord base = null;
8486        ActivityRecord top = null;
8487        ActivityRecord tmp;
8488
8489        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8490            tmp = tr.mActivities.get(i);
8491            if (tmp.finishing) {
8492                continue;
8493            }
8494            base = tmp;
8495            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8496                top = base;
8497            }
8498            rti.numActivities++;
8499        }
8500
8501        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8502        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8503
8504        return rti;
8505    }
8506
8507    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8508        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8509                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8510        if (!allowed) {
8511            if (checkPermission(android.Manifest.permission.GET_TASKS,
8512                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8513                // Temporary compatibility: some existing apps on the system image may
8514                // still be requesting the old permission and not switched to the new
8515                // one; if so, we'll still allow them full access.  This means we need
8516                // to see if they are holding the old permission and are a system app.
8517                try {
8518                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8519                        allowed = true;
8520                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8521                                + " is using old GET_TASKS but privileged; allowing");
8522                    }
8523                } catch (RemoteException e) {
8524                }
8525            }
8526        }
8527        if (!allowed) {
8528            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8529                    + " does not hold REAL_GET_TASKS; limiting output");
8530        }
8531        return allowed;
8532    }
8533
8534    @Override
8535    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8536        final int callingUid = Binder.getCallingUid();
8537        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8538                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8539
8540        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8541        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8542        synchronized (this) {
8543            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8544                    callingUid);
8545            final boolean detailed = checkCallingPermission(
8546                    android.Manifest.permission.GET_DETAILED_TASKS)
8547                    == PackageManager.PERMISSION_GRANTED;
8548
8549            final int recentsCount = mRecentTasks.size();
8550            ArrayList<ActivityManager.RecentTaskInfo> res =
8551                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8552
8553            final Set<Integer> includedUsers;
8554            if (includeProfiles) {
8555                includedUsers = mUserController.getProfileIds(userId);
8556            } else {
8557                includedUsers = new HashSet<>();
8558            }
8559            includedUsers.add(Integer.valueOf(userId));
8560
8561            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8562                TaskRecord tr = mRecentTasks.get(i);
8563                // Only add calling user or related users recent tasks
8564                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8565                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8566                    continue;
8567                }
8568
8569                // Return the entry if desired by the caller.  We always return
8570                // the first entry, because callers always expect this to be the
8571                // foreground app.  We may filter others if the caller has
8572                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8573                // we should exclude the entry.
8574
8575                if (i == 0
8576                        || withExcluded
8577                        || (tr.intent == null)
8578                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8579                                == 0)) {
8580                    if (!allowed) {
8581                        // If the caller doesn't have the GET_TASKS permission, then only
8582                        // allow them to see a small subset of tasks -- their own and home.
8583                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8584                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8585                            continue;
8586                        }
8587                    }
8588                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8589                        if (tr.stack != null && tr.stack.isHomeStack()) {
8590                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8591                                    "Skipping, home stack task: " + tr);
8592                            continue;
8593                        }
8594                    }
8595                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8596                        // Don't include auto remove tasks that are finished or finishing.
8597                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8598                                "Skipping, auto-remove without activity: " + tr);
8599                        continue;
8600                    }
8601                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8602                            && !tr.isAvailable) {
8603                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8604                                "Skipping, unavail real act: " + tr);
8605                        continue;
8606                    }
8607
8608                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8609                    if (!detailed) {
8610                        rti.baseIntent.replaceExtras((Bundle)null);
8611                    }
8612
8613                    res.add(rti);
8614                    maxNum--;
8615                }
8616            }
8617            return res;
8618        }
8619    }
8620
8621    @Override
8622    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8623        synchronized (this) {
8624            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8625                    "getTaskThumbnail()");
8626            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8627                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8628            if (tr != null) {
8629                return tr.getTaskThumbnailLocked();
8630            }
8631        }
8632        return null;
8633    }
8634
8635    @Override
8636    public int addAppTask(IBinder activityToken, Intent intent,
8637            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8638        final int callingUid = Binder.getCallingUid();
8639        final long callingIdent = Binder.clearCallingIdentity();
8640
8641        try {
8642            synchronized (this) {
8643                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8644                if (r == null) {
8645                    throw new IllegalArgumentException("Activity does not exist; token="
8646                            + activityToken);
8647                }
8648                ComponentName comp = intent.getComponent();
8649                if (comp == null) {
8650                    throw new IllegalArgumentException("Intent " + intent
8651                            + " must specify explicit component");
8652                }
8653                if (thumbnail.getWidth() != mThumbnailWidth
8654                        || thumbnail.getHeight() != mThumbnailHeight) {
8655                    throw new IllegalArgumentException("Bad thumbnail size: got "
8656                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8657                            + mThumbnailWidth + "x" + mThumbnailHeight);
8658                }
8659                if (intent.getSelector() != null) {
8660                    intent.setSelector(null);
8661                }
8662                if (intent.getSourceBounds() != null) {
8663                    intent.setSourceBounds(null);
8664                }
8665                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8666                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8667                        // The caller has added this as an auto-remove task...  that makes no
8668                        // sense, so turn off auto-remove.
8669                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8670                    }
8671                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8672                    // Must be a new task.
8673                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8674                }
8675                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8676                    mLastAddedTaskActivity = null;
8677                }
8678                ActivityInfo ainfo = mLastAddedTaskActivity;
8679                if (ainfo == null) {
8680                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8681                            comp, 0, UserHandle.getUserId(callingUid));
8682                    if (ainfo.applicationInfo.uid != callingUid) {
8683                        throw new SecurityException(
8684                                "Can't add task for another application: target uid="
8685                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8686                    }
8687                }
8688
8689                // Use the full screen as the context for the task thumbnail
8690                final Point displaySize = new Point();
8691                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8692                r.task.stack.getDisplaySize(displaySize);
8693                thumbnailInfo.taskWidth = displaySize.x;
8694                thumbnailInfo.taskHeight = displaySize.y;
8695                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8696
8697                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8698                        intent, description, thumbnailInfo);
8699
8700                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8701                if (trimIdx >= 0) {
8702                    // If this would have caused a trim, then we'll abort because that
8703                    // means it would be added at the end of the list but then just removed.
8704                    return INVALID_TASK_ID;
8705                }
8706
8707                final int N = mRecentTasks.size();
8708                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8709                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8710                    tr.removedFromRecents();
8711                }
8712
8713                task.inRecents = true;
8714                mRecentTasks.add(task);
8715                r.task.stack.addTask(task, false, false);
8716
8717                task.setLastThumbnailLocked(thumbnail);
8718                task.freeLastThumbnail();
8719
8720                return task.taskId;
8721            }
8722        } finally {
8723            Binder.restoreCallingIdentity(callingIdent);
8724        }
8725    }
8726
8727    @Override
8728    public Point getAppTaskThumbnailSize() {
8729        synchronized (this) {
8730            return new Point(mThumbnailWidth,  mThumbnailHeight);
8731        }
8732    }
8733
8734    @Override
8735    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8736        synchronized (this) {
8737            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8738            if (r != null) {
8739                r.setTaskDescription(td);
8740                r.task.updateTaskDescription();
8741            }
8742        }
8743    }
8744
8745    @Override
8746    public void setTaskResizeable(int taskId, boolean resizeable) {
8747        synchronized (this) {
8748            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8749                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8750            if (task == null) {
8751                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8752                return;
8753            }
8754            if (task.mResizeable != resizeable) {
8755                task.mResizeable = resizeable;
8756                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8757                mStackSupervisor.resumeTopActivitiesLocked();
8758            }
8759        }
8760    }
8761
8762    @Override
8763    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8764        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8765                "resizeTask()");
8766        long ident = Binder.clearCallingIdentity();
8767        try {
8768            synchronized (this) {
8769                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8770                if (task == null) {
8771                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8772                    return;
8773                }
8774                // Place the task in the right stack if it isn't there already based on
8775                // the requested bounds.
8776                // The stack transition logic is:
8777                // - a null bounds on a freeform task moves that task to fullscreen
8778                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8779                //   that task to freeform
8780                // - otherwise the task is not moved
8781                int stackId = task.stack.mStackId;
8782                if (!StackId.isTaskResizeAllowed(stackId)) {
8783                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8784                }
8785                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8786                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8787                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8788                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8789                }
8790                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8791                if (stackId != task.stack.mStackId) {
8792                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8793                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8794                    preserveWindow = false;
8795                }
8796
8797                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8798            }
8799        } finally {
8800            Binder.restoreCallingIdentity(ident);
8801        }
8802    }
8803
8804    @Override
8805    public Rect getTaskBounds(int taskId) {
8806        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8807                "getTaskBounds()");
8808        long ident = Binder.clearCallingIdentity();
8809        Rect rect = new Rect();
8810        try {
8811            synchronized (this) {
8812                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8813                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8814                if (task == null) {
8815                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8816                    return rect;
8817                }
8818                if (task.stack != null) {
8819                    // Return the bounds from window manager since it will be adjusted for various
8820                    // things like the presense of a docked stack for tasks that aren't resizeable.
8821                    mWindowManager.getTaskBounds(task.taskId, rect);
8822                } else {
8823                    // Task isn't in window manager yet since it isn't associated with a stack.
8824                    // Return the persist value from activity manager
8825                    if (task.mBounds != null) {
8826                        rect.set(task.mBounds);
8827                    } else if (task.mLastNonFullscreenBounds != null) {
8828                        rect.set(task.mLastNonFullscreenBounds);
8829                    }
8830                }
8831            }
8832        } finally {
8833            Binder.restoreCallingIdentity(ident);
8834        }
8835        return rect;
8836    }
8837
8838    @Override
8839    public Bitmap getTaskDescriptionIcon(String filename) {
8840        if (!FileUtils.isValidExtFilename(filename)
8841                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8842            throw new IllegalArgumentException("Bad filename: " + filename);
8843        }
8844        return mTaskPersister.getTaskDescriptionIcon(filename);
8845    }
8846
8847    @Override
8848    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8849            throws RemoteException {
8850        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8851                opts.getCustomInPlaceResId() == 0) {
8852            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8853                    "with valid animation");
8854        }
8855        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8856        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8857                opts.getCustomInPlaceResId());
8858        mWindowManager.executeAppTransition();
8859    }
8860
8861    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
8862            boolean removeFromRecents) {
8863        if (removeFromRecents) {
8864            mRecentTasks.remove(tr);
8865            tr.removedFromRecents();
8866        }
8867        ComponentName component = tr.getBaseIntent().getComponent();
8868        if (component == null) {
8869            Slog.w(TAG, "No component for base intent of task: " + tr);
8870            return;
8871        }
8872
8873        // Find any running services associated with this app and stop if needed.
8874        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8875
8876        if (!killProcess) {
8877            return;
8878        }
8879
8880        // Determine if the process(es) for this task should be killed.
8881        final String pkg = component.getPackageName();
8882        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8883        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8884        for (int i = 0; i < pmap.size(); i++) {
8885
8886            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8887            for (int j = 0; j < uids.size(); j++) {
8888                ProcessRecord proc = uids.valueAt(j);
8889                if (proc.userId != tr.userId) {
8890                    // Don't kill process for a different user.
8891                    continue;
8892                }
8893                if (proc == mHomeProcess) {
8894                    // Don't kill the home process along with tasks from the same package.
8895                    continue;
8896                }
8897                if (!proc.pkgList.containsKey(pkg)) {
8898                    // Don't kill process that is not associated with this task.
8899                    continue;
8900                }
8901
8902                for (int k = 0; k < proc.activities.size(); k++) {
8903                    TaskRecord otherTask = proc.activities.get(k).task;
8904                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8905                        // Don't kill process(es) that has an activity in a different task that is
8906                        // also in recents.
8907                        return;
8908                    }
8909                }
8910
8911                if (proc.foregroundServices) {
8912                    // Don't kill process(es) with foreground service.
8913                    return;
8914                }
8915
8916                // Add process to kill list.
8917                procsToKill.add(proc);
8918            }
8919        }
8920
8921        // Kill the running processes.
8922        for (int i = 0; i < procsToKill.size(); i++) {
8923            ProcessRecord pr = procsToKill.get(i);
8924            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8925                    && pr.curReceiver == null) {
8926                pr.kill("remove task", true);
8927            } else {
8928                // We delay killing processes that are not in the background or running a receiver.
8929                pr.waitingToKill = "remove task";
8930            }
8931        }
8932    }
8933
8934    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8935        // Remove all tasks with activities in the specified package from the list of recent tasks
8936        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8937            TaskRecord tr = mRecentTasks.get(i);
8938            if (tr.userId != userId) continue;
8939
8940            ComponentName cn = tr.intent.getComponent();
8941            if (cn != null && cn.getPackageName().equals(packageName)) {
8942                // If the package name matches, remove the task.
8943                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
8944            }
8945        }
8946    }
8947
8948    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8949            int userId) {
8950
8951        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8952            TaskRecord tr = mRecentTasks.get(i);
8953            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8954                continue;
8955            }
8956
8957            ComponentName cn = tr.intent.getComponent();
8958            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8959                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8960            if (sameComponent) {
8961                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
8962            }
8963        }
8964    }
8965
8966    /**
8967     * Removes the task with the specified task id.
8968     *
8969     * @param taskId Identifier of the task to be removed.
8970     * @param killProcess Kill any process associated with the task if possible.
8971     * @param removeFromRecents Whether to also remove the task from recents.
8972     * @return Returns true if the given task was found and removed.
8973     */
8974    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
8975            boolean removeFromRecents) {
8976        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8977                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8978        if (tr != null) {
8979            tr.removeTaskActivitiesLocked();
8980            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
8981            if (tr.isPersistable) {
8982                notifyTaskPersisterLocked(null, true);
8983            }
8984            return true;
8985        }
8986        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8987        return false;
8988    }
8989
8990    @Override
8991    public boolean removeTask(int taskId) {
8992        synchronized (this) {
8993            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8994                    "removeTask()");
8995            long ident = Binder.clearCallingIdentity();
8996            try {
8997                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
8998            } finally {
8999                Binder.restoreCallingIdentity(ident);
9000            }
9001        }
9002    }
9003
9004    /**
9005     * TODO: Add mController hook
9006     */
9007    @Override
9008    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9009        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9010
9011        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9012        synchronized(this) {
9013            moveTaskToFrontLocked(taskId, flags, bOptions);
9014        }
9015    }
9016
9017    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9018        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9019
9020        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9021                Binder.getCallingUid(), -1, -1, "Task to front")) {
9022            ActivityOptions.abort(options);
9023            return;
9024        }
9025        final long origId = Binder.clearCallingIdentity();
9026        try {
9027            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9028            if (task == null) {
9029                Slog.d(TAG, "Could not find task for id: "+ taskId);
9030                return;
9031            }
9032            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9033                mStackSupervisor.showLockTaskToast();
9034                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9035                return;
9036            }
9037            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9038            if (prev != null && prev.isRecentsActivity()) {
9039                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9040            }
9041            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9042        } finally {
9043            Binder.restoreCallingIdentity(origId);
9044        }
9045        ActivityOptions.abort(options);
9046    }
9047
9048    /**
9049     * Moves an activity, and all of the other activities within the same task, to the bottom
9050     * of the history stack.  The activity's order within the task is unchanged.
9051     *
9052     * @param token A reference to the activity we wish to move
9053     * @param nonRoot If false then this only works if the activity is the root
9054     *                of a task; if true it will work for any activity in a task.
9055     * @return Returns true if the move completed, false if not.
9056     */
9057    @Override
9058    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9059        enforceNotIsolatedCaller("moveActivityTaskToBack");
9060        synchronized(this) {
9061            final long origId = Binder.clearCallingIdentity();
9062            try {
9063                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9064                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9065                if (task != null) {
9066                    if (mStackSupervisor.isLockedTask(task)) {
9067                        mStackSupervisor.showLockTaskToast();
9068                        return false;
9069                    }
9070                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9071                }
9072            } finally {
9073                Binder.restoreCallingIdentity(origId);
9074            }
9075        }
9076        return false;
9077    }
9078
9079    @Override
9080    public void moveTaskBackwards(int task) {
9081        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9082                "moveTaskBackwards()");
9083
9084        synchronized(this) {
9085            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9086                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9087                return;
9088            }
9089            final long origId = Binder.clearCallingIdentity();
9090            moveTaskBackwardsLocked(task);
9091            Binder.restoreCallingIdentity(origId);
9092        }
9093    }
9094
9095    private final void moveTaskBackwardsLocked(int task) {
9096        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9097    }
9098
9099    @Override
9100    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9101            IActivityContainerCallback callback) throws RemoteException {
9102        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9103                "createActivityContainer()");
9104        synchronized (this) {
9105            if (parentActivityToken == null) {
9106                throw new IllegalArgumentException("parent token must not be null");
9107            }
9108            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9109            if (r == null) {
9110                return null;
9111            }
9112            if (callback == null) {
9113                throw new IllegalArgumentException("callback must not be null");
9114            }
9115            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9116        }
9117    }
9118
9119    @Override
9120    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9121        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9122                "deleteActivityContainer()");
9123        synchronized (this) {
9124            mStackSupervisor.deleteActivityContainer(container);
9125        }
9126    }
9127
9128    @Override
9129    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9130        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9131                "createStackOnDisplay()");
9132        synchronized (this) {
9133            final int stackId = mStackSupervisor.getNextStackId();
9134            final ActivityStack stack =
9135                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9136            if (stack == null) {
9137                return null;
9138            }
9139            return stack.mActivityContainer;
9140        }
9141    }
9142
9143    @Override
9144    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9145        synchronized (this) {
9146            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9147            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9148                return stack.mActivityContainer.getDisplayId();
9149            }
9150            return Display.DEFAULT_DISPLAY;
9151        }
9152    }
9153
9154    @Override
9155    public int getActivityStackId(IBinder token) throws RemoteException {
9156        synchronized (this) {
9157            ActivityStack stack = ActivityRecord.getStackLocked(token);
9158            if (stack == null) {
9159                return INVALID_STACK_ID;
9160            }
9161            return stack.mStackId;
9162        }
9163    }
9164
9165    @Override
9166    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9167        if (stackId == HOME_STACK_ID) {
9168            throw new IllegalArgumentException(
9169                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9170        }
9171        synchronized (this) {
9172            long ident = Binder.clearCallingIdentity();
9173            try {
9174                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9175                if (r == null) {
9176                    throw new IllegalArgumentException(
9177                            "moveActivityToStack: No activity record matching token=" + token);
9178                }
9179                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9180                        + " to stackId=" + stackId);
9181                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9182                        "moveActivityToStack");
9183            } finally {
9184                Binder.restoreCallingIdentity(ident);
9185            }
9186        }
9187    }
9188
9189    @Override
9190    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9191        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9192                "moveTaskToStack()");
9193        if (stackId == HOME_STACK_ID) {
9194            throw new IllegalArgumentException(
9195                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9196        }
9197        synchronized (this) {
9198            long ident = Binder.clearCallingIdentity();
9199            try {
9200                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9201                        + " to stackId=" + stackId + " toTop=" + toTop);
9202                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9203                        "moveTaskToStack");
9204            } finally {
9205                Binder.restoreCallingIdentity(ident);
9206            }
9207        }
9208    }
9209
9210    /**
9211     * Moves the input task to the docked stack.
9212     *
9213     * @param taskId Id of task to move.
9214     * @param createMode The mode the docked stack should be created in if it doesn't exist
9215     *                   already. See
9216     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9217     *                   and
9218     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9219     * @param toTop If the task and stack should be moved to the top.
9220     */
9221    @Override
9222    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) {
9223        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9224                "moveTaskToDockedStack()");
9225        synchronized (this) {
9226            long ident = Binder.clearCallingIdentity();
9227            try {
9228                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9229                        + " to createMode=" + createMode + " toTop=" + toTop);
9230                mWindowManager.setDockedStackCreateMode(createMode);
9231                mStackSupervisor.moveTaskToStackLocked(
9232                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack");
9233            } finally {
9234                Binder.restoreCallingIdentity(ident);
9235            }
9236        }
9237    }
9238
9239    /**
9240     * Moves the top activity in the input stackId to the pinned stack.
9241     *
9242     * @param stackId Id of stack to move the top activity to pinned stack.
9243     * @param bounds Bounds to use for pinned stack.
9244     *
9245     * @return True if the top activity of the input stack was successfully moved to the pinned
9246     *          stack.
9247     */
9248    @Override
9249    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9250        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9251                "moveTopActivityToPinnedStack()");
9252        synchronized (this) {
9253            long ident = Binder.clearCallingIdentity();
9254            try {
9255                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9256            } finally {
9257                Binder.restoreCallingIdentity(ident);
9258            }
9259        }
9260    }
9261
9262    @Override
9263    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9264        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9265                "resizeStack()");
9266        long ident = Binder.clearCallingIdentity();
9267        try {
9268            synchronized (this) {
9269                mStackSupervisor.resizeStackLocked(
9270                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9271            }
9272        } finally {
9273            Binder.restoreCallingIdentity(ident);
9274        }
9275    }
9276
9277    @Override
9278    public void positionTaskInStack(int taskId, int stackId, int position) {
9279        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9280                "positionTaskInStack()");
9281        if (stackId == HOME_STACK_ID) {
9282            throw new IllegalArgumentException(
9283                    "positionTaskInStack: Attempt to change the position of task "
9284                    + taskId + " in/to home stack");
9285        }
9286        synchronized (this) {
9287            long ident = Binder.clearCallingIdentity();
9288            try {
9289                if (DEBUG_STACK) Slog.d(TAG_STACK,
9290                        "positionTaskInStack: positioning task=" + taskId
9291                        + " in stackId=" + stackId + " at position=" + position);
9292                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9293            } finally {
9294                Binder.restoreCallingIdentity(ident);
9295            }
9296        }
9297    }
9298
9299    @Override
9300    public List<StackInfo> getAllStackInfos() {
9301        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9302                "getAllStackInfos()");
9303        long ident = Binder.clearCallingIdentity();
9304        try {
9305            synchronized (this) {
9306                return mStackSupervisor.getAllStackInfosLocked();
9307            }
9308        } finally {
9309            Binder.restoreCallingIdentity(ident);
9310        }
9311    }
9312
9313    @Override
9314    public StackInfo getStackInfo(int stackId) {
9315        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9316                "getStackInfo()");
9317        long ident = Binder.clearCallingIdentity();
9318        try {
9319            synchronized (this) {
9320                return mStackSupervisor.getStackInfoLocked(stackId);
9321            }
9322        } finally {
9323            Binder.restoreCallingIdentity(ident);
9324        }
9325    }
9326
9327    @Override
9328    public boolean isInHomeStack(int taskId) {
9329        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9330                "getStackInfo()");
9331        long ident = Binder.clearCallingIdentity();
9332        try {
9333            synchronized (this) {
9334                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9335                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9336                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9337            }
9338        } finally {
9339            Binder.restoreCallingIdentity(ident);
9340        }
9341    }
9342
9343    @Override
9344    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9345        synchronized(this) {
9346            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9347        }
9348    }
9349
9350    @Override
9351    public void updateDeviceOwner(String packageName) {
9352        final int callingUid = Binder.getCallingUid();
9353        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9354            throw new SecurityException("updateDeviceOwner called from non-system process");
9355        }
9356        synchronized (this) {
9357            mDeviceOwnerName = packageName;
9358        }
9359    }
9360
9361    @Override
9362    public void updateLockTaskPackages(int userId, String[] packages) {
9363        final int callingUid = Binder.getCallingUid();
9364        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9365            throw new SecurityException("updateLockTaskPackage called from non-system process");
9366        }
9367        synchronized (this) {
9368            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9369                    Arrays.toString(packages));
9370            mLockTaskPackages.put(userId, packages);
9371            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9372        }
9373    }
9374
9375
9376    void startLockTaskModeLocked(TaskRecord task) {
9377        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9378        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9379            return;
9380        }
9381
9382        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9383        // is initiated by system after the pinning request was shown and locked mode is initiated
9384        // by an authorized app directly
9385        final int callingUid = Binder.getCallingUid();
9386        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9387        long ident = Binder.clearCallingIdentity();
9388        try {
9389            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9390            if (!isSystemInitiated) {
9391                task.mLockTaskUid = callingUid;
9392                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9393                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9394                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9395                    StatusBarManagerInternal statusBarManager =
9396                            LocalServices.getService(StatusBarManagerInternal.class);
9397                    if (statusBarManager != null) {
9398                        statusBarManager.showScreenPinningRequest();
9399                    }
9400                    return;
9401                }
9402
9403                if (stack == null || task != stack.topTask()) {
9404                    throw new IllegalArgumentException("Invalid task, not in foreground");
9405                }
9406            }
9407            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9408                    "Locking fully");
9409            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9410                    ActivityManager.LOCK_TASK_MODE_PINNED :
9411                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9412                    "startLockTask", true);
9413        } finally {
9414            Binder.restoreCallingIdentity(ident);
9415        }
9416    }
9417
9418    @Override
9419    public void startLockTaskMode(int taskId) {
9420        synchronized (this) {
9421            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9422            if (task != null) {
9423                startLockTaskModeLocked(task);
9424            }
9425        }
9426    }
9427
9428    @Override
9429    public void startLockTaskMode(IBinder token) {
9430        synchronized (this) {
9431            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9432            if (r == null) {
9433                return;
9434            }
9435            final TaskRecord task = r.task;
9436            if (task != null) {
9437                startLockTaskModeLocked(task);
9438            }
9439        }
9440    }
9441
9442    @Override
9443    public void startLockTaskModeOnCurrent() throws RemoteException {
9444        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9445                "startLockTaskModeOnCurrent");
9446        long ident = Binder.clearCallingIdentity();
9447        try {
9448            synchronized (this) {
9449                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9450                if (r != null) {
9451                    startLockTaskModeLocked(r.task);
9452                }
9453            }
9454        } finally {
9455            Binder.restoreCallingIdentity(ident);
9456        }
9457    }
9458
9459    @Override
9460    public void stopLockTaskMode() {
9461        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9462        if (lockTask == null) {
9463            // Our work here is done.
9464            return;
9465        }
9466
9467        final int callingUid = Binder.getCallingUid();
9468        final int lockTaskUid = lockTask.mLockTaskUid;
9469        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9470        // It is possible lockTaskMode was started by the system process because
9471        // android:lockTaskMode is set to a locking value in the application manifest instead of
9472        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9473        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9474        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9475                callingUid != lockTaskUid
9476                && (lockTaskUid != 0
9477                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9478            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9479                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9480        }
9481
9482        long ident = Binder.clearCallingIdentity();
9483        try {
9484            Log.d(TAG, "stopLockTaskMode");
9485            // Stop lock task
9486            synchronized (this) {
9487                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9488                        "stopLockTask", true);
9489            }
9490        } finally {
9491            Binder.restoreCallingIdentity(ident);
9492        }
9493    }
9494
9495    @Override
9496    public void stopLockTaskModeOnCurrent() throws RemoteException {
9497        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9498                "stopLockTaskModeOnCurrent");
9499        long ident = Binder.clearCallingIdentity();
9500        try {
9501            stopLockTaskMode();
9502        } finally {
9503            Binder.restoreCallingIdentity(ident);
9504        }
9505    }
9506
9507    @Override
9508    public boolean isInLockTaskMode() {
9509        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9510    }
9511
9512    @Override
9513    public int getLockTaskModeState() {
9514        synchronized (this) {
9515            return mStackSupervisor.getLockTaskModeState();
9516        }
9517    }
9518
9519    @Override
9520    public void showLockTaskEscapeMessage(IBinder token) {
9521        synchronized (this) {
9522            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9523            if (r == null) {
9524                return;
9525            }
9526            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9527        }
9528    }
9529
9530    // =========================================================
9531    // CONTENT PROVIDERS
9532    // =========================================================
9533
9534    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9535        List<ProviderInfo> providers = null;
9536        try {
9537            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9538                queryContentProviders(app.processName, app.uid,
9539                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9540            providers = slice != null ? slice.getList() : null;
9541        } catch (RemoteException ex) {
9542        }
9543        if (DEBUG_MU) Slog.v(TAG_MU,
9544                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9545        int userId = app.userId;
9546        if (providers != null) {
9547            int N = providers.size();
9548            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9549            for (int i=0; i<N; i++) {
9550                ProviderInfo cpi =
9551                    (ProviderInfo)providers.get(i);
9552                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9553                        cpi.name, cpi.flags);
9554                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9555                    // This is a singleton provider, but a user besides the
9556                    // default user is asking to initialize a process it runs
9557                    // in...  well, no, it doesn't actually run in this process,
9558                    // it runs in the process of the default user.  Get rid of it.
9559                    providers.remove(i);
9560                    N--;
9561                    i--;
9562                    continue;
9563                }
9564
9565                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9566                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9567                if (cpr == null) {
9568                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9569                    mProviderMap.putProviderByClass(comp, cpr);
9570                }
9571                if (DEBUG_MU) Slog.v(TAG_MU,
9572                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9573                app.pubProviders.put(cpi.name, cpr);
9574                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9575                    // Don't add this if it is a platform component that is marked
9576                    // to run in multiple processes, because this is actually
9577                    // part of the framework so doesn't make sense to track as a
9578                    // separate apk in the process.
9579                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9580                            mProcessStats);
9581                }
9582                notifyPackageUse(cpi.applicationInfo.packageName);
9583            }
9584        }
9585        return providers;
9586    }
9587
9588    /**
9589     * Check if {@link ProcessRecord} has a possible chance at accessing the
9590     * given {@link ProviderInfo}. Final permission checking is always done
9591     * in {@link ContentProvider}.
9592     */
9593    private final String checkContentProviderPermissionLocked(
9594            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9595        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9596        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9597        boolean checkedGrants = false;
9598        if (checkUser) {
9599            // Looking for cross-user grants before enforcing the typical cross-users permissions
9600            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9601            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9602                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9603                    return null;
9604                }
9605                checkedGrants = true;
9606            }
9607            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9608                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9609            if (userId != tmpTargetUserId) {
9610                // When we actually went to determine the final targer user ID, this ended
9611                // up different than our initial check for the authority.  This is because
9612                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9613                // SELF.  So we need to re-check the grants again.
9614                checkedGrants = false;
9615            }
9616        }
9617        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9618                cpi.applicationInfo.uid, cpi.exported)
9619                == PackageManager.PERMISSION_GRANTED) {
9620            return null;
9621        }
9622        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9623                cpi.applicationInfo.uid, cpi.exported)
9624                == PackageManager.PERMISSION_GRANTED) {
9625            return null;
9626        }
9627
9628        PathPermission[] pps = cpi.pathPermissions;
9629        if (pps != null) {
9630            int i = pps.length;
9631            while (i > 0) {
9632                i--;
9633                PathPermission pp = pps[i];
9634                String pprperm = pp.getReadPermission();
9635                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9636                        cpi.applicationInfo.uid, cpi.exported)
9637                        == PackageManager.PERMISSION_GRANTED) {
9638                    return null;
9639                }
9640                String ppwperm = pp.getWritePermission();
9641                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9642                        cpi.applicationInfo.uid, cpi.exported)
9643                        == PackageManager.PERMISSION_GRANTED) {
9644                    return null;
9645                }
9646            }
9647        }
9648        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9649            return null;
9650        }
9651
9652        String msg;
9653        if (!cpi.exported) {
9654            msg = "Permission Denial: opening provider " + cpi.name
9655                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9656                    + ", uid=" + callingUid + ") that is not exported from uid "
9657                    + cpi.applicationInfo.uid;
9658        } else {
9659            msg = "Permission Denial: opening provider " + cpi.name
9660                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9661                    + ", uid=" + callingUid + ") requires "
9662                    + cpi.readPermission + " or " + cpi.writePermission;
9663        }
9664        Slog.w(TAG, msg);
9665        return msg;
9666    }
9667
9668    /**
9669     * Returns if the ContentProvider has granted a uri to callingUid
9670     */
9671    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9672        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9673        if (perms != null) {
9674            for (int i=perms.size()-1; i>=0; i--) {
9675                GrantUri grantUri = perms.keyAt(i);
9676                if (grantUri.sourceUserId == userId || !checkUser) {
9677                    if (matchesProvider(grantUri.uri, cpi)) {
9678                        return true;
9679                    }
9680                }
9681            }
9682        }
9683        return false;
9684    }
9685
9686    /**
9687     * Returns true if the uri authority is one of the authorities specified in the provider.
9688     */
9689    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9690        String uriAuth = uri.getAuthority();
9691        String cpiAuth = cpi.authority;
9692        if (cpiAuth.indexOf(';') == -1) {
9693            return cpiAuth.equals(uriAuth);
9694        }
9695        String[] cpiAuths = cpiAuth.split(";");
9696        int length = cpiAuths.length;
9697        for (int i = 0; i < length; i++) {
9698            if (cpiAuths[i].equals(uriAuth)) return true;
9699        }
9700        return false;
9701    }
9702
9703    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9704            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9705        if (r != null) {
9706            for (int i=0; i<r.conProviders.size(); i++) {
9707                ContentProviderConnection conn = r.conProviders.get(i);
9708                if (conn.provider == cpr) {
9709                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9710                            "Adding provider requested by "
9711                            + r.processName + " from process "
9712                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9713                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9714                    if (stable) {
9715                        conn.stableCount++;
9716                        conn.numStableIncs++;
9717                    } else {
9718                        conn.unstableCount++;
9719                        conn.numUnstableIncs++;
9720                    }
9721                    return conn;
9722                }
9723            }
9724            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9725            if (stable) {
9726                conn.stableCount = 1;
9727                conn.numStableIncs = 1;
9728            } else {
9729                conn.unstableCount = 1;
9730                conn.numUnstableIncs = 1;
9731            }
9732            cpr.connections.add(conn);
9733            r.conProviders.add(conn);
9734            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9735            return conn;
9736        }
9737        cpr.addExternalProcessHandleLocked(externalProcessToken);
9738        return null;
9739    }
9740
9741    boolean decProviderCountLocked(ContentProviderConnection conn,
9742            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9743        if (conn != null) {
9744            cpr = conn.provider;
9745            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9746                    "Removing provider requested by "
9747                    + conn.client.processName + " from process "
9748                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9749                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9750            if (stable) {
9751                conn.stableCount--;
9752            } else {
9753                conn.unstableCount--;
9754            }
9755            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9756                cpr.connections.remove(conn);
9757                conn.client.conProviders.remove(conn);
9758                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9759                    // The client is more important than last activity -- note the time this
9760                    // is happening, so we keep the old provider process around a bit as last
9761                    // activity to avoid thrashing it.
9762                    if (cpr.proc != null) {
9763                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9764                    }
9765                }
9766                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9767                return true;
9768            }
9769            return false;
9770        }
9771        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9772        return false;
9773    }
9774
9775    private void checkTime(long startTime, String where) {
9776        long now = SystemClock.elapsedRealtime();
9777        if ((now-startTime) > 1000) {
9778            // If we are taking more than a second, log about it.
9779            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9780        }
9781    }
9782
9783    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9784            String name, IBinder token, boolean stable, int userId) {
9785        ContentProviderRecord cpr;
9786        ContentProviderConnection conn = null;
9787        ProviderInfo cpi = null;
9788
9789        synchronized(this) {
9790            long startTime = SystemClock.elapsedRealtime();
9791
9792            ProcessRecord r = null;
9793            if (caller != null) {
9794                r = getRecordForAppLocked(caller);
9795                if (r == null) {
9796                    throw new SecurityException(
9797                            "Unable to find app for caller " + caller
9798                          + " (pid=" + Binder.getCallingPid()
9799                          + ") when getting content provider " + name);
9800                }
9801            }
9802
9803            boolean checkCrossUser = true;
9804
9805            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9806
9807            // First check if this content provider has been published...
9808            cpr = mProviderMap.getProviderByName(name, userId);
9809            // If that didn't work, check if it exists for user 0 and then
9810            // verify that it's a singleton provider before using it.
9811            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9812                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9813                if (cpr != null) {
9814                    cpi = cpr.info;
9815                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9816                            cpi.name, cpi.flags)
9817                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9818                        userId = UserHandle.USER_SYSTEM;
9819                        checkCrossUser = false;
9820                    } else {
9821                        cpr = null;
9822                        cpi = null;
9823                    }
9824                }
9825            }
9826
9827            boolean providerRunning = cpr != null;
9828            if (providerRunning) {
9829                cpi = cpr.info;
9830                String msg;
9831                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9832                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9833                        != null) {
9834                    throw new SecurityException(msg);
9835                }
9836                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9837
9838                if (r != null && cpr.canRunHere(r)) {
9839                    // This provider has been published or is in the process
9840                    // of being published...  but it is also allowed to run
9841                    // in the caller's process, so don't make a connection
9842                    // and just let the caller instantiate its own instance.
9843                    ContentProviderHolder holder = cpr.newHolder(null);
9844                    // don't give caller the provider object, it needs
9845                    // to make its own.
9846                    holder.provider = null;
9847                    return holder;
9848                }
9849
9850                final long origId = Binder.clearCallingIdentity();
9851
9852                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9853
9854                // In this case the provider instance already exists, so we can
9855                // return it right away.
9856                conn = incProviderCountLocked(r, cpr, token, stable);
9857                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9858                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9859                        // If this is a perceptible app accessing the provider,
9860                        // make sure to count it as being accessed and thus
9861                        // back up on the LRU list.  This is good because
9862                        // content providers are often expensive to start.
9863                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9864                        updateLruProcessLocked(cpr.proc, false, null);
9865                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9866                    }
9867                }
9868
9869                if (cpr.proc != null) {
9870                    if (false) {
9871                        if (cpr.name.flattenToShortString().equals(
9872                                "com.android.providers.calendar/.CalendarProvider2")) {
9873                            Slog.v(TAG, "****************** KILLING "
9874                                + cpr.name.flattenToShortString());
9875                            Process.killProcess(cpr.proc.pid);
9876                        }
9877                    }
9878                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9879                    boolean success = updateOomAdjLocked(cpr.proc);
9880                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9881                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9882                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9883                    // NOTE: there is still a race here where a signal could be
9884                    // pending on the process even though we managed to update its
9885                    // adj level.  Not sure what to do about this, but at least
9886                    // the race is now smaller.
9887                    if (!success) {
9888                        // Uh oh...  it looks like the provider's process
9889                        // has been killed on us.  We need to wait for a new
9890                        // process to be started, and make sure its death
9891                        // doesn't kill our process.
9892                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9893                                + " is crashing; detaching " + r);
9894                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9895                        checkTime(startTime, "getContentProviderImpl: before appDied");
9896                        appDiedLocked(cpr.proc);
9897                        checkTime(startTime, "getContentProviderImpl: after appDied");
9898                        if (!lastRef) {
9899                            // This wasn't the last ref our process had on
9900                            // the provider...  we have now been killed, bail.
9901                            return null;
9902                        }
9903                        providerRunning = false;
9904                        conn = null;
9905                    }
9906                }
9907
9908                Binder.restoreCallingIdentity(origId);
9909            }
9910
9911            if (!providerRunning) {
9912                try {
9913                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9914                    cpi = AppGlobals.getPackageManager().
9915                        resolveContentProvider(name,
9916                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9917                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9918                } catch (RemoteException ex) {
9919                }
9920                if (cpi == null) {
9921                    return null;
9922                }
9923                // If the provider is a singleton AND
9924                // (it's a call within the same user || the provider is a
9925                // privileged app)
9926                // Then allow connecting to the singleton provider
9927                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9928                        cpi.name, cpi.flags)
9929                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9930                if (singleton) {
9931                    userId = UserHandle.USER_SYSTEM;
9932                }
9933                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9934                checkTime(startTime, "getContentProviderImpl: got app info for user");
9935
9936                String msg;
9937                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9938                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9939                        != null) {
9940                    throw new SecurityException(msg);
9941                }
9942                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9943
9944                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9945                        && !cpi.processName.equals("system")) {
9946                    // If this content provider does not run in the system
9947                    // process, and the system is not yet ready to run other
9948                    // processes, then fail fast instead of hanging.
9949                    throw new IllegalArgumentException(
9950                            "Attempt to launch content provider before system ready");
9951                }
9952
9953                // Make sure that the user who owns this provider is running.  If not,
9954                // we don't want to allow it to run.
9955                if (!mUserController.isUserRunningLocked(userId, 0)) {
9956                    Slog.w(TAG, "Unable to launch app "
9957                            + cpi.applicationInfo.packageName + "/"
9958                            + cpi.applicationInfo.uid + " for provider "
9959                            + name + ": user " + userId + " is stopped");
9960                    return null;
9961                }
9962
9963                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9964                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9965                cpr = mProviderMap.getProviderByClass(comp, userId);
9966                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9967                final boolean firstClass = cpr == null;
9968                if (firstClass) {
9969                    final long ident = Binder.clearCallingIdentity();
9970                    try {
9971                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9972                        ApplicationInfo ai =
9973                            AppGlobals.getPackageManager().
9974                                getApplicationInfo(
9975                                        cpi.applicationInfo.packageName,
9976                                        STOCK_PM_FLAGS, userId);
9977                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9978                        if (ai == null) {
9979                            Slog.w(TAG, "No package info for content provider "
9980                                    + cpi.name);
9981                            return null;
9982                        }
9983                        ai = getAppInfoForUser(ai, userId);
9984                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9985                    } catch (RemoteException ex) {
9986                        // pm is in same process, this will never happen.
9987                    } finally {
9988                        Binder.restoreCallingIdentity(ident);
9989                    }
9990                }
9991
9992                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9993
9994                if (r != null && cpr.canRunHere(r)) {
9995                    // If this is a multiprocess provider, then just return its
9996                    // info and allow the caller to instantiate it.  Only do
9997                    // this if the provider is the same user as the caller's
9998                    // process, or can run as root (so can be in any process).
9999                    return cpr.newHolder(null);
10000                }
10001
10002                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10003                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10004                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10005
10006                // This is single process, and our app is now connecting to it.
10007                // See if we are already in the process of launching this
10008                // provider.
10009                final int N = mLaunchingProviders.size();
10010                int i;
10011                for (i = 0; i < N; i++) {
10012                    if (mLaunchingProviders.get(i) == cpr) {
10013                        break;
10014                    }
10015                }
10016
10017                // If the provider is not already being launched, then get it
10018                // started.
10019                if (i >= N) {
10020                    final long origId = Binder.clearCallingIdentity();
10021
10022                    try {
10023                        // Content provider is now in use, its package can't be stopped.
10024                        try {
10025                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10026                            AppGlobals.getPackageManager().setPackageStoppedState(
10027                                    cpr.appInfo.packageName, false, userId);
10028                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10029                        } catch (RemoteException e) {
10030                        } catch (IllegalArgumentException e) {
10031                            Slog.w(TAG, "Failed trying to unstop package "
10032                                    + cpr.appInfo.packageName + ": " + e);
10033                        }
10034
10035                        // Use existing process if already started
10036                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10037                        ProcessRecord proc = getProcessRecordLocked(
10038                                cpi.processName, cpr.appInfo.uid, false);
10039                        if (proc != null && proc.thread != null) {
10040                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10041                                    "Installing in existing process " + proc);
10042                            if (!proc.pubProviders.containsKey(cpi.name)) {
10043                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10044                                proc.pubProviders.put(cpi.name, cpr);
10045                                try {
10046                                    proc.thread.scheduleInstallProvider(cpi);
10047                                } catch (RemoteException e) {
10048                                }
10049                            }
10050                        } else {
10051                            checkTime(startTime, "getContentProviderImpl: before start process");
10052                            proc = startProcessLocked(cpi.processName,
10053                                    cpr.appInfo, false, 0, "content provider",
10054                                    new ComponentName(cpi.applicationInfo.packageName,
10055                                            cpi.name), false, false, false);
10056                            checkTime(startTime, "getContentProviderImpl: after start process");
10057                            if (proc == null) {
10058                                Slog.w(TAG, "Unable to launch app "
10059                                        + cpi.applicationInfo.packageName + "/"
10060                                        + cpi.applicationInfo.uid + " for provider "
10061                                        + name + ": process is bad");
10062                                return null;
10063                            }
10064                        }
10065                        cpr.launchingApp = proc;
10066                        mLaunchingProviders.add(cpr);
10067                    } finally {
10068                        Binder.restoreCallingIdentity(origId);
10069                    }
10070                }
10071
10072                checkTime(startTime, "getContentProviderImpl: updating data structures");
10073
10074                // Make sure the provider is published (the same provider class
10075                // may be published under multiple names).
10076                if (firstClass) {
10077                    mProviderMap.putProviderByClass(comp, cpr);
10078                }
10079
10080                mProviderMap.putProviderByName(name, cpr);
10081                conn = incProviderCountLocked(r, cpr, token, stable);
10082                if (conn != null) {
10083                    conn.waiting = true;
10084                }
10085            }
10086            checkTime(startTime, "getContentProviderImpl: done!");
10087        }
10088
10089        // Wait for the provider to be published...
10090        synchronized (cpr) {
10091            while (cpr.provider == null) {
10092                if (cpr.launchingApp == null) {
10093                    Slog.w(TAG, "Unable to launch app "
10094                            + cpi.applicationInfo.packageName + "/"
10095                            + cpi.applicationInfo.uid + " for provider "
10096                            + name + ": launching app became null");
10097                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10098                            UserHandle.getUserId(cpi.applicationInfo.uid),
10099                            cpi.applicationInfo.packageName,
10100                            cpi.applicationInfo.uid, name);
10101                    return null;
10102                }
10103                try {
10104                    if (DEBUG_MU) Slog.v(TAG_MU,
10105                            "Waiting to start provider " + cpr
10106                            + " launchingApp=" + cpr.launchingApp);
10107                    if (conn != null) {
10108                        conn.waiting = true;
10109                    }
10110                    cpr.wait();
10111                } catch (InterruptedException ex) {
10112                } finally {
10113                    if (conn != null) {
10114                        conn.waiting = false;
10115                    }
10116                }
10117            }
10118        }
10119        return cpr != null ? cpr.newHolder(conn) : null;
10120    }
10121
10122    @Override
10123    public final ContentProviderHolder getContentProvider(
10124            IApplicationThread caller, String name, int userId, boolean stable) {
10125        enforceNotIsolatedCaller("getContentProvider");
10126        if (caller == null) {
10127            String msg = "null IApplicationThread when getting content provider "
10128                    + name;
10129            Slog.w(TAG, msg);
10130            throw new SecurityException(msg);
10131        }
10132        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10133        // with cross-user grant.
10134        return getContentProviderImpl(caller, name, null, stable, userId);
10135    }
10136
10137    public ContentProviderHolder getContentProviderExternal(
10138            String name, int userId, IBinder token) {
10139        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10140            "Do not have permission in call getContentProviderExternal()");
10141        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10142                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10143        return getContentProviderExternalUnchecked(name, token, userId);
10144    }
10145
10146    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10147            IBinder token, int userId) {
10148        return getContentProviderImpl(null, name, token, true, userId);
10149    }
10150
10151    /**
10152     * Drop a content provider from a ProcessRecord's bookkeeping
10153     */
10154    public void removeContentProvider(IBinder connection, boolean stable) {
10155        enforceNotIsolatedCaller("removeContentProvider");
10156        long ident = Binder.clearCallingIdentity();
10157        try {
10158            synchronized (this) {
10159                ContentProviderConnection conn;
10160                try {
10161                    conn = (ContentProviderConnection)connection;
10162                } catch (ClassCastException e) {
10163                    String msg ="removeContentProvider: " + connection
10164                            + " not a ContentProviderConnection";
10165                    Slog.w(TAG, msg);
10166                    throw new IllegalArgumentException(msg);
10167                }
10168                if (conn == null) {
10169                    throw new NullPointerException("connection is null");
10170                }
10171                if (decProviderCountLocked(conn, null, null, stable)) {
10172                    updateOomAdjLocked();
10173                }
10174            }
10175        } finally {
10176            Binder.restoreCallingIdentity(ident);
10177        }
10178    }
10179
10180    public void removeContentProviderExternal(String name, IBinder token) {
10181        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10182            "Do not have permission in call removeContentProviderExternal()");
10183        int userId = UserHandle.getCallingUserId();
10184        long ident = Binder.clearCallingIdentity();
10185        try {
10186            removeContentProviderExternalUnchecked(name, token, userId);
10187        } finally {
10188            Binder.restoreCallingIdentity(ident);
10189        }
10190    }
10191
10192    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10193        synchronized (this) {
10194            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10195            if(cpr == null) {
10196                //remove from mProvidersByClass
10197                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10198                return;
10199            }
10200
10201            //update content provider record entry info
10202            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10203            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10204            if (localCpr.hasExternalProcessHandles()) {
10205                if (localCpr.removeExternalProcessHandleLocked(token)) {
10206                    updateOomAdjLocked();
10207                } else {
10208                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10209                            + " with no external reference for token: "
10210                            + token + ".");
10211                }
10212            } else {
10213                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10214                        + " with no external references.");
10215            }
10216        }
10217    }
10218
10219    public final void publishContentProviders(IApplicationThread caller,
10220            List<ContentProviderHolder> providers) {
10221        if (providers == null) {
10222            return;
10223        }
10224
10225        enforceNotIsolatedCaller("publishContentProviders");
10226        synchronized (this) {
10227            final ProcessRecord r = getRecordForAppLocked(caller);
10228            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10229            if (r == null) {
10230                throw new SecurityException(
10231                        "Unable to find app for caller " + caller
10232                      + " (pid=" + Binder.getCallingPid()
10233                      + ") when publishing content providers");
10234            }
10235
10236            final long origId = Binder.clearCallingIdentity();
10237
10238            final int N = providers.size();
10239            for (int i = 0; i < N; i++) {
10240                ContentProviderHolder src = providers.get(i);
10241                if (src == null || src.info == null || src.provider == null) {
10242                    continue;
10243                }
10244                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10245                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10246                if (dst != null) {
10247                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10248                    mProviderMap.putProviderByClass(comp, dst);
10249                    String names[] = dst.info.authority.split(";");
10250                    for (int j = 0; j < names.length; j++) {
10251                        mProviderMap.putProviderByName(names[j], dst);
10252                    }
10253
10254                    int launchingCount = mLaunchingProviders.size();
10255                    int j;
10256                    boolean wasInLaunchingProviders = false;
10257                    for (j = 0; j < launchingCount; j++) {
10258                        if (mLaunchingProviders.get(j) == dst) {
10259                            mLaunchingProviders.remove(j);
10260                            wasInLaunchingProviders = true;
10261                            j--;
10262                            launchingCount--;
10263                        }
10264                    }
10265                    if (wasInLaunchingProviders) {
10266                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10267                    }
10268                    synchronized (dst) {
10269                        dst.provider = src.provider;
10270                        dst.proc = r;
10271                        dst.notifyAll();
10272                    }
10273                    updateOomAdjLocked(r);
10274                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10275                            src.info.authority);
10276                }
10277            }
10278
10279            Binder.restoreCallingIdentity(origId);
10280        }
10281    }
10282
10283    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10284        ContentProviderConnection conn;
10285        try {
10286            conn = (ContentProviderConnection)connection;
10287        } catch (ClassCastException e) {
10288            String msg ="refContentProvider: " + connection
10289                    + " not a ContentProviderConnection";
10290            Slog.w(TAG, msg);
10291            throw new IllegalArgumentException(msg);
10292        }
10293        if (conn == null) {
10294            throw new NullPointerException("connection is null");
10295        }
10296
10297        synchronized (this) {
10298            if (stable > 0) {
10299                conn.numStableIncs += stable;
10300            }
10301            stable = conn.stableCount + stable;
10302            if (stable < 0) {
10303                throw new IllegalStateException("stableCount < 0: " + stable);
10304            }
10305
10306            if (unstable > 0) {
10307                conn.numUnstableIncs += unstable;
10308            }
10309            unstable = conn.unstableCount + unstable;
10310            if (unstable < 0) {
10311                throw new IllegalStateException("unstableCount < 0: " + unstable);
10312            }
10313
10314            if ((stable+unstable) <= 0) {
10315                throw new IllegalStateException("ref counts can't go to zero here: stable="
10316                        + stable + " unstable=" + unstable);
10317            }
10318            conn.stableCount = stable;
10319            conn.unstableCount = unstable;
10320            return !conn.dead;
10321        }
10322    }
10323
10324    public void unstableProviderDied(IBinder connection) {
10325        ContentProviderConnection conn;
10326        try {
10327            conn = (ContentProviderConnection)connection;
10328        } catch (ClassCastException e) {
10329            String msg ="refContentProvider: " + connection
10330                    + " not a ContentProviderConnection";
10331            Slog.w(TAG, msg);
10332            throw new IllegalArgumentException(msg);
10333        }
10334        if (conn == null) {
10335            throw new NullPointerException("connection is null");
10336        }
10337
10338        // Safely retrieve the content provider associated with the connection.
10339        IContentProvider provider;
10340        synchronized (this) {
10341            provider = conn.provider.provider;
10342        }
10343
10344        if (provider == null) {
10345            // Um, yeah, we're way ahead of you.
10346            return;
10347        }
10348
10349        // Make sure the caller is being honest with us.
10350        if (provider.asBinder().pingBinder()) {
10351            // Er, no, still looks good to us.
10352            synchronized (this) {
10353                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10354                        + " says " + conn + " died, but we don't agree");
10355                return;
10356            }
10357        }
10358
10359        // Well look at that!  It's dead!
10360        synchronized (this) {
10361            if (conn.provider.provider != provider) {
10362                // But something changed...  good enough.
10363                return;
10364            }
10365
10366            ProcessRecord proc = conn.provider.proc;
10367            if (proc == null || proc.thread == null) {
10368                // Seems like the process is already cleaned up.
10369                return;
10370            }
10371
10372            // As far as we're concerned, this is just like receiving a
10373            // death notification...  just a bit prematurely.
10374            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10375                    + ") early provider death");
10376            final long ident = Binder.clearCallingIdentity();
10377            try {
10378                appDiedLocked(proc);
10379            } finally {
10380                Binder.restoreCallingIdentity(ident);
10381            }
10382        }
10383    }
10384
10385    @Override
10386    public void appNotRespondingViaProvider(IBinder connection) {
10387        enforceCallingPermission(
10388                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10389
10390        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10391        if (conn == null) {
10392            Slog.w(TAG, "ContentProviderConnection is null");
10393            return;
10394        }
10395
10396        final ProcessRecord host = conn.provider.proc;
10397        if (host == null) {
10398            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10399            return;
10400        }
10401
10402        final long token = Binder.clearCallingIdentity();
10403        try {
10404            appNotResponding(host, null, null, false, "ContentProvider not responding");
10405        } finally {
10406            Binder.restoreCallingIdentity(token);
10407        }
10408    }
10409
10410    public final void installSystemProviders() {
10411        List<ProviderInfo> providers;
10412        synchronized (this) {
10413            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10414            providers = generateApplicationProvidersLocked(app);
10415            if (providers != null) {
10416                for (int i=providers.size()-1; i>=0; i--) {
10417                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10418                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10419                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10420                                + ": not system .apk");
10421                        providers.remove(i);
10422                    }
10423                }
10424            }
10425        }
10426        if (providers != null) {
10427            mSystemThread.installSystemProviders(providers);
10428        }
10429
10430        mCoreSettingsObserver = new CoreSettingsObserver(this);
10431
10432        //mUsageStatsService.monitorPackages();
10433    }
10434
10435    /**
10436     * Allows apps to retrieve the MIME type of a URI.
10437     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10438     * users, then it does not need permission to access the ContentProvider.
10439     * Either, it needs cross-user uri grants.
10440     *
10441     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10442     *
10443     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10444     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10445     */
10446    public String getProviderMimeType(Uri uri, int userId) {
10447        enforceNotIsolatedCaller("getProviderMimeType");
10448        final String name = uri.getAuthority();
10449        int callingUid = Binder.getCallingUid();
10450        int callingPid = Binder.getCallingPid();
10451        long ident = 0;
10452        boolean clearedIdentity = false;
10453        synchronized (this) {
10454            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10455        }
10456        if (canClearIdentity(callingPid, callingUid, userId)) {
10457            clearedIdentity = true;
10458            ident = Binder.clearCallingIdentity();
10459        }
10460        ContentProviderHolder holder = null;
10461        try {
10462            holder = getContentProviderExternalUnchecked(name, null, userId);
10463            if (holder != null) {
10464                return holder.provider.getType(uri);
10465            }
10466        } catch (RemoteException e) {
10467            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10468            return null;
10469        } finally {
10470            // We need to clear the identity to call removeContentProviderExternalUnchecked
10471            if (!clearedIdentity) {
10472                ident = Binder.clearCallingIdentity();
10473            }
10474            try {
10475                if (holder != null) {
10476                    removeContentProviderExternalUnchecked(name, null, userId);
10477                }
10478            } finally {
10479                Binder.restoreCallingIdentity(ident);
10480            }
10481        }
10482
10483        return null;
10484    }
10485
10486    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10487        if (UserHandle.getUserId(callingUid) == userId) {
10488            return true;
10489        }
10490        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10491                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10492                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10493                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10494                return true;
10495        }
10496        return false;
10497    }
10498
10499    // =========================================================
10500    // GLOBAL MANAGEMENT
10501    // =========================================================
10502
10503    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10504            boolean isolated, int isolatedUid) {
10505        String proc = customProcess != null ? customProcess : info.processName;
10506        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10507        final int userId = UserHandle.getUserId(info.uid);
10508        int uid = info.uid;
10509        if (isolated) {
10510            if (isolatedUid == 0) {
10511                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10512                while (true) {
10513                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10514                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10515                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10516                    }
10517                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10518                    mNextIsolatedProcessUid++;
10519                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10520                        // No process for this uid, use it.
10521                        break;
10522                    }
10523                    stepsLeft--;
10524                    if (stepsLeft <= 0) {
10525                        return null;
10526                    }
10527                }
10528            } else {
10529                // Special case for startIsolatedProcess (internal only), where
10530                // the uid of the isolated process is specified by the caller.
10531                uid = isolatedUid;
10532            }
10533        }
10534        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10535        if (!mBooted && !mBooting
10536                && userId == UserHandle.USER_SYSTEM
10537                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10538            r.persistent = true;
10539        }
10540        addProcessNameLocked(r);
10541        return r;
10542    }
10543
10544    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10545            String abiOverride) {
10546        ProcessRecord app;
10547        if (!isolated) {
10548            app = getProcessRecordLocked(info.processName, info.uid, true);
10549        } else {
10550            app = null;
10551        }
10552
10553        if (app == null) {
10554            app = newProcessRecordLocked(info, null, isolated, 0);
10555            updateLruProcessLocked(app, false, null);
10556            updateOomAdjLocked();
10557        }
10558
10559        // This package really, really can not be stopped.
10560        try {
10561            AppGlobals.getPackageManager().setPackageStoppedState(
10562                    info.packageName, false, UserHandle.getUserId(app.uid));
10563        } catch (RemoteException e) {
10564        } catch (IllegalArgumentException e) {
10565            Slog.w(TAG, "Failed trying to unstop package "
10566                    + info.packageName + ": " + e);
10567        }
10568
10569        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10570            app.persistent = true;
10571            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10572        }
10573        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10574            mPersistentStartingProcesses.add(app);
10575            startProcessLocked(app, "added application", app.processName, abiOverride,
10576                    null /* entryPoint */, null /* entryPointArgs */);
10577        }
10578
10579        return app;
10580    }
10581
10582    public void unhandledBack() {
10583        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10584                "unhandledBack()");
10585
10586        synchronized(this) {
10587            final long origId = Binder.clearCallingIdentity();
10588            try {
10589                getFocusedStack().unhandledBackLocked();
10590            } finally {
10591                Binder.restoreCallingIdentity(origId);
10592            }
10593        }
10594    }
10595
10596    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10597        enforceNotIsolatedCaller("openContentUri");
10598        final int userId = UserHandle.getCallingUserId();
10599        String name = uri.getAuthority();
10600        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10601        ParcelFileDescriptor pfd = null;
10602        if (cph != null) {
10603            // We record the binder invoker's uid in thread-local storage before
10604            // going to the content provider to open the file.  Later, in the code
10605            // that handles all permissions checks, we look for this uid and use
10606            // that rather than the Activity Manager's own uid.  The effect is that
10607            // we do the check against the caller's permissions even though it looks
10608            // to the content provider like the Activity Manager itself is making
10609            // the request.
10610            Binder token = new Binder();
10611            sCallerIdentity.set(new Identity(
10612                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10613            try {
10614                pfd = cph.provider.openFile(null, uri, "r", null, token);
10615            } catch (FileNotFoundException e) {
10616                // do nothing; pfd will be returned null
10617            } finally {
10618                // Ensure that whatever happens, we clean up the identity state
10619                sCallerIdentity.remove();
10620                // Ensure we're done with the provider.
10621                removeContentProviderExternalUnchecked(name, null, userId);
10622            }
10623        } else {
10624            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10625        }
10626        return pfd;
10627    }
10628
10629    // Actually is sleeping or shutting down or whatever else in the future
10630    // is an inactive state.
10631    public boolean isSleepingOrShuttingDown() {
10632        return isSleeping() || mShuttingDown;
10633    }
10634
10635    public boolean isSleeping() {
10636        return mSleeping;
10637    }
10638
10639    void onWakefulnessChanged(int wakefulness) {
10640        synchronized(this) {
10641            mWakefulness = wakefulness;
10642            updateSleepIfNeededLocked();
10643        }
10644    }
10645
10646    void finishRunningVoiceLocked() {
10647        if (mRunningVoice != null) {
10648            mRunningVoice = null;
10649            mVoiceWakeLock.release();
10650            updateSleepIfNeededLocked();
10651        }
10652    }
10653
10654    void startTimeTrackingFocusedActivityLocked() {
10655        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10656            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10657        }
10658    }
10659
10660    void updateSleepIfNeededLocked() {
10661        if (mSleeping && !shouldSleepLocked()) {
10662            mSleeping = false;
10663            startTimeTrackingFocusedActivityLocked();
10664            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10665            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10666            updateOomAdjLocked();
10667        } else if (!mSleeping && shouldSleepLocked()) {
10668            mSleeping = true;
10669            if (mCurAppTimeTracker != null) {
10670                mCurAppTimeTracker.stop();
10671            }
10672            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10673            mStackSupervisor.goingToSleepLocked();
10674            updateOomAdjLocked();
10675
10676            // Initialize the wake times of all processes.
10677            checkExcessivePowerUsageLocked(false);
10678            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10679            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10680            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10681        }
10682    }
10683
10684    private boolean shouldSleepLocked() {
10685        // Resume applications while running a voice interactor.
10686        if (mRunningVoice != null) {
10687            return false;
10688        }
10689
10690        // TODO: Transform the lock screen state into a sleep token instead.
10691        switch (mWakefulness) {
10692            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10693            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10694            case PowerManagerInternal.WAKEFULNESS_DOZING:
10695                // Pause applications whenever the lock screen is shown or any sleep
10696                // tokens have been acquired.
10697                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10698            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10699            default:
10700                // If we're asleep then pause applications unconditionally.
10701                return true;
10702        }
10703    }
10704
10705    /** Pokes the task persister. */
10706    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10707        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10708            // Never persist the home stack.
10709            return;
10710        }
10711        mTaskPersister.wakeup(task, flush);
10712    }
10713
10714    /** Notifies all listeners when the task stack has changed. */
10715    void notifyTaskStackChangedLocked() {
10716        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10717        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10718        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10719    }
10720
10721    @Override
10722    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10723        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10724    }
10725
10726    @Override
10727    public boolean shutdown(int timeout) {
10728        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10729                != PackageManager.PERMISSION_GRANTED) {
10730            throw new SecurityException("Requires permission "
10731                    + android.Manifest.permission.SHUTDOWN);
10732        }
10733
10734        boolean timedout = false;
10735
10736        synchronized(this) {
10737            mShuttingDown = true;
10738            updateEventDispatchingLocked();
10739            timedout = mStackSupervisor.shutdownLocked(timeout);
10740        }
10741
10742        mAppOpsService.shutdown();
10743        if (mUsageStatsService != null) {
10744            mUsageStatsService.prepareShutdown();
10745        }
10746        mBatteryStatsService.shutdown();
10747        synchronized (this) {
10748            mProcessStats.shutdownLocked();
10749            notifyTaskPersisterLocked(null, true);
10750        }
10751
10752        return timedout;
10753    }
10754
10755    public final void activitySlept(IBinder token) {
10756        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10757
10758        final long origId = Binder.clearCallingIdentity();
10759
10760        synchronized (this) {
10761            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10762            if (r != null) {
10763                mStackSupervisor.activitySleptLocked(r);
10764            }
10765        }
10766
10767        Binder.restoreCallingIdentity(origId);
10768    }
10769
10770    private String lockScreenShownToString() {
10771        switch (mLockScreenShown) {
10772            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10773            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10774            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10775            default: return "Unknown=" + mLockScreenShown;
10776        }
10777    }
10778
10779    void logLockScreen(String msg) {
10780        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10781                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10782                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10783                + " mSleeping=" + mSleeping);
10784    }
10785
10786    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10787        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10788        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10789            boolean wasRunningVoice = mRunningVoice != null;
10790            mRunningVoice = session;
10791            if (!wasRunningVoice) {
10792                mVoiceWakeLock.acquire();
10793                updateSleepIfNeededLocked();
10794            }
10795        }
10796    }
10797
10798    private void updateEventDispatchingLocked() {
10799        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10800    }
10801
10802    public void setLockScreenShown(boolean shown) {
10803        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10804                != PackageManager.PERMISSION_GRANTED) {
10805            throw new SecurityException("Requires permission "
10806                    + android.Manifest.permission.DEVICE_POWER);
10807        }
10808
10809        synchronized(this) {
10810            long ident = Binder.clearCallingIdentity();
10811            try {
10812                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10813                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10814                updateSleepIfNeededLocked();
10815            } finally {
10816                Binder.restoreCallingIdentity(ident);
10817            }
10818        }
10819    }
10820
10821    @Override
10822    public void stopAppSwitches() {
10823        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10824                != PackageManager.PERMISSION_GRANTED) {
10825            throw new SecurityException("Requires permission "
10826                    + android.Manifest.permission.STOP_APP_SWITCHES);
10827        }
10828
10829        synchronized(this) {
10830            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10831                    + APP_SWITCH_DELAY_TIME;
10832            mDidAppSwitch = false;
10833            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10834            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10835            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10836        }
10837    }
10838
10839    public void resumeAppSwitches() {
10840        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10841                != PackageManager.PERMISSION_GRANTED) {
10842            throw new SecurityException("Requires permission "
10843                    + android.Manifest.permission.STOP_APP_SWITCHES);
10844        }
10845
10846        synchronized(this) {
10847            // Note that we don't execute any pending app switches... we will
10848            // let those wait until either the timeout, or the next start
10849            // activity request.
10850            mAppSwitchesAllowedTime = 0;
10851        }
10852    }
10853
10854    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10855            int callingPid, int callingUid, String name) {
10856        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10857            return true;
10858        }
10859
10860        int perm = checkComponentPermission(
10861                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10862                sourceUid, -1, true);
10863        if (perm == PackageManager.PERMISSION_GRANTED) {
10864            return true;
10865        }
10866
10867        // If the actual IPC caller is different from the logical source, then
10868        // also see if they are allowed to control app switches.
10869        if (callingUid != -1 && callingUid != sourceUid) {
10870            perm = checkComponentPermission(
10871                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10872                    callingUid, -1, true);
10873            if (perm == PackageManager.PERMISSION_GRANTED) {
10874                return true;
10875            }
10876        }
10877
10878        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10879        return false;
10880    }
10881
10882    public void setDebugApp(String packageName, boolean waitForDebugger,
10883            boolean persistent) {
10884        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10885                "setDebugApp()");
10886
10887        long ident = Binder.clearCallingIdentity();
10888        try {
10889            // Note that this is not really thread safe if there are multiple
10890            // callers into it at the same time, but that's not a situation we
10891            // care about.
10892            if (persistent) {
10893                final ContentResolver resolver = mContext.getContentResolver();
10894                Settings.Global.putString(
10895                    resolver, Settings.Global.DEBUG_APP,
10896                    packageName);
10897                Settings.Global.putInt(
10898                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10899                    waitForDebugger ? 1 : 0);
10900            }
10901
10902            synchronized (this) {
10903                if (!persistent) {
10904                    mOrigDebugApp = mDebugApp;
10905                    mOrigWaitForDebugger = mWaitForDebugger;
10906                }
10907                mDebugApp = packageName;
10908                mWaitForDebugger = waitForDebugger;
10909                mDebugTransient = !persistent;
10910                if (packageName != null) {
10911                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10912                            false, UserHandle.USER_ALL, "set debug app");
10913                }
10914            }
10915        } finally {
10916            Binder.restoreCallingIdentity(ident);
10917        }
10918    }
10919
10920    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10921        synchronized (this) {
10922            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10923            if (!isDebuggable) {
10924                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10925                    throw new SecurityException("Process not debuggable: " + app.packageName);
10926                }
10927            }
10928
10929            mTrackAllocationApp = processName;
10930        }
10931    }
10932
10933    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10934        synchronized (this) {
10935            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10936            if (!isDebuggable) {
10937                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10938                    throw new SecurityException("Process not debuggable: " + app.packageName);
10939                }
10940            }
10941            mProfileApp = processName;
10942            mProfileFile = profilerInfo.profileFile;
10943            if (mProfileFd != null) {
10944                try {
10945                    mProfileFd.close();
10946                } catch (IOException e) {
10947                }
10948                mProfileFd = null;
10949            }
10950            mProfileFd = profilerInfo.profileFd;
10951            mSamplingInterval = profilerInfo.samplingInterval;
10952            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10953            mProfileType = 0;
10954        }
10955    }
10956
10957    @Override
10958    public void setAlwaysFinish(boolean enabled) {
10959        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10960                "setAlwaysFinish()");
10961
10962        Settings.Global.putInt(
10963                mContext.getContentResolver(),
10964                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10965
10966        synchronized (this) {
10967            mAlwaysFinishActivities = enabled;
10968        }
10969    }
10970
10971    @Override
10972    public void setActivityController(IActivityController controller) {
10973        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10974                "setActivityController()");
10975        synchronized (this) {
10976            mController = controller;
10977            Watchdog.getInstance().setActivityController(controller);
10978        }
10979    }
10980
10981    @Override
10982    public void setUserIsMonkey(boolean userIsMonkey) {
10983        synchronized (this) {
10984            synchronized (mPidsSelfLocked) {
10985                final int callingPid = Binder.getCallingPid();
10986                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10987                if (precessRecord == null) {
10988                    throw new SecurityException("Unknown process: " + callingPid);
10989                }
10990                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10991                    throw new SecurityException("Only an instrumentation process "
10992                            + "with a UiAutomation can call setUserIsMonkey");
10993                }
10994            }
10995            mUserIsMonkey = userIsMonkey;
10996        }
10997    }
10998
10999    @Override
11000    public boolean isUserAMonkey() {
11001        synchronized (this) {
11002            // If there is a controller also implies the user is a monkey.
11003            return (mUserIsMonkey || mController != null);
11004        }
11005    }
11006
11007    public void requestBugReport() {
11008        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11009        SystemProperties.set("ctl.start", "bugreport");
11010    }
11011
11012    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11013        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11014    }
11015
11016    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11017        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11018            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11019        }
11020        return KEY_DISPATCHING_TIMEOUT;
11021    }
11022
11023    @Override
11024    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11025        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11026                != PackageManager.PERMISSION_GRANTED) {
11027            throw new SecurityException("Requires permission "
11028                    + android.Manifest.permission.FILTER_EVENTS);
11029        }
11030        ProcessRecord proc;
11031        long timeout;
11032        synchronized (this) {
11033            synchronized (mPidsSelfLocked) {
11034                proc = mPidsSelfLocked.get(pid);
11035            }
11036            timeout = getInputDispatchingTimeoutLocked(proc);
11037        }
11038
11039        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11040            return -1;
11041        }
11042
11043        return timeout;
11044    }
11045
11046    /**
11047     * Handle input dispatching timeouts.
11048     * Returns whether input dispatching should be aborted or not.
11049     */
11050    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11051            final ActivityRecord activity, final ActivityRecord parent,
11052            final boolean aboveSystem, String reason) {
11053        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11054                != PackageManager.PERMISSION_GRANTED) {
11055            throw new SecurityException("Requires permission "
11056                    + android.Manifest.permission.FILTER_EVENTS);
11057        }
11058
11059        final String annotation;
11060        if (reason == null) {
11061            annotation = "Input dispatching timed out";
11062        } else {
11063            annotation = "Input dispatching timed out (" + reason + ")";
11064        }
11065
11066        if (proc != null) {
11067            synchronized (this) {
11068                if (proc.debugging) {
11069                    return false;
11070                }
11071
11072                if (mDidDexOpt) {
11073                    // Give more time since we were dexopting.
11074                    mDidDexOpt = false;
11075                    return false;
11076                }
11077
11078                if (proc.instrumentationClass != null) {
11079                    Bundle info = new Bundle();
11080                    info.putString("shortMsg", "keyDispatchingTimedOut");
11081                    info.putString("longMsg", annotation);
11082                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11083                    return true;
11084                }
11085            }
11086            mHandler.post(new Runnable() {
11087                @Override
11088                public void run() {
11089                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11090                }
11091            });
11092        }
11093
11094        return true;
11095    }
11096
11097    @Override
11098    public Bundle getAssistContextExtras(int requestType) {
11099        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11100                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11101        if (pae == null) {
11102            return null;
11103        }
11104        synchronized (pae) {
11105            while (!pae.haveResult) {
11106                try {
11107                    pae.wait();
11108                } catch (InterruptedException e) {
11109                }
11110            }
11111        }
11112        synchronized (this) {
11113            buildAssistBundleLocked(pae, pae.result);
11114            mPendingAssistExtras.remove(pae);
11115            mUiHandler.removeCallbacks(pae);
11116        }
11117        return pae.extras;
11118    }
11119
11120    @Override
11121    public boolean isAssistDataAllowedOnCurrentActivity() {
11122        int userId;
11123        synchronized (this) {
11124            userId = mUserController.getCurrentUserIdLocked();
11125            ActivityRecord activity = getFocusedStack().topActivity();
11126            if (activity == null) {
11127                return false;
11128            }
11129            userId = activity.userId;
11130        }
11131        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11132                Context.DEVICE_POLICY_SERVICE);
11133        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11134    }
11135
11136    @Override
11137    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11138        long ident = Binder.clearCallingIdentity();
11139        try {
11140            synchronized (this) {
11141                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11142                ActivityRecord top = getFocusedStack().topActivity();
11143                if (top != caller) {
11144                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11145                            + " is not current top " + top);
11146                    return false;
11147                }
11148                if (!top.nowVisible) {
11149                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11150                            + " is not visible");
11151                    return false;
11152                }
11153            }
11154            AssistUtils utils = new AssistUtils(mContext);
11155            return utils.showSessionForActiveService(args,
11156                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11157        } finally {
11158            Binder.restoreCallingIdentity(ident);
11159        }
11160    }
11161
11162    @Override
11163    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11164            IBinder activityToken) {
11165        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11166                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11167    }
11168
11169    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11170            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11171            long timeout) {
11172        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11173                "enqueueAssistContext()");
11174        synchronized (this) {
11175            ActivityRecord activity = getFocusedStack().topActivity();
11176            if (activity == null) {
11177                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11178                return null;
11179            }
11180            if (activity.app == null || activity.app.thread == null) {
11181                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11182                return null;
11183            }
11184            if (activityToken != null) {
11185                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11186                if (activity != caller) {
11187                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11188                            + " is not current top " + activity);
11189                    return null;
11190                }
11191            }
11192            PendingAssistExtras pae;
11193            Bundle extras = new Bundle();
11194            if (args != null) {
11195                extras.putAll(args);
11196            }
11197            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11198            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11199            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11200            try {
11201                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11202                        requestType);
11203                mPendingAssistExtras.add(pae);
11204                mUiHandler.postDelayed(pae, timeout);
11205            } catch (RemoteException e) {
11206                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11207                return null;
11208            }
11209            return pae;
11210        }
11211    }
11212
11213    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11214        IResultReceiver receiver;
11215        synchronized (this) {
11216            mPendingAssistExtras.remove(pae);
11217            receiver = pae.receiver;
11218        }
11219        if (receiver != null) {
11220            // Caller wants result sent back to them.
11221            try {
11222                pae.receiver.send(0, null);
11223            } catch (RemoteException e) {
11224            }
11225        }
11226    }
11227
11228    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11229        if (result != null) {
11230            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11231        }
11232        if (pae.hint != null) {
11233            pae.extras.putBoolean(pae.hint, true);
11234        }
11235    }
11236
11237    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11238            AssistContent content, Uri referrer) {
11239        PendingAssistExtras pae = (PendingAssistExtras)token;
11240        synchronized (pae) {
11241            pae.result = extras;
11242            pae.structure = structure;
11243            pae.content = content;
11244            if (referrer != null) {
11245                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11246            }
11247            pae.haveResult = true;
11248            pae.notifyAll();
11249            if (pae.intent == null && pae.receiver == null) {
11250                // Caller is just waiting for the result.
11251                return;
11252            }
11253        }
11254
11255        // We are now ready to launch the assist activity.
11256        IResultReceiver sendReceiver = null;
11257        Bundle sendBundle = null;
11258        synchronized (this) {
11259            buildAssistBundleLocked(pae, extras);
11260            boolean exists = mPendingAssistExtras.remove(pae);
11261            mUiHandler.removeCallbacks(pae);
11262            if (!exists) {
11263                // Timed out.
11264                return;
11265            }
11266            if ((sendReceiver=pae.receiver) != null) {
11267                // Caller wants result sent back to them.
11268                sendBundle = new Bundle();
11269                sendBundle.putBundle("data", pae.extras);
11270                sendBundle.putParcelable("structure", pae.structure);
11271                sendBundle.putParcelable("content", pae.content);
11272            }
11273        }
11274        if (sendReceiver != null) {
11275            try {
11276                sendReceiver.send(0, sendBundle);
11277            } catch (RemoteException e) {
11278            }
11279            return;
11280        }
11281
11282        long ident = Binder.clearCallingIdentity();
11283        try {
11284            pae.intent.replaceExtras(pae.extras);
11285            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11286                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11287                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11288            closeSystemDialogs("assist");
11289            try {
11290                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11291            } catch (ActivityNotFoundException e) {
11292                Slog.w(TAG, "No activity to handle assist action.", e);
11293            }
11294        } finally {
11295            Binder.restoreCallingIdentity(ident);
11296        }
11297    }
11298
11299    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11300            Bundle args) {
11301        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11302                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11303    }
11304
11305    public void registerProcessObserver(IProcessObserver observer) {
11306        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11307                "registerProcessObserver()");
11308        synchronized (this) {
11309            mProcessObservers.register(observer);
11310        }
11311    }
11312
11313    @Override
11314    public void unregisterProcessObserver(IProcessObserver observer) {
11315        synchronized (this) {
11316            mProcessObservers.unregister(observer);
11317        }
11318    }
11319
11320    @Override
11321    public void registerUidObserver(IUidObserver observer, int which) {
11322        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11323                "registerUidObserver()");
11324        synchronized (this) {
11325            mUidObservers.register(observer, which);
11326        }
11327    }
11328
11329    @Override
11330    public void unregisterUidObserver(IUidObserver observer) {
11331        synchronized (this) {
11332            mUidObservers.unregister(observer);
11333        }
11334    }
11335
11336    @Override
11337    public boolean convertFromTranslucent(IBinder token) {
11338        final long origId = Binder.clearCallingIdentity();
11339        try {
11340            synchronized (this) {
11341                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11342                if (r == null) {
11343                    return false;
11344                }
11345                final boolean translucentChanged = r.changeWindowTranslucency(true);
11346                if (translucentChanged) {
11347                    r.task.stack.releaseBackgroundResources(r);
11348                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11349                }
11350                mWindowManager.setAppFullscreen(token, true);
11351                return translucentChanged;
11352            }
11353        } finally {
11354            Binder.restoreCallingIdentity(origId);
11355        }
11356    }
11357
11358    @Override
11359    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11360        final long origId = Binder.clearCallingIdentity();
11361        try {
11362            synchronized (this) {
11363                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11364                if (r == null) {
11365                    return false;
11366                }
11367                int index = r.task.mActivities.lastIndexOf(r);
11368                if (index > 0) {
11369                    ActivityRecord under = r.task.mActivities.get(index - 1);
11370                    under.returningOptions = options;
11371                }
11372                final boolean translucentChanged = r.changeWindowTranslucency(false);
11373                if (translucentChanged) {
11374                    r.task.stack.convertActivityToTranslucent(r);
11375                }
11376                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11377                mWindowManager.setAppFullscreen(token, false);
11378                return translucentChanged;
11379            }
11380        } finally {
11381            Binder.restoreCallingIdentity(origId);
11382        }
11383    }
11384
11385    @Override
11386    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11387        final long origId = Binder.clearCallingIdentity();
11388        try {
11389            synchronized (this) {
11390                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11391                if (r != null) {
11392                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11393                }
11394            }
11395            return false;
11396        } finally {
11397            Binder.restoreCallingIdentity(origId);
11398        }
11399    }
11400
11401    @Override
11402    public boolean isBackgroundVisibleBehind(IBinder token) {
11403        final long origId = Binder.clearCallingIdentity();
11404        try {
11405            synchronized (this) {
11406                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11407                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11408                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11409                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11410                return visible;
11411            }
11412        } finally {
11413            Binder.restoreCallingIdentity(origId);
11414        }
11415    }
11416
11417    @Override
11418    public ActivityOptions getActivityOptions(IBinder token) {
11419        final long origId = Binder.clearCallingIdentity();
11420        try {
11421            synchronized (this) {
11422                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11423                if (r != null) {
11424                    final ActivityOptions activityOptions = r.pendingOptions;
11425                    r.pendingOptions = null;
11426                    return activityOptions;
11427                }
11428                return null;
11429            }
11430        } finally {
11431            Binder.restoreCallingIdentity(origId);
11432        }
11433    }
11434
11435    @Override
11436    public void setImmersive(IBinder token, boolean immersive) {
11437        synchronized(this) {
11438            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11439            if (r == null) {
11440                throw new IllegalArgumentException();
11441            }
11442            r.immersive = immersive;
11443
11444            // update associated state if we're frontmost
11445            if (r == mFocusedActivity) {
11446                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11447                applyUpdateLockStateLocked(r);
11448            }
11449        }
11450    }
11451
11452    @Override
11453    public boolean isImmersive(IBinder token) {
11454        synchronized (this) {
11455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11456            if (r == null) {
11457                throw new IllegalArgumentException();
11458            }
11459            return r.immersive;
11460        }
11461    }
11462
11463    public boolean isTopActivityImmersive() {
11464        enforceNotIsolatedCaller("startActivity");
11465        synchronized (this) {
11466            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11467            return (r != null) ? r.immersive : false;
11468        }
11469    }
11470
11471    @Override
11472    public boolean isTopOfTask(IBinder token) {
11473        synchronized (this) {
11474            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11475            if (r == null) {
11476                throw new IllegalArgumentException();
11477            }
11478            return r.task.getTopActivity() == r;
11479        }
11480    }
11481
11482    public final void enterSafeMode() {
11483        synchronized(this) {
11484            // It only makes sense to do this before the system is ready
11485            // and started launching other packages.
11486            if (!mSystemReady) {
11487                try {
11488                    AppGlobals.getPackageManager().enterSafeMode();
11489                } catch (RemoteException e) {
11490                }
11491            }
11492
11493            mSafeMode = true;
11494        }
11495    }
11496
11497    public final void showSafeModeOverlay() {
11498        View v = LayoutInflater.from(mContext).inflate(
11499                com.android.internal.R.layout.safe_mode, null);
11500        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11501        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11502        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11503        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11504        lp.gravity = Gravity.BOTTOM | Gravity.START;
11505        lp.format = v.getBackground().getOpacity();
11506        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11507                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11508        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11509        ((WindowManager)mContext.getSystemService(
11510                Context.WINDOW_SERVICE)).addView(v, lp);
11511    }
11512
11513    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11514        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11515            return;
11516        }
11517        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11518        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11519        synchronized (stats) {
11520            if (mBatteryStatsService.isOnBattery()) {
11521                mBatteryStatsService.enforceCallingPermission();
11522                int MY_UID = Binder.getCallingUid();
11523                final int uid;
11524                if (sender == null) {
11525                    uid = sourceUid;
11526                } else {
11527                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11528                }
11529                BatteryStatsImpl.Uid.Pkg pkg =
11530                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11531                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11532                pkg.noteWakeupAlarmLocked(tag);
11533            }
11534        }
11535    }
11536
11537    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11538        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11539            return;
11540        }
11541        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11542        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11543        synchronized (stats) {
11544            mBatteryStatsService.enforceCallingPermission();
11545            int MY_UID = Binder.getCallingUid();
11546            final int uid;
11547            if (sender == null) {
11548                uid = sourceUid;
11549            } else {
11550                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11551            }
11552            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11553        }
11554    }
11555
11556    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11557        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11558            return;
11559        }
11560        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11561        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11562        synchronized (stats) {
11563            mBatteryStatsService.enforceCallingPermission();
11564            int MY_UID = Binder.getCallingUid();
11565            final int uid;
11566            if (sender == null) {
11567                uid = sourceUid;
11568            } else {
11569                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11570            }
11571            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11572        }
11573    }
11574
11575    public boolean killPids(int[] pids, String pReason, boolean secure) {
11576        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11577            throw new SecurityException("killPids only available to the system");
11578        }
11579        String reason = (pReason == null) ? "Unknown" : pReason;
11580        // XXX Note: don't acquire main activity lock here, because the window
11581        // manager calls in with its locks held.
11582
11583        boolean killed = false;
11584        synchronized (mPidsSelfLocked) {
11585            int[] types = new int[pids.length];
11586            int worstType = 0;
11587            for (int i=0; i<pids.length; i++) {
11588                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11589                if (proc != null) {
11590                    int type = proc.setAdj;
11591                    types[i] = type;
11592                    if (type > worstType) {
11593                        worstType = type;
11594                    }
11595                }
11596            }
11597
11598            // If the worst oom_adj is somewhere in the cached proc LRU range,
11599            // then constrain it so we will kill all cached procs.
11600            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11601                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11602                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11603            }
11604
11605            // If this is not a secure call, don't let it kill processes that
11606            // are important.
11607            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11608                worstType = ProcessList.SERVICE_ADJ;
11609            }
11610
11611            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11612            for (int i=0; i<pids.length; i++) {
11613                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11614                if (proc == null) {
11615                    continue;
11616                }
11617                int adj = proc.setAdj;
11618                if (adj >= worstType && !proc.killedByAm) {
11619                    proc.kill(reason, true);
11620                    killed = true;
11621                }
11622            }
11623        }
11624        return killed;
11625    }
11626
11627    @Override
11628    public void killUid(int appId, int userId, String reason) {
11629        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11630        synchronized (this) {
11631            final long identity = Binder.clearCallingIdentity();
11632            try {
11633                killPackageProcessesLocked(null, appId, userId,
11634                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11635                        reason != null ? reason : "kill uid");
11636            } finally {
11637                Binder.restoreCallingIdentity(identity);
11638            }
11639        }
11640    }
11641
11642    @Override
11643    public boolean killProcessesBelowForeground(String reason) {
11644        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11645            throw new SecurityException("killProcessesBelowForeground() only available to system");
11646        }
11647
11648        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11649    }
11650
11651    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11652        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11653            throw new SecurityException("killProcessesBelowAdj() only available to system");
11654        }
11655
11656        boolean killed = false;
11657        synchronized (mPidsSelfLocked) {
11658            final int size = mPidsSelfLocked.size();
11659            for (int i = 0; i < size; i++) {
11660                final int pid = mPidsSelfLocked.keyAt(i);
11661                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11662                if (proc == null) continue;
11663
11664                final int adj = proc.setAdj;
11665                if (adj > belowAdj && !proc.killedByAm) {
11666                    proc.kill(reason, true);
11667                    killed = true;
11668                }
11669            }
11670        }
11671        return killed;
11672    }
11673
11674    @Override
11675    public void hang(final IBinder who, boolean allowRestart) {
11676        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11677                != PackageManager.PERMISSION_GRANTED) {
11678            throw new SecurityException("Requires permission "
11679                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11680        }
11681
11682        final IBinder.DeathRecipient death = new DeathRecipient() {
11683            @Override
11684            public void binderDied() {
11685                synchronized (this) {
11686                    notifyAll();
11687                }
11688            }
11689        };
11690
11691        try {
11692            who.linkToDeath(death, 0);
11693        } catch (RemoteException e) {
11694            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11695            return;
11696        }
11697
11698        synchronized (this) {
11699            Watchdog.getInstance().setAllowRestart(allowRestart);
11700            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11701            synchronized (death) {
11702                while (who.isBinderAlive()) {
11703                    try {
11704                        death.wait();
11705                    } catch (InterruptedException e) {
11706                    }
11707                }
11708            }
11709            Watchdog.getInstance().setAllowRestart(true);
11710        }
11711    }
11712
11713    @Override
11714    public void restart() {
11715        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11716                != PackageManager.PERMISSION_GRANTED) {
11717            throw new SecurityException("Requires permission "
11718                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11719        }
11720
11721        Log.i(TAG, "Sending shutdown broadcast...");
11722
11723        BroadcastReceiver br = new BroadcastReceiver() {
11724            @Override public void onReceive(Context context, Intent intent) {
11725                // Now the broadcast is done, finish up the low-level shutdown.
11726                Log.i(TAG, "Shutting down activity manager...");
11727                shutdown(10000);
11728                Log.i(TAG, "Shutdown complete, restarting!");
11729                Process.killProcess(Process.myPid());
11730                System.exit(10);
11731            }
11732        };
11733
11734        // First send the high-level shut down broadcast.
11735        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11736        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11737        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11738        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11739        mContext.sendOrderedBroadcastAsUser(intent,
11740                UserHandle.ALL, null, br, mHandler, 0, null, null);
11741        */
11742        br.onReceive(mContext, intent);
11743    }
11744
11745    private long getLowRamTimeSinceIdle(long now) {
11746        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11747    }
11748
11749    @Override
11750    public void performIdleMaintenance() {
11751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11752                != PackageManager.PERMISSION_GRANTED) {
11753            throw new SecurityException("Requires permission "
11754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11755        }
11756
11757        synchronized (this) {
11758            final long now = SystemClock.uptimeMillis();
11759            final long timeSinceLastIdle = now - mLastIdleTime;
11760            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11761            mLastIdleTime = now;
11762            mLowRamTimeSinceLastIdle = 0;
11763            if (mLowRamStartTime != 0) {
11764                mLowRamStartTime = now;
11765            }
11766
11767            StringBuilder sb = new StringBuilder(128);
11768            sb.append("Idle maintenance over ");
11769            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11770            sb.append(" low RAM for ");
11771            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11772            Slog.i(TAG, sb.toString());
11773
11774            // If at least 1/3 of our time since the last idle period has been spent
11775            // with RAM low, then we want to kill processes.
11776            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11777
11778            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11779                ProcessRecord proc = mLruProcesses.get(i);
11780                if (proc.notCachedSinceIdle) {
11781                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11782                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11783                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11784                        if (doKilling && proc.initialIdlePss != 0
11785                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11786                            sb = new StringBuilder(128);
11787                            sb.append("Kill");
11788                            sb.append(proc.processName);
11789                            sb.append(" in idle maint: pss=");
11790                            sb.append(proc.lastPss);
11791                            sb.append(", initialPss=");
11792                            sb.append(proc.initialIdlePss);
11793                            sb.append(", period=");
11794                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11795                            sb.append(", lowRamPeriod=");
11796                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11797                            Slog.wtfQuiet(TAG, sb.toString());
11798                            proc.kill("idle maint (pss " + proc.lastPss
11799                                    + " from " + proc.initialIdlePss + ")", true);
11800                        }
11801                    }
11802                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11803                    proc.notCachedSinceIdle = true;
11804                    proc.initialIdlePss = 0;
11805                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11806                            mTestPssMode, isSleeping(), now);
11807                }
11808            }
11809
11810            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11811            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11812        }
11813    }
11814
11815    private void retrieveSettings() {
11816        final ContentResolver resolver = mContext.getContentResolver();
11817        String debugApp = Settings.Global.getString(resolver, Settings.Global.DEBUG_APP);
11818        boolean waitForDebugger = Settings.Global.getInt(
11819            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11820        boolean alwaysFinishActivities = Settings.Global.getInt(
11821            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11822        boolean forceRtl = Settings.Global.getInt(
11823                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11824        int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
11825        boolean forceResizable = Settings.Global.getInt(
11826                resolver, Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
11827                defaultForceResizable) != 0;
11828        // Transfer any global setting for forcing RTL layout, into a System Property
11829        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11830
11831        Configuration configuration = new Configuration();
11832        Settings.System.getConfiguration(resolver, configuration);
11833        if (forceRtl) {
11834            // This will take care of setting the correct layout direction flags
11835            configuration.setLayoutDirection(configuration.locale);
11836        }
11837
11838        synchronized (this) {
11839            mDebugApp = mOrigDebugApp = debugApp;
11840            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11841            mAlwaysFinishActivities = alwaysFinishActivities;
11842            mForceResizableActivites = forceResizable;
11843            // This happens before any activities are started, so we can
11844            // change mConfiguration in-place.
11845            updateConfigurationLocked(configuration, null, true);
11846            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11847                    "Initial config: " + mConfiguration);
11848        }
11849    }
11850
11851    /** Loads resources after the current configuration has been set. */
11852    private void loadResourcesOnSystemReady() {
11853        final Resources res = mContext.getResources();
11854        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11855        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11856        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11857    }
11858
11859    public boolean testIsSystemReady() {
11860        // no need to synchronize(this) just to read & return the value
11861        return mSystemReady;
11862    }
11863
11864    private static File getCalledPreBootReceiversFile() {
11865        File dataDir = Environment.getDataDirectory();
11866        File systemDir = new File(dataDir, "system");
11867        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11868        return fname;
11869    }
11870
11871    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11872        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11873        File file = getCalledPreBootReceiversFile();
11874        FileInputStream fis = null;
11875        try {
11876            fis = new FileInputStream(file);
11877            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11878            int fvers = dis.readInt();
11879            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11880                String vers = dis.readUTF();
11881                String codename = dis.readUTF();
11882                String build = dis.readUTF();
11883                if (android.os.Build.VERSION.RELEASE.equals(vers)
11884                        && android.os.Build.VERSION.CODENAME.equals(codename)
11885                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11886                    int num = dis.readInt();
11887                    while (num > 0) {
11888                        num--;
11889                        String pkg = dis.readUTF();
11890                        String cls = dis.readUTF();
11891                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11892                    }
11893                }
11894            }
11895        } catch (FileNotFoundException e) {
11896        } catch (IOException e) {
11897            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11898        } finally {
11899            if (fis != null) {
11900                try {
11901                    fis.close();
11902                } catch (IOException e) {
11903                }
11904            }
11905        }
11906        return lastDoneReceivers;
11907    }
11908
11909    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11910        File file = getCalledPreBootReceiversFile();
11911        FileOutputStream fos = null;
11912        DataOutputStream dos = null;
11913        try {
11914            fos = new FileOutputStream(file);
11915            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11916            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11917            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11918            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11919            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11920            dos.writeInt(list.size());
11921            for (int i=0; i<list.size(); i++) {
11922                dos.writeUTF(list.get(i).getPackageName());
11923                dos.writeUTF(list.get(i).getClassName());
11924            }
11925        } catch (IOException e) {
11926            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11927            file.delete();
11928        } finally {
11929            FileUtils.sync(fos);
11930            if (dos != null) {
11931                try {
11932                    dos.close();
11933                } catch (IOException e) {
11934                    // TODO Auto-generated catch block
11935                    e.printStackTrace();
11936                }
11937            }
11938        }
11939    }
11940
11941    final class PreBootContinuation extends IIntentReceiver.Stub {
11942        final Intent intent;
11943        final Runnable onFinishCallback;
11944        final ArrayList<ComponentName> doneReceivers;
11945        final List<ResolveInfo> ris;
11946        final int[] users;
11947        int lastRi = -1;
11948        int curRi = 0;
11949        int curUser = 0;
11950
11951        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11952                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11953            intent = _intent;
11954            onFinishCallback = _onFinishCallback;
11955            doneReceivers = _doneReceivers;
11956            ris = _ris;
11957            users = _users;
11958        }
11959
11960        void go() {
11961            if (lastRi != curRi) {
11962                ActivityInfo ai = ris.get(curRi).activityInfo;
11963                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11964                intent.setComponent(comp);
11965                doneReceivers.add(comp);
11966                lastRi = curRi;
11967                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11968                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11969            }
11970            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11971                    + " for user " + users[curUser]);
11972            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11973            broadcastIntentLocked(null, null, intent, null, this,
11974                    0, null, null, null, AppOpsManager.OP_NONE,
11975                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11976        }
11977
11978        public void performReceive(Intent intent, int resultCode,
11979                String data, Bundle extras, boolean ordered,
11980                boolean sticky, int sendingUser) {
11981            curUser++;
11982            if (curUser >= users.length) {
11983                curUser = 0;
11984                curRi++;
11985                if (curRi >= ris.size()) {
11986                    // All done sending broadcasts!
11987                    if (onFinishCallback != null) {
11988                        // The raw IIntentReceiver interface is called
11989                        // with the AM lock held, so redispatch to
11990                        // execute our code without the lock.
11991                        mHandler.post(onFinishCallback);
11992                    }
11993                    return;
11994                }
11995            }
11996            go();
11997        }
11998    }
11999
12000    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12001            ArrayList<ComponentName> doneReceivers) {
12002        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12003        List<ResolveInfo> ris = null;
12004        try {
12005            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12006                    intent, null, 0, UserHandle.USER_SYSTEM);
12007        } catch (RemoteException e) {
12008        }
12009        if (ris == null) {
12010            return false;
12011        }
12012        for (int i=ris.size()-1; i>=0; i--) {
12013            if ((ris.get(i).activityInfo.applicationInfo.flags
12014                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
12015                ris.remove(i);
12016            }
12017        }
12018        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12019
12020        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12021        for (int i=0; i<ris.size(); i++) {
12022            ActivityInfo ai = ris.get(i).activityInfo;
12023            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12024            if (lastDoneReceivers.contains(comp)) {
12025                // We already did the pre boot receiver for this app with the current
12026                // platform version, so don't do it again...
12027                ris.remove(i);
12028                i--;
12029                // ...however, do keep it as one that has been done, so we don't
12030                // forget about it when rewriting the file of last done receivers.
12031                doneReceivers.add(comp);
12032            }
12033        }
12034
12035        if (ris.size() <= 0) {
12036            return false;
12037        }
12038
12039        // TODO: can we still do this with per user encryption?
12040        final int[] users = mUserController.getUsers();
12041        if (users.length <= 0) {
12042            return false;
12043        }
12044
12045        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12046                ris, users);
12047        cont.go();
12048        return true;
12049    }
12050
12051    public void systemReady(final Runnable goingCallback) {
12052        synchronized(this) {
12053            if (mSystemReady) {
12054                // If we're done calling all the receivers, run the next "boot phase" passed in
12055                // by the SystemServer
12056                if (goingCallback != null) {
12057                    goingCallback.run();
12058                }
12059                return;
12060            }
12061
12062            mLocalDeviceIdleController
12063                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12064
12065            // Make sure we have the current profile info, since it is needed for
12066            // security checks.
12067            mUserController.updateCurrentProfileIdsLocked();
12068
12069            mRecentTasks.clear();
12070            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12071            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12072            mTaskPersister.startPersisting();
12073
12074            // Check to see if there are any update receivers to run.
12075            if (!mDidUpdate) {
12076                if (mWaitingUpdate) {
12077                    return;
12078                }
12079                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12080                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12081                    public void run() {
12082                        synchronized (ActivityManagerService.this) {
12083                            mDidUpdate = true;
12084                        }
12085                        showBootMessage(mContext.getText(
12086                                R.string.android_upgrading_complete),
12087                                false);
12088                        writeLastDonePreBootReceivers(doneReceivers);
12089                        systemReady(goingCallback);
12090                    }
12091                }, doneReceivers);
12092
12093                if (mWaitingUpdate) {
12094                    return;
12095                }
12096                mDidUpdate = true;
12097            }
12098
12099            mAppOpsService.systemReady();
12100            mSystemReady = true;
12101        }
12102
12103        ArrayList<ProcessRecord> procsToKill = null;
12104        synchronized(mPidsSelfLocked) {
12105            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12106                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12107                if (!isAllowedWhileBooting(proc.info)){
12108                    if (procsToKill == null) {
12109                        procsToKill = new ArrayList<ProcessRecord>();
12110                    }
12111                    procsToKill.add(proc);
12112                }
12113            }
12114        }
12115
12116        synchronized(this) {
12117            if (procsToKill != null) {
12118                for (int i=procsToKill.size()-1; i>=0; i--) {
12119                    ProcessRecord proc = procsToKill.get(i);
12120                    Slog.i(TAG, "Removing system update proc: " + proc);
12121                    removeProcessLocked(proc, true, false, "system update done");
12122                }
12123            }
12124
12125            // Now that we have cleaned up any update processes, we
12126            // are ready to start launching real processes and know that
12127            // we won't trample on them any more.
12128            mProcessesReady = true;
12129        }
12130
12131        Slog.i(TAG, "System now ready");
12132        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12133            SystemClock.uptimeMillis());
12134
12135        synchronized(this) {
12136            // Make sure we have no pre-ready processes sitting around.
12137
12138            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12139                ResolveInfo ri = mContext.getPackageManager()
12140                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12141                                STOCK_PM_FLAGS);
12142                CharSequence errorMsg = null;
12143                if (ri != null) {
12144                    ActivityInfo ai = ri.activityInfo;
12145                    ApplicationInfo app = ai.applicationInfo;
12146                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12147                        mTopAction = Intent.ACTION_FACTORY_TEST;
12148                        mTopData = null;
12149                        mTopComponent = new ComponentName(app.packageName,
12150                                ai.name);
12151                    } else {
12152                        errorMsg = mContext.getResources().getText(
12153                                com.android.internal.R.string.factorytest_not_system);
12154                    }
12155                } else {
12156                    errorMsg = mContext.getResources().getText(
12157                            com.android.internal.R.string.factorytest_no_action);
12158                }
12159                if (errorMsg != null) {
12160                    mTopAction = null;
12161                    mTopData = null;
12162                    mTopComponent = null;
12163                    Message msg = Message.obtain();
12164                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12165                    msg.getData().putCharSequence("msg", errorMsg);
12166                    mUiHandler.sendMessage(msg);
12167                }
12168            }
12169        }
12170
12171        retrieveSettings();
12172        loadResourcesOnSystemReady();
12173        final int currentUserId;
12174        synchronized (this) {
12175            currentUserId = mUserController.getCurrentUserIdLocked();
12176            readGrantedUriPermissionsLocked();
12177        }
12178
12179        if (goingCallback != null) goingCallback.run();
12180
12181
12182        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12183                Integer.toString(currentUserId), currentUserId);
12184        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12185                Integer.toString(currentUserId), currentUserId);
12186        mSystemServiceManager.startUser(currentUserId);
12187
12188        synchronized (this) {
12189            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12190                try {
12191                    List apps = AppGlobals.getPackageManager().
12192                        getPersistentApplications(STOCK_PM_FLAGS);
12193                    if (apps != null) {
12194                        int N = apps.size();
12195                        int i;
12196                        for (i=0; i<N; i++) {
12197                            ApplicationInfo info
12198                                = (ApplicationInfo)apps.get(i);
12199                            if (info != null &&
12200                                    !info.packageName.equals("android")) {
12201                                addAppLocked(info, false, null /* ABI override */);
12202                            }
12203                        }
12204                    }
12205                } catch (RemoteException ex) {
12206                    // pm is in same process, this will never happen.
12207                }
12208            }
12209
12210            // Start up initial activity.
12211            mBooting = true;
12212            startHomeActivityLocked(currentUserId, "systemReady");
12213
12214            try {
12215                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12216                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12217                            + " data partition or your device will be unstable.");
12218                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12219                }
12220            } catch (RemoteException e) {
12221            }
12222
12223            if (!Build.isBuildConsistent()) {
12224                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12225                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12226            }
12227
12228            long ident = Binder.clearCallingIdentity();
12229            try {
12230                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12231                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12232                        | Intent.FLAG_RECEIVER_FOREGROUND);
12233                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12234                broadcastIntentLocked(null, null, intent,
12235                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12236                        null, false, false, MY_PID, Process.SYSTEM_UID,
12237                        currentUserId);
12238                intent = new Intent(Intent.ACTION_USER_STARTING);
12239                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12240                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12241                broadcastIntentLocked(null, null, intent,
12242                        null, new IIntentReceiver.Stub() {
12243                            @Override
12244                            public void performReceive(Intent intent, int resultCode, String data,
12245                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12246                                    throws RemoteException {
12247                            }
12248                        }, 0, null, null,
12249                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12250                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12251            } catch (Throwable t) {
12252                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12253            } finally {
12254                Binder.restoreCallingIdentity(ident);
12255            }
12256            mStackSupervisor.resumeTopActivitiesLocked();
12257            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12258        }
12259    }
12260
12261    private boolean makeAppCrashingLocked(ProcessRecord app,
12262            String shortMsg, String longMsg, String stackTrace) {
12263        app.crashing = true;
12264        app.crashingReport = generateProcessError(app,
12265                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12266        startAppProblemLocked(app);
12267        app.stopFreezingAllLocked();
12268        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12269    }
12270
12271    private void makeAppNotRespondingLocked(ProcessRecord app,
12272            String activity, String shortMsg, String longMsg) {
12273        app.notResponding = true;
12274        app.notRespondingReport = generateProcessError(app,
12275                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12276                activity, shortMsg, longMsg, null);
12277        startAppProblemLocked(app);
12278        app.stopFreezingAllLocked();
12279    }
12280
12281    /**
12282     * Generate a process error record, suitable for attachment to a ProcessRecord.
12283     *
12284     * @param app The ProcessRecord in which the error occurred.
12285     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12286     *                      ActivityManager.AppErrorStateInfo
12287     * @param activity The activity associated with the crash, if known.
12288     * @param shortMsg Short message describing the crash.
12289     * @param longMsg Long message describing the crash.
12290     * @param stackTrace Full crash stack trace, may be null.
12291     *
12292     * @return Returns a fully-formed AppErrorStateInfo record.
12293     */
12294    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12295            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12296        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12297
12298        report.condition = condition;
12299        report.processName = app.processName;
12300        report.pid = app.pid;
12301        report.uid = app.info.uid;
12302        report.tag = activity;
12303        report.shortMsg = shortMsg;
12304        report.longMsg = longMsg;
12305        report.stackTrace = stackTrace;
12306
12307        return report;
12308    }
12309
12310    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12311        synchronized (this) {
12312            app.crashing = false;
12313            app.crashingReport = null;
12314            app.notResponding = false;
12315            app.notRespondingReport = null;
12316            if (app.anrDialog == fromDialog) {
12317                app.anrDialog = null;
12318            }
12319            if (app.waitDialog == fromDialog) {
12320                app.waitDialog = null;
12321            }
12322            if (app.pid > 0 && app.pid != MY_PID) {
12323                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12324                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12325                app.kill("user request after error", true);
12326            }
12327        }
12328    }
12329
12330    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12331            String shortMsg, String longMsg, String stackTrace) {
12332        long now = SystemClock.uptimeMillis();
12333
12334        Long crashTime;
12335        if (!app.isolated) {
12336            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12337        } else {
12338            crashTime = null;
12339        }
12340        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12341            // This process loses!
12342            Slog.w(TAG, "Process " + app.info.processName
12343                    + " has crashed too many times: killing!");
12344            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12345                    app.userId, app.info.processName, app.uid);
12346            mStackSupervisor.handleAppCrashLocked(app);
12347            if (!app.persistent) {
12348                // We don't want to start this process again until the user
12349                // explicitly does so...  but for persistent process, we really
12350                // need to keep it running.  If a persistent process is actually
12351                // repeatedly crashing, then badness for everyone.
12352                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12353                        app.info.processName);
12354                if (!app.isolated) {
12355                    // XXX We don't have a way to mark isolated processes
12356                    // as bad, since they don't have a peristent identity.
12357                    mBadProcesses.put(app.info.processName, app.uid,
12358                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12359                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12360                }
12361                app.bad = true;
12362                app.removed = true;
12363                // Don't let services in this process be restarted and potentially
12364                // annoy the user repeatedly.  Unless it is persistent, since those
12365                // processes run critical code.
12366                removeProcessLocked(app, false, false, "crash");
12367                mStackSupervisor.resumeTopActivitiesLocked();
12368                return false;
12369            }
12370            mStackSupervisor.resumeTopActivitiesLocked();
12371        } else {
12372            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12373        }
12374
12375        // Bump up the crash count of any services currently running in the proc.
12376        for (int i=app.services.size()-1; i>=0; i--) {
12377            // Any services running in the application need to be placed
12378            // back in the pending list.
12379            ServiceRecord sr = app.services.valueAt(i);
12380            sr.crashCount++;
12381        }
12382
12383        // If the crashing process is what we consider to be the "home process" and it has been
12384        // replaced by a third-party app, clear the package preferred activities from packages
12385        // with a home activity running in the process to prevent a repeatedly crashing app
12386        // from blocking the user to manually clear the list.
12387        final ArrayList<ActivityRecord> activities = app.activities;
12388        if (app == mHomeProcess && activities.size() > 0
12389                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12390            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12391                final ActivityRecord r = activities.get(activityNdx);
12392                if (r.isHomeActivity()) {
12393                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12394                    try {
12395                        ActivityThread.getPackageManager()
12396                                .clearPackagePreferredActivities(r.packageName);
12397                    } catch (RemoteException c) {
12398                        // pm is in same process, this will never happen.
12399                    }
12400                }
12401            }
12402        }
12403
12404        if (!app.isolated) {
12405            // XXX Can't keep track of crash times for isolated processes,
12406            // because they don't have a perisistent identity.
12407            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12408        }
12409
12410        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12411        return true;
12412    }
12413
12414    void startAppProblemLocked(ProcessRecord app) {
12415        // If this app is not running under the current user, then we
12416        // can't give it a report button because that would require
12417        // launching the report UI under a different user.
12418        app.errorReportReceiver = null;
12419
12420        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12421            if (app.userId == userId) {
12422                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12423                        mContext, app.info.packageName, app.info.flags);
12424            }
12425        }
12426        skipCurrentReceiverLocked(app);
12427    }
12428
12429    void skipCurrentReceiverLocked(ProcessRecord app) {
12430        for (BroadcastQueue queue : mBroadcastQueues) {
12431            queue.skipCurrentReceiverLocked(app);
12432        }
12433    }
12434
12435    /**
12436     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12437     * The application process will exit immediately after this call returns.
12438     * @param app object of the crashing app, null for the system server
12439     * @param crashInfo describing the exception
12440     */
12441    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12442        ProcessRecord r = findAppProcess(app, "Crash");
12443        final String processName = app == null ? "system_server"
12444                : (r == null ? "unknown" : r.processName);
12445
12446        handleApplicationCrashInner("crash", r, processName, crashInfo);
12447    }
12448
12449    /* Native crash reporting uses this inner version because it needs to be somewhat
12450     * decoupled from the AM-managed cleanup lifecycle
12451     */
12452    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12453            ApplicationErrorReport.CrashInfo crashInfo) {
12454        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12455                UserHandle.getUserId(Binder.getCallingUid()), processName,
12456                r == null ? -1 : r.info.flags,
12457                crashInfo.exceptionClassName,
12458                crashInfo.exceptionMessage,
12459                crashInfo.throwFileName,
12460                crashInfo.throwLineNumber);
12461
12462        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12463
12464        crashApplication(r, crashInfo);
12465    }
12466
12467    public void handleApplicationStrictModeViolation(
12468            IBinder app,
12469            int violationMask,
12470            StrictMode.ViolationInfo info) {
12471        ProcessRecord r = findAppProcess(app, "StrictMode");
12472        if (r == null) {
12473            return;
12474        }
12475
12476        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12477            Integer stackFingerprint = info.hashCode();
12478            boolean logIt = true;
12479            synchronized (mAlreadyLoggedViolatedStacks) {
12480                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12481                    logIt = false;
12482                    // TODO: sub-sample into EventLog for these, with
12483                    // the info.durationMillis?  Then we'd get
12484                    // the relative pain numbers, without logging all
12485                    // the stack traces repeatedly.  We'd want to do
12486                    // likewise in the client code, which also does
12487                    // dup suppression, before the Binder call.
12488                } else {
12489                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12490                        mAlreadyLoggedViolatedStacks.clear();
12491                    }
12492                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12493                }
12494            }
12495            if (logIt) {
12496                logStrictModeViolationToDropBox(r, info);
12497            }
12498        }
12499
12500        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12501            AppErrorResult result = new AppErrorResult();
12502            synchronized (this) {
12503                final long origId = Binder.clearCallingIdentity();
12504
12505                Message msg = Message.obtain();
12506                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12507                HashMap<String, Object> data = new HashMap<String, Object>();
12508                data.put("result", result);
12509                data.put("app", r);
12510                data.put("violationMask", violationMask);
12511                data.put("info", info);
12512                msg.obj = data;
12513                mUiHandler.sendMessage(msg);
12514
12515                Binder.restoreCallingIdentity(origId);
12516            }
12517            int res = result.get();
12518            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12519        }
12520    }
12521
12522    // Depending on the policy in effect, there could be a bunch of
12523    // these in quick succession so we try to batch these together to
12524    // minimize disk writes, number of dropbox entries, and maximize
12525    // compression, by having more fewer, larger records.
12526    private void logStrictModeViolationToDropBox(
12527            ProcessRecord process,
12528            StrictMode.ViolationInfo info) {
12529        if (info == null) {
12530            return;
12531        }
12532        final boolean isSystemApp = process == null ||
12533                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12534                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12535        final String processName = process == null ? "unknown" : process.processName;
12536        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12537        final DropBoxManager dbox = (DropBoxManager)
12538                mContext.getSystemService(Context.DROPBOX_SERVICE);
12539
12540        // Exit early if the dropbox isn't configured to accept this report type.
12541        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12542
12543        boolean bufferWasEmpty;
12544        boolean needsFlush;
12545        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12546        synchronized (sb) {
12547            bufferWasEmpty = sb.length() == 0;
12548            appendDropBoxProcessHeaders(process, processName, sb);
12549            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12550            sb.append("System-App: ").append(isSystemApp).append("\n");
12551            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12552            if (info.violationNumThisLoop != 0) {
12553                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12554            }
12555            if (info.numAnimationsRunning != 0) {
12556                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12557            }
12558            if (info.broadcastIntentAction != null) {
12559                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12560            }
12561            if (info.durationMillis != -1) {
12562                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12563            }
12564            if (info.numInstances != -1) {
12565                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12566            }
12567            if (info.tags != null) {
12568                for (String tag : info.tags) {
12569                    sb.append("Span-Tag: ").append(tag).append("\n");
12570                }
12571            }
12572            sb.append("\n");
12573            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12574                sb.append(info.crashInfo.stackTrace);
12575                sb.append("\n");
12576            }
12577            if (info.message != null) {
12578                sb.append(info.message);
12579                sb.append("\n");
12580            }
12581
12582            // Only buffer up to ~64k.  Various logging bits truncate
12583            // things at 128k.
12584            needsFlush = (sb.length() > 64 * 1024);
12585        }
12586
12587        // Flush immediately if the buffer's grown too large, or this
12588        // is a non-system app.  Non-system apps are isolated with a
12589        // different tag & policy and not batched.
12590        //
12591        // Batching is useful during internal testing with
12592        // StrictMode settings turned up high.  Without batching,
12593        // thousands of separate files could be created on boot.
12594        if (!isSystemApp || needsFlush) {
12595            new Thread("Error dump: " + dropboxTag) {
12596                @Override
12597                public void run() {
12598                    String report;
12599                    synchronized (sb) {
12600                        report = sb.toString();
12601                        sb.delete(0, sb.length());
12602                        sb.trimToSize();
12603                    }
12604                    if (report.length() != 0) {
12605                        dbox.addText(dropboxTag, report);
12606                    }
12607                }
12608            }.start();
12609            return;
12610        }
12611
12612        // System app batching:
12613        if (!bufferWasEmpty) {
12614            // An existing dropbox-writing thread is outstanding, so
12615            // we don't need to start it up.  The existing thread will
12616            // catch the buffer appends we just did.
12617            return;
12618        }
12619
12620        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12621        // (After this point, we shouldn't access AMS internal data structures.)
12622        new Thread("Error dump: " + dropboxTag) {
12623            @Override
12624            public void run() {
12625                // 5 second sleep to let stacks arrive and be batched together
12626                try {
12627                    Thread.sleep(5000);  // 5 seconds
12628                } catch (InterruptedException e) {}
12629
12630                String errorReport;
12631                synchronized (mStrictModeBuffer) {
12632                    errorReport = mStrictModeBuffer.toString();
12633                    if (errorReport.length() == 0) {
12634                        return;
12635                    }
12636                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12637                    mStrictModeBuffer.trimToSize();
12638                }
12639                dbox.addText(dropboxTag, errorReport);
12640            }
12641        }.start();
12642    }
12643
12644    /**
12645     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12646     * @param app object of the crashing app, null for the system server
12647     * @param tag reported by the caller
12648     * @param system whether this wtf is coming from the system
12649     * @param crashInfo describing the context of the error
12650     * @return true if the process should exit immediately (WTF is fatal)
12651     */
12652    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12653            final ApplicationErrorReport.CrashInfo crashInfo) {
12654        final int callingUid = Binder.getCallingUid();
12655        final int callingPid = Binder.getCallingPid();
12656
12657        if (system) {
12658            // If this is coming from the system, we could very well have low-level
12659            // system locks held, so we want to do this all asynchronously.  And we
12660            // never want this to become fatal, so there is that too.
12661            mHandler.post(new Runnable() {
12662                @Override public void run() {
12663                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12664                }
12665            });
12666            return false;
12667        }
12668
12669        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12670                crashInfo);
12671
12672        if (r != null && r.pid != Process.myPid() &&
12673                Settings.Global.getInt(mContext.getContentResolver(),
12674                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12675            crashApplication(r, crashInfo);
12676            return true;
12677        } else {
12678            return false;
12679        }
12680    }
12681
12682    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12683            final ApplicationErrorReport.CrashInfo crashInfo) {
12684        final ProcessRecord r = findAppProcess(app, "WTF");
12685        final String processName = app == null ? "system_server"
12686                : (r == null ? "unknown" : r.processName);
12687
12688        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12689                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12690
12691        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12692
12693        return r;
12694    }
12695
12696    /**
12697     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12698     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12699     */
12700    private ProcessRecord findAppProcess(IBinder app, String reason) {
12701        if (app == null) {
12702            return null;
12703        }
12704
12705        synchronized (this) {
12706            final int NP = mProcessNames.getMap().size();
12707            for (int ip=0; ip<NP; ip++) {
12708                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12709                final int NA = apps.size();
12710                for (int ia=0; ia<NA; ia++) {
12711                    ProcessRecord p = apps.valueAt(ia);
12712                    if (p.thread != null && p.thread.asBinder() == app) {
12713                        return p;
12714                    }
12715                }
12716            }
12717
12718            Slog.w(TAG, "Can't find mystery application for " + reason
12719                    + " from pid=" + Binder.getCallingPid()
12720                    + " uid=" + Binder.getCallingUid() + ": " + app);
12721            return null;
12722        }
12723    }
12724
12725    /**
12726     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12727     * to append various headers to the dropbox log text.
12728     */
12729    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12730            StringBuilder sb) {
12731        // Watchdog thread ends up invoking this function (with
12732        // a null ProcessRecord) to add the stack file to dropbox.
12733        // Do not acquire a lock on this (am) in such cases, as it
12734        // could cause a potential deadlock, if and when watchdog
12735        // is invoked due to unavailability of lock on am and it
12736        // would prevent watchdog from killing system_server.
12737        if (process == null) {
12738            sb.append("Process: ").append(processName).append("\n");
12739            return;
12740        }
12741        // Note: ProcessRecord 'process' is guarded by the service
12742        // instance.  (notably process.pkgList, which could otherwise change
12743        // concurrently during execution of this method)
12744        synchronized (this) {
12745            sb.append("Process: ").append(processName).append("\n");
12746            int flags = process.info.flags;
12747            IPackageManager pm = AppGlobals.getPackageManager();
12748            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12749            for (int ip=0; ip<process.pkgList.size(); ip++) {
12750                String pkg = process.pkgList.keyAt(ip);
12751                sb.append("Package: ").append(pkg);
12752                try {
12753                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12754                    if (pi != null) {
12755                        sb.append(" v").append(pi.versionCode);
12756                        if (pi.versionName != null) {
12757                            sb.append(" (").append(pi.versionName).append(")");
12758                        }
12759                    }
12760                } catch (RemoteException e) {
12761                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12762                }
12763                sb.append("\n");
12764            }
12765        }
12766    }
12767
12768    private static String processClass(ProcessRecord process) {
12769        if (process == null || process.pid == MY_PID) {
12770            return "system_server";
12771        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12772            return "system_app";
12773        } else {
12774            return "data_app";
12775        }
12776    }
12777
12778    /**
12779     * Write a description of an error (crash, WTF, ANR) to the drop box.
12780     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12781     * @param process which caused the error, null means the system server
12782     * @param activity which triggered the error, null if unknown
12783     * @param parent activity related to the error, null if unknown
12784     * @param subject line related to the error, null if absent
12785     * @param report in long form describing the error, null if absent
12786     * @param logFile to include in the report, null if none
12787     * @param crashInfo giving an application stack trace, null if absent
12788     */
12789    public void addErrorToDropBox(String eventType,
12790            ProcessRecord process, String processName, ActivityRecord activity,
12791            ActivityRecord parent, String subject,
12792            final String report, final File logFile,
12793            final ApplicationErrorReport.CrashInfo crashInfo) {
12794        // NOTE -- this must never acquire the ActivityManagerService lock,
12795        // otherwise the watchdog may be prevented from resetting the system.
12796
12797        final String dropboxTag = processClass(process) + "_" + eventType;
12798        final DropBoxManager dbox = (DropBoxManager)
12799                mContext.getSystemService(Context.DROPBOX_SERVICE);
12800
12801        // Exit early if the dropbox isn't configured to accept this report type.
12802        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12803
12804        final StringBuilder sb = new StringBuilder(1024);
12805        appendDropBoxProcessHeaders(process, processName, sb);
12806        if (activity != null) {
12807            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12808        }
12809        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12810            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12811        }
12812        if (parent != null && parent != activity) {
12813            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12814        }
12815        if (subject != null) {
12816            sb.append("Subject: ").append(subject).append("\n");
12817        }
12818        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12819        if (Debug.isDebuggerConnected()) {
12820            sb.append("Debugger: Connected\n");
12821        }
12822        sb.append("\n");
12823
12824        // Do the rest in a worker thread to avoid blocking the caller on I/O
12825        // (After this point, we shouldn't access AMS internal data structures.)
12826        Thread worker = new Thread("Error dump: " + dropboxTag) {
12827            @Override
12828            public void run() {
12829                if (report != null) {
12830                    sb.append(report);
12831                }
12832                if (logFile != null) {
12833                    try {
12834                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12835                                    "\n\n[[TRUNCATED]]"));
12836                    } catch (IOException e) {
12837                        Slog.e(TAG, "Error reading " + logFile, e);
12838                    }
12839                }
12840                if (crashInfo != null && crashInfo.stackTrace != null) {
12841                    sb.append(crashInfo.stackTrace);
12842                }
12843
12844                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12845                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12846                if (lines > 0) {
12847                    sb.append("\n");
12848
12849                    // Merge several logcat streams, and take the last N lines
12850                    InputStreamReader input = null;
12851                    try {
12852                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12853                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12854                                "-b", "crash",
12855                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12856
12857                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12858                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12859                        input = new InputStreamReader(logcat.getInputStream());
12860
12861                        int num;
12862                        char[] buf = new char[8192];
12863                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12864                    } catch (IOException e) {
12865                        Slog.e(TAG, "Error running logcat", e);
12866                    } finally {
12867                        if (input != null) try { input.close(); } catch (IOException e) {}
12868                    }
12869                }
12870
12871                dbox.addText(dropboxTag, sb.toString());
12872            }
12873        };
12874
12875        if (process == null) {
12876            // If process is null, we are being called from some internal code
12877            // and may be about to die -- run this synchronously.
12878            worker.run();
12879        } else {
12880            worker.start();
12881        }
12882    }
12883
12884    /**
12885     * Bring up the "unexpected error" dialog box for a crashing app.
12886     * Deal with edge cases (intercepts from instrumented applications,
12887     * ActivityController, error intent receivers, that sort of thing).
12888     * @param r the application crashing
12889     * @param crashInfo describing the failure
12890     */
12891    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12892        long timeMillis = System.currentTimeMillis();
12893        String shortMsg = crashInfo.exceptionClassName;
12894        String longMsg = crashInfo.exceptionMessage;
12895        String stackTrace = crashInfo.stackTrace;
12896        if (shortMsg != null && longMsg != null) {
12897            longMsg = shortMsg + ": " + longMsg;
12898        } else if (shortMsg != null) {
12899            longMsg = shortMsg;
12900        }
12901
12902        AppErrorResult result = new AppErrorResult();
12903        synchronized (this) {
12904            if (mController != null) {
12905                try {
12906                    String name = r != null ? r.processName : null;
12907                    int pid = r != null ? r.pid : Binder.getCallingPid();
12908                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12909                    if (!mController.appCrashed(name, pid,
12910                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12911                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12912                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12913                            Slog.w(TAG, "Skip killing native crashed app " + name
12914                                    + "(" + pid + ") during testing");
12915                        } else {
12916                            Slog.w(TAG, "Force-killing crashed app " + name
12917                                    + " at watcher's request");
12918                            if (r != null) {
12919                                r.kill("crash", true);
12920                            } else {
12921                                // Huh.
12922                                Process.killProcess(pid);
12923                                killProcessGroup(uid, pid);
12924                            }
12925                        }
12926                        return;
12927                    }
12928                } catch (RemoteException e) {
12929                    mController = null;
12930                    Watchdog.getInstance().setActivityController(null);
12931                }
12932            }
12933
12934            final long origId = Binder.clearCallingIdentity();
12935
12936            // If this process is running instrumentation, finish it.
12937            if (r != null && r.instrumentationClass != null) {
12938                Slog.w(TAG, "Error in app " + r.processName
12939                      + " running instrumentation " + r.instrumentationClass + ":");
12940                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12941                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12942                Bundle info = new Bundle();
12943                info.putString("shortMsg", shortMsg);
12944                info.putString("longMsg", longMsg);
12945                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12946                Binder.restoreCallingIdentity(origId);
12947                return;
12948            }
12949
12950            // Log crash in battery stats.
12951            if (r != null) {
12952                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12953            }
12954
12955            // If we can't identify the process or it's already exceeded its crash quota,
12956            // quit right away without showing a crash dialog.
12957            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12958                Binder.restoreCallingIdentity(origId);
12959                return;
12960            }
12961
12962            Message msg = Message.obtain();
12963            msg.what = SHOW_ERROR_UI_MSG;
12964            HashMap data = new HashMap();
12965            data.put("result", result);
12966            data.put("app", r);
12967            msg.obj = data;
12968            mUiHandler.sendMessage(msg);
12969
12970            Binder.restoreCallingIdentity(origId);
12971        }
12972
12973        int res = result.get();
12974
12975        Intent appErrorIntent = null;
12976        synchronized (this) {
12977            if (r != null && !r.isolated) {
12978                // XXX Can't keep track of crash time for isolated processes,
12979                // since they don't have a persistent identity.
12980                mProcessCrashTimes.put(r.info.processName, r.uid,
12981                        SystemClock.uptimeMillis());
12982            }
12983            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12984                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12985            }
12986        }
12987
12988        if (appErrorIntent != null) {
12989            try {
12990                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12991            } catch (ActivityNotFoundException e) {
12992                Slog.w(TAG, "bug report receiver dissappeared", e);
12993            }
12994        }
12995    }
12996
12997    Intent createAppErrorIntentLocked(ProcessRecord r,
12998            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12999        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13000        if (report == null) {
13001            return null;
13002        }
13003        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13004        result.setComponent(r.errorReportReceiver);
13005        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13006        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13007        return result;
13008    }
13009
13010    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13011            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13012        if (r.errorReportReceiver == null) {
13013            return null;
13014        }
13015
13016        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13017            return null;
13018        }
13019
13020        ApplicationErrorReport report = new ApplicationErrorReport();
13021        report.packageName = r.info.packageName;
13022        report.installerPackageName = r.errorReportReceiver.getPackageName();
13023        report.processName = r.processName;
13024        report.time = timeMillis;
13025        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13026
13027        if (r.crashing || r.forceCrashReport) {
13028            report.type = ApplicationErrorReport.TYPE_CRASH;
13029            report.crashInfo = crashInfo;
13030        } else if (r.notResponding) {
13031            report.type = ApplicationErrorReport.TYPE_ANR;
13032            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13033
13034            report.anrInfo.activity = r.notRespondingReport.tag;
13035            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13036            report.anrInfo.info = r.notRespondingReport.longMsg;
13037        }
13038
13039        return report;
13040    }
13041
13042    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13043        enforceNotIsolatedCaller("getProcessesInErrorState");
13044        // assume our apps are happy - lazy create the list
13045        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13046
13047        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13048                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13049        int userId = UserHandle.getUserId(Binder.getCallingUid());
13050
13051        synchronized (this) {
13052
13053            // iterate across all processes
13054            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13055                ProcessRecord app = mLruProcesses.get(i);
13056                if (!allUsers && app.userId != userId) {
13057                    continue;
13058                }
13059                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13060                    // This one's in trouble, so we'll generate a report for it
13061                    // crashes are higher priority (in case there's a crash *and* an anr)
13062                    ActivityManager.ProcessErrorStateInfo report = null;
13063                    if (app.crashing) {
13064                        report = app.crashingReport;
13065                    } else if (app.notResponding) {
13066                        report = app.notRespondingReport;
13067                    }
13068
13069                    if (report != null) {
13070                        if (errList == null) {
13071                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13072                        }
13073                        errList.add(report);
13074                    } else {
13075                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13076                                " crashing = " + app.crashing +
13077                                " notResponding = " + app.notResponding);
13078                    }
13079                }
13080            }
13081        }
13082
13083        return errList;
13084    }
13085
13086    static int procStateToImportance(int procState, int memAdj,
13087            ActivityManager.RunningAppProcessInfo currApp) {
13088        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13089        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13090            currApp.lru = memAdj;
13091        } else {
13092            currApp.lru = 0;
13093        }
13094        return imp;
13095    }
13096
13097    private void fillInProcMemInfo(ProcessRecord app,
13098            ActivityManager.RunningAppProcessInfo outInfo) {
13099        outInfo.pid = app.pid;
13100        outInfo.uid = app.info.uid;
13101        if (mHeavyWeightProcess == app) {
13102            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13103        }
13104        if (app.persistent) {
13105            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13106        }
13107        if (app.activities.size() > 0) {
13108            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13109        }
13110        outInfo.lastTrimLevel = app.trimMemoryLevel;
13111        int adj = app.curAdj;
13112        int procState = app.curProcState;
13113        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13114        outInfo.importanceReasonCode = app.adjTypeCode;
13115        outInfo.processState = app.curProcState;
13116    }
13117
13118    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13119        enforceNotIsolatedCaller("getRunningAppProcesses");
13120
13121        final int callingUid = Binder.getCallingUid();
13122
13123        // Lazy instantiation of list
13124        List<ActivityManager.RunningAppProcessInfo> runList = null;
13125        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13126                callingUid) == PackageManager.PERMISSION_GRANTED;
13127        final int userId = UserHandle.getUserId(callingUid);
13128        final boolean allUids = isGetTasksAllowed(
13129                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13130
13131        synchronized (this) {
13132            // Iterate across all processes
13133            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13134                ProcessRecord app = mLruProcesses.get(i);
13135                if ((!allUsers && app.userId != userId)
13136                        || (!allUids && app.uid != callingUid)) {
13137                    continue;
13138                }
13139                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13140                    // Generate process state info for running application
13141                    ActivityManager.RunningAppProcessInfo currApp =
13142                        new ActivityManager.RunningAppProcessInfo(app.processName,
13143                                app.pid, app.getPackageList());
13144                    fillInProcMemInfo(app, currApp);
13145                    if (app.adjSource instanceof ProcessRecord) {
13146                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13147                        currApp.importanceReasonImportance =
13148                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13149                                        app.adjSourceProcState);
13150                    } else if (app.adjSource instanceof ActivityRecord) {
13151                        ActivityRecord r = (ActivityRecord)app.adjSource;
13152                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13153                    }
13154                    if (app.adjTarget instanceof ComponentName) {
13155                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13156                    }
13157                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13158                    //        + " lru=" + currApp.lru);
13159                    if (runList == null) {
13160                        runList = new ArrayList<>();
13161                    }
13162                    runList.add(currApp);
13163                }
13164            }
13165        }
13166        return runList;
13167    }
13168
13169    public List<ApplicationInfo> getRunningExternalApplications() {
13170        enforceNotIsolatedCaller("getRunningExternalApplications");
13171        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13172        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13173        if (runningApps != null && runningApps.size() > 0) {
13174            Set<String> extList = new HashSet<String>();
13175            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13176                if (app.pkgList != null) {
13177                    for (String pkg : app.pkgList) {
13178                        extList.add(pkg);
13179                    }
13180                }
13181            }
13182            IPackageManager pm = AppGlobals.getPackageManager();
13183            for (String pkg : extList) {
13184                try {
13185                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13186                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13187                        retList.add(info);
13188                    }
13189                } catch (RemoteException e) {
13190                }
13191            }
13192        }
13193        return retList;
13194    }
13195
13196    @Override
13197    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13198        enforceNotIsolatedCaller("getMyMemoryState");
13199        synchronized (this) {
13200            ProcessRecord proc;
13201            synchronized (mPidsSelfLocked) {
13202                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13203            }
13204            fillInProcMemInfo(proc, outInfo);
13205        }
13206    }
13207
13208    @Override
13209    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13210            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13211        (new ActivityManagerShellCommand(this, false)).exec(
13212                this, in, out, err, args, resultReceiver);
13213    }
13214
13215    @Override
13216    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13217        if (checkCallingPermission(android.Manifest.permission.DUMP)
13218                != PackageManager.PERMISSION_GRANTED) {
13219            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13220                    + Binder.getCallingPid()
13221                    + ", uid=" + Binder.getCallingUid()
13222                    + " without permission "
13223                    + android.Manifest.permission.DUMP);
13224            return;
13225        }
13226
13227        boolean dumpAll = false;
13228        boolean dumpClient = false;
13229        String dumpPackage = null;
13230
13231        int opti = 0;
13232        while (opti < args.length) {
13233            String opt = args[opti];
13234            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13235                break;
13236            }
13237            opti++;
13238            if ("-a".equals(opt)) {
13239                dumpAll = true;
13240            } else if ("-c".equals(opt)) {
13241                dumpClient = true;
13242            } else if ("-p".equals(opt)) {
13243                if (opti < args.length) {
13244                    dumpPackage = args[opti];
13245                    opti++;
13246                } else {
13247                    pw.println("Error: -p option requires package argument");
13248                    return;
13249                }
13250                dumpClient = true;
13251            } else if ("-h".equals(opt)) {
13252                ActivityManagerShellCommand.dumpHelp(pw, true);
13253                return;
13254            } else {
13255                pw.println("Unknown argument: " + opt + "; use -h for help");
13256            }
13257        }
13258
13259        long origId = Binder.clearCallingIdentity();
13260        boolean more = false;
13261        // Is the caller requesting to dump a particular piece of data?
13262        if (opti < args.length) {
13263            String cmd = args[opti];
13264            opti++;
13265            if ("activities".equals(cmd) || "a".equals(cmd)) {
13266                synchronized (this) {
13267                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13268                }
13269            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13270                synchronized (this) {
13271                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13272                }
13273            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13274                String[] newArgs;
13275                String name;
13276                if (opti >= args.length) {
13277                    name = null;
13278                    newArgs = EMPTY_STRING_ARRAY;
13279                } else {
13280                    dumpPackage = args[opti];
13281                    opti++;
13282                    newArgs = new String[args.length - opti];
13283                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13284                            args.length - opti);
13285                }
13286                synchronized (this) {
13287                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13288                }
13289            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13290                String[] newArgs;
13291                String name;
13292                if (opti >= args.length) {
13293                    name = null;
13294                    newArgs = EMPTY_STRING_ARRAY;
13295                } else {
13296                    dumpPackage = args[opti];
13297                    opti++;
13298                    newArgs = new String[args.length - opti];
13299                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13300                            args.length - opti);
13301                }
13302                synchronized (this) {
13303                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13304                }
13305            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13306                String[] newArgs;
13307                String name;
13308                if (opti >= args.length) {
13309                    name = null;
13310                    newArgs = EMPTY_STRING_ARRAY;
13311                } else {
13312                    dumpPackage = args[opti];
13313                    opti++;
13314                    newArgs = new String[args.length - opti];
13315                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13316                            args.length - opti);
13317                }
13318                synchronized (this) {
13319                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13320                }
13321            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13322                synchronized (this) {
13323                    dumpOomLocked(fd, pw, args, opti, true);
13324                }
13325            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13326                synchronized (this) {
13327                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13328                }
13329            } else if ("provider".equals(cmd)) {
13330                String[] newArgs;
13331                String name;
13332                if (opti >= args.length) {
13333                    name = null;
13334                    newArgs = EMPTY_STRING_ARRAY;
13335                } else {
13336                    name = args[opti];
13337                    opti++;
13338                    newArgs = new String[args.length - opti];
13339                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13340                }
13341                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13342                    pw.println("No providers match: " + name);
13343                    pw.println("Use -h for help.");
13344                }
13345            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13346                synchronized (this) {
13347                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13348                }
13349            } else if ("service".equals(cmd)) {
13350                String[] newArgs;
13351                String name;
13352                if (opti >= args.length) {
13353                    name = null;
13354                    newArgs = EMPTY_STRING_ARRAY;
13355                } else {
13356                    name = args[opti];
13357                    opti++;
13358                    newArgs = new String[args.length - opti];
13359                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13360                            args.length - opti);
13361                }
13362                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13363                    pw.println("No services match: " + name);
13364                    pw.println("Use -h for help.");
13365                }
13366            } else if ("package".equals(cmd)) {
13367                String[] newArgs;
13368                if (opti >= args.length) {
13369                    pw.println("package: no package name specified");
13370                    pw.println("Use -h for help.");
13371                } else {
13372                    dumpPackage = args[opti];
13373                    opti++;
13374                    newArgs = new String[args.length - opti];
13375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13376                            args.length - opti);
13377                    args = newArgs;
13378                    opti = 0;
13379                    more = true;
13380                }
13381            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13382                synchronized (this) {
13383                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13384                }
13385            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13386                synchronized (this) {
13387                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13388                }
13389            } else {
13390                // Dumping a single activity?
13391                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13392                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13393                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13394                    if (res < 0) {
13395                        pw.println("Bad activity command, or no activities match: " + cmd);
13396                        pw.println("Use -h for help.");
13397                    }
13398                }
13399            }
13400            if (!more) {
13401                Binder.restoreCallingIdentity(origId);
13402                return;
13403            }
13404        }
13405
13406        // No piece of data specified, dump everything.
13407        synchronized (this) {
13408            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13409            pw.println();
13410            if (dumpAll) {
13411                pw.println("-------------------------------------------------------------------------------");
13412            }
13413            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13414            pw.println();
13415            if (dumpAll) {
13416                pw.println("-------------------------------------------------------------------------------");
13417            }
13418            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13419            pw.println();
13420            if (dumpAll) {
13421                pw.println("-------------------------------------------------------------------------------");
13422            }
13423            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13424            pw.println();
13425            if (dumpAll) {
13426                pw.println("-------------------------------------------------------------------------------");
13427            }
13428            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13429            pw.println();
13430            if (dumpAll) {
13431                pw.println("-------------------------------------------------------------------------------");
13432            }
13433            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13434            pw.println();
13435            if (dumpAll) {
13436                pw.println("-------------------------------------------------------------------------------");
13437            }
13438            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13439            if (mAssociations.size() > 0) {
13440                pw.println();
13441                if (dumpAll) {
13442                    pw.println("-------------------------------------------------------------------------------");
13443                }
13444                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13445            }
13446            pw.println();
13447            if (dumpAll) {
13448                pw.println("-------------------------------------------------------------------------------");
13449            }
13450            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13451        }
13452        Binder.restoreCallingIdentity(origId);
13453    }
13454
13455    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13456            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13457        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13458
13459        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13460                dumpPackage);
13461        boolean needSep = printedAnything;
13462
13463        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13464                dumpPackage, needSep, "  mFocusedActivity: ");
13465        if (printed) {
13466            printedAnything = true;
13467            needSep = false;
13468        }
13469
13470        if (dumpPackage == null) {
13471            if (needSep) {
13472                pw.println();
13473            }
13474            needSep = true;
13475            printedAnything = true;
13476            mStackSupervisor.dump(pw, "  ");
13477        }
13478
13479        if (!printedAnything) {
13480            pw.println("  (nothing)");
13481        }
13482    }
13483
13484    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13485            int opti, boolean dumpAll, String dumpPackage) {
13486        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13487
13488        boolean printedAnything = false;
13489
13490        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13491            boolean printedHeader = false;
13492
13493            final int N = mRecentTasks.size();
13494            for (int i=0; i<N; i++) {
13495                TaskRecord tr = mRecentTasks.get(i);
13496                if (dumpPackage != null) {
13497                    if (tr.realActivity == null ||
13498                            !dumpPackage.equals(tr.realActivity)) {
13499                        continue;
13500                    }
13501                }
13502                if (!printedHeader) {
13503                    pw.println("  Recent tasks:");
13504                    printedHeader = true;
13505                    printedAnything = true;
13506                }
13507                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13508                        pw.println(tr);
13509                if (dumpAll) {
13510                    mRecentTasks.get(i).dump(pw, "    ");
13511                }
13512            }
13513        }
13514
13515        if (!printedAnything) {
13516            pw.println("  (nothing)");
13517        }
13518    }
13519
13520    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13521            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13522        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13523
13524        int dumpUid = 0;
13525        if (dumpPackage != null) {
13526            IPackageManager pm = AppGlobals.getPackageManager();
13527            try {
13528                dumpUid = pm.getPackageUid(dumpPackage, 0);
13529            } catch (RemoteException e) {
13530            }
13531        }
13532
13533        boolean printedAnything = false;
13534
13535        final long now = SystemClock.uptimeMillis();
13536
13537        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13538            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13539                    = mAssociations.valueAt(i1);
13540            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13541                SparseArray<ArrayMap<String, Association>> sourceUids
13542                        = targetComponents.valueAt(i2);
13543                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13544                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13545                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13546                        Association ass = sourceProcesses.valueAt(i4);
13547                        if (dumpPackage != null) {
13548                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13549                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13550                                continue;
13551                            }
13552                        }
13553                        printedAnything = true;
13554                        pw.print("  ");
13555                        pw.print(ass.mTargetProcess);
13556                        pw.print("/");
13557                        UserHandle.formatUid(pw, ass.mTargetUid);
13558                        pw.print(" <- ");
13559                        pw.print(ass.mSourceProcess);
13560                        pw.print("/");
13561                        UserHandle.formatUid(pw, ass.mSourceUid);
13562                        pw.println();
13563                        pw.print("    via ");
13564                        pw.print(ass.mTargetComponent.flattenToShortString());
13565                        pw.println();
13566                        pw.print("    ");
13567                        long dur = ass.mTime;
13568                        if (ass.mNesting > 0) {
13569                            dur += now - ass.mStartTime;
13570                        }
13571                        TimeUtils.formatDuration(dur, pw);
13572                        pw.print(" (");
13573                        pw.print(ass.mCount);
13574                        pw.println(" times)");
13575                        if (ass.mNesting > 0) {
13576                            pw.print("    ");
13577                            pw.print(" Currently active: ");
13578                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13579                            pw.println();
13580                        }
13581                    }
13582                }
13583            }
13584
13585        }
13586
13587        if (!printedAnything) {
13588            pw.println("  (nothing)");
13589        }
13590    }
13591
13592    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13593            String header, boolean needSep) {
13594        boolean printed = false;
13595        int whichAppId = -1;
13596        if (dumpPackage != null) {
13597            try {
13598                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13599                        dumpPackage, 0);
13600                whichAppId = UserHandle.getAppId(info.uid);
13601            } catch (NameNotFoundException e) {
13602                e.printStackTrace();
13603            }
13604        }
13605        for (int i=0; i<uids.size(); i++) {
13606            UidRecord uidRec = uids.valueAt(i);
13607            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13608                continue;
13609            }
13610            if (!printed) {
13611                printed = true;
13612                if (needSep) {
13613                    pw.println();
13614                }
13615                pw.print("  ");
13616                pw.println(header);
13617                needSep = true;
13618            }
13619            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13620            pw.print(": "); pw.println(uidRec);
13621        }
13622        return printed;
13623    }
13624
13625    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13626            int opti, boolean dumpAll, String dumpPackage) {
13627        boolean needSep = false;
13628        boolean printedAnything = false;
13629        int numPers = 0;
13630
13631        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13632
13633        if (dumpAll) {
13634            final int NP = mProcessNames.getMap().size();
13635            for (int ip=0; ip<NP; ip++) {
13636                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13637                final int NA = procs.size();
13638                for (int ia=0; ia<NA; ia++) {
13639                    ProcessRecord r = procs.valueAt(ia);
13640                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13641                        continue;
13642                    }
13643                    if (!needSep) {
13644                        pw.println("  All known processes:");
13645                        needSep = true;
13646                        printedAnything = true;
13647                    }
13648                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13649                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13650                        pw.print(" "); pw.println(r);
13651                    r.dump(pw, "    ");
13652                    if (r.persistent) {
13653                        numPers++;
13654                    }
13655                }
13656            }
13657        }
13658
13659        if (mIsolatedProcesses.size() > 0) {
13660            boolean printed = false;
13661            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13662                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13663                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13664                    continue;
13665                }
13666                if (!printed) {
13667                    if (needSep) {
13668                        pw.println();
13669                    }
13670                    pw.println("  Isolated process list (sorted by uid):");
13671                    printedAnything = true;
13672                    printed = true;
13673                    needSep = true;
13674                }
13675                pw.println(String.format("%sIsolated #%2d: %s",
13676                        "    ", i, r.toString()));
13677            }
13678        }
13679
13680        if (mActiveUids.size() > 0) {
13681            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13682                printedAnything = needSep = true;
13683            }
13684        }
13685        if (mValidateUids.size() > 0) {
13686            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13687                printedAnything = needSep = true;
13688            }
13689        }
13690
13691        if (mLruProcesses.size() > 0) {
13692            if (needSep) {
13693                pw.println();
13694            }
13695            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13696                    pw.print(" total, non-act at ");
13697                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13698                    pw.print(", non-svc at ");
13699                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13700                    pw.println("):");
13701            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13702            needSep = true;
13703            printedAnything = true;
13704        }
13705
13706        if (dumpAll || dumpPackage != null) {
13707            synchronized (mPidsSelfLocked) {
13708                boolean printed = false;
13709                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13710                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13711                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13712                        continue;
13713                    }
13714                    if (!printed) {
13715                        if (needSep) pw.println();
13716                        needSep = true;
13717                        pw.println("  PID mappings:");
13718                        printed = true;
13719                        printedAnything = true;
13720                    }
13721                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13722                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13723                }
13724            }
13725        }
13726
13727        if (mForegroundProcesses.size() > 0) {
13728            synchronized (mPidsSelfLocked) {
13729                boolean printed = false;
13730                for (int i=0; i<mForegroundProcesses.size(); i++) {
13731                    ProcessRecord r = mPidsSelfLocked.get(
13732                            mForegroundProcesses.valueAt(i).pid);
13733                    if (dumpPackage != null && (r == null
13734                            || !r.pkgList.containsKey(dumpPackage))) {
13735                        continue;
13736                    }
13737                    if (!printed) {
13738                        if (needSep) pw.println();
13739                        needSep = true;
13740                        pw.println("  Foreground Processes:");
13741                        printed = true;
13742                        printedAnything = true;
13743                    }
13744                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13745                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13746                }
13747            }
13748        }
13749
13750        if (mPersistentStartingProcesses.size() > 0) {
13751            if (needSep) pw.println();
13752            needSep = true;
13753            printedAnything = true;
13754            pw.println("  Persisent processes that are starting:");
13755            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13756                    "Starting Norm", "Restarting PERS", dumpPackage);
13757        }
13758
13759        if (mRemovedProcesses.size() > 0) {
13760            if (needSep) pw.println();
13761            needSep = true;
13762            printedAnything = true;
13763            pw.println("  Processes that are being removed:");
13764            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13765                    "Removed Norm", "Removed PERS", dumpPackage);
13766        }
13767
13768        if (mProcessesOnHold.size() > 0) {
13769            if (needSep) pw.println();
13770            needSep = true;
13771            printedAnything = true;
13772            pw.println("  Processes that are on old until the system is ready:");
13773            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13774                    "OnHold Norm", "OnHold PERS", dumpPackage);
13775        }
13776
13777        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13778
13779        if (mProcessCrashTimes.getMap().size() > 0) {
13780            boolean printed = false;
13781            long now = SystemClock.uptimeMillis();
13782            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13783            final int NP = pmap.size();
13784            for (int ip=0; ip<NP; ip++) {
13785                String pname = pmap.keyAt(ip);
13786                SparseArray<Long> uids = pmap.valueAt(ip);
13787                final int N = uids.size();
13788                for (int i=0; i<N; i++) {
13789                    int puid = uids.keyAt(i);
13790                    ProcessRecord r = mProcessNames.get(pname, puid);
13791                    if (dumpPackage != null && (r == null
13792                            || !r.pkgList.containsKey(dumpPackage))) {
13793                        continue;
13794                    }
13795                    if (!printed) {
13796                        if (needSep) pw.println();
13797                        needSep = true;
13798                        pw.println("  Time since processes crashed:");
13799                        printed = true;
13800                        printedAnything = true;
13801                    }
13802                    pw.print("    Process "); pw.print(pname);
13803                            pw.print(" uid "); pw.print(puid);
13804                            pw.print(": last crashed ");
13805                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13806                            pw.println(" ago");
13807                }
13808            }
13809        }
13810
13811        if (mBadProcesses.getMap().size() > 0) {
13812            boolean printed = false;
13813            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13814            final int NP = pmap.size();
13815            for (int ip=0; ip<NP; ip++) {
13816                String pname = pmap.keyAt(ip);
13817                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13818                final int N = uids.size();
13819                for (int i=0; i<N; i++) {
13820                    int puid = uids.keyAt(i);
13821                    ProcessRecord r = mProcessNames.get(pname, puid);
13822                    if (dumpPackage != null && (r == null
13823                            || !r.pkgList.containsKey(dumpPackage))) {
13824                        continue;
13825                    }
13826                    if (!printed) {
13827                        if (needSep) pw.println();
13828                        needSep = true;
13829                        pw.println("  Bad processes:");
13830                        printedAnything = true;
13831                    }
13832                    BadProcessInfo info = uids.valueAt(i);
13833                    pw.print("    Bad process "); pw.print(pname);
13834                            pw.print(" uid "); pw.print(puid);
13835                            pw.print(": crashed at time "); pw.println(info.time);
13836                    if (info.shortMsg != null) {
13837                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13838                    }
13839                    if (info.longMsg != null) {
13840                        pw.print("      Long msg: "); pw.println(info.longMsg);
13841                    }
13842                    if (info.stack != null) {
13843                        pw.println("      Stack:");
13844                        int lastPos = 0;
13845                        for (int pos=0; pos<info.stack.length(); pos++) {
13846                            if (info.stack.charAt(pos) == '\n') {
13847                                pw.print("        ");
13848                                pw.write(info.stack, lastPos, pos-lastPos);
13849                                pw.println();
13850                                lastPos = pos+1;
13851                            }
13852                        }
13853                        if (lastPos < info.stack.length()) {
13854                            pw.print("        ");
13855                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13856                            pw.println();
13857                        }
13858                    }
13859                }
13860            }
13861        }
13862
13863        if (dumpPackage == null) {
13864            pw.println();
13865            needSep = false;
13866            mUserController.dump(pw, dumpAll);
13867        }
13868        if (mHomeProcess != null && (dumpPackage == null
13869                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13870            if (needSep) {
13871                pw.println();
13872                needSep = false;
13873            }
13874            pw.println("  mHomeProcess: " + mHomeProcess);
13875        }
13876        if (mPreviousProcess != null && (dumpPackage == null
13877                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13878            if (needSep) {
13879                pw.println();
13880                needSep = false;
13881            }
13882            pw.println("  mPreviousProcess: " + mPreviousProcess);
13883        }
13884        if (dumpAll) {
13885            StringBuilder sb = new StringBuilder(128);
13886            sb.append("  mPreviousProcessVisibleTime: ");
13887            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13888            pw.println(sb);
13889        }
13890        if (mHeavyWeightProcess != null && (dumpPackage == null
13891                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13892            if (needSep) {
13893                pw.println();
13894                needSep = false;
13895            }
13896            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13897        }
13898        if (dumpPackage == null) {
13899            pw.println("  mConfiguration: " + mConfiguration);
13900        }
13901        if (dumpAll) {
13902            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13903            if (mCompatModePackages.getPackages().size() > 0) {
13904                boolean printed = false;
13905                for (Map.Entry<String, Integer> entry
13906                        : mCompatModePackages.getPackages().entrySet()) {
13907                    String pkg = entry.getKey();
13908                    int mode = entry.getValue();
13909                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13910                        continue;
13911                    }
13912                    if (!printed) {
13913                        pw.println("  mScreenCompatPackages:");
13914                        printed = true;
13915                    }
13916                    pw.print("    "); pw.print(pkg); pw.print(": ");
13917                            pw.print(mode); pw.println();
13918                }
13919            }
13920        }
13921        if (dumpPackage == null) {
13922            pw.println("  mWakefulness="
13923                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13924            pw.println("  mSleepTokens=" + mSleepTokens);
13925            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13926                    + lockScreenShownToString());
13927            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13928            if (mRunningVoice != null) {
13929                pw.println("  mRunningVoice=" + mRunningVoice);
13930                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13931            }
13932        }
13933        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13934                || mOrigWaitForDebugger) {
13935            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13936                    || dumpPackage.equals(mOrigDebugApp)) {
13937                if (needSep) {
13938                    pw.println();
13939                    needSep = false;
13940                }
13941                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13942                        + " mDebugTransient=" + mDebugTransient
13943                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13944            }
13945        }
13946        if (mCurAppTimeTracker != null) {
13947            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13948        }
13949        if (mMemWatchProcesses.getMap().size() > 0) {
13950            pw.println("  Mem watch processes:");
13951            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13952                    = mMemWatchProcesses.getMap();
13953            for (int i=0; i<procs.size(); i++) {
13954                final String proc = procs.keyAt(i);
13955                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13956                for (int j=0; j<uids.size(); j++) {
13957                    if (needSep) {
13958                        pw.println();
13959                        needSep = false;
13960                    }
13961                    StringBuilder sb = new StringBuilder();
13962                    sb.append("    ").append(proc).append('/');
13963                    UserHandle.formatUid(sb, uids.keyAt(j));
13964                    Pair<Long, String> val = uids.valueAt(j);
13965                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13966                    if (val.second != null) {
13967                        sb.append(", report to ").append(val.second);
13968                    }
13969                    pw.println(sb.toString());
13970                }
13971            }
13972            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13973            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13974            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13975                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13976        }
13977        if (mTrackAllocationApp != null) {
13978            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13979                if (needSep) {
13980                    pw.println();
13981                    needSep = false;
13982                }
13983                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13984            }
13985        }
13986        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13987                || mProfileFd != null) {
13988            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13989                if (needSep) {
13990                    pw.println();
13991                    needSep = false;
13992                }
13993                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13994                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13995                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13996                        + mAutoStopProfiler);
13997                pw.println("  mProfileType=" + mProfileType);
13998            }
13999        }
14000        if (dumpPackage == null) {
14001            if (mAlwaysFinishActivities || mController != null) {
14002                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14003                        + " mController=" + mController);
14004            }
14005            if (dumpAll) {
14006                pw.println("  Total persistent processes: " + numPers);
14007                pw.println("  mProcessesReady=" + mProcessesReady
14008                        + " mSystemReady=" + mSystemReady
14009                        + " mBooted=" + mBooted
14010                        + " mFactoryTest=" + mFactoryTest);
14011                pw.println("  mBooting=" + mBooting
14012                        + " mCallFinishBooting=" + mCallFinishBooting
14013                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14014                pw.print("  mLastPowerCheckRealtime=");
14015                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14016                        pw.println("");
14017                pw.print("  mLastPowerCheckUptime=");
14018                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14019                        pw.println("");
14020                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14021                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14022                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14023                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14024                        + " (" + mLruProcesses.size() + " total)"
14025                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14026                        + " mNumServiceProcs=" + mNumServiceProcs
14027                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14028                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14029                        + " mLastMemoryLevel" + mLastMemoryLevel
14030                        + " mLastNumProcesses" + mLastNumProcesses);
14031                long now = SystemClock.uptimeMillis();
14032                pw.print("  mLastIdleTime=");
14033                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14034                        pw.print(" mLowRamSinceLastIdle=");
14035                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14036                        pw.println();
14037            }
14038        }
14039
14040        if (!printedAnything) {
14041            pw.println("  (nothing)");
14042        }
14043    }
14044
14045    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14046            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14047        if (mProcessesToGc.size() > 0) {
14048            boolean printed = false;
14049            long now = SystemClock.uptimeMillis();
14050            for (int i=0; i<mProcessesToGc.size(); i++) {
14051                ProcessRecord proc = mProcessesToGc.get(i);
14052                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14053                    continue;
14054                }
14055                if (!printed) {
14056                    if (needSep) pw.println();
14057                    needSep = true;
14058                    pw.println("  Processes that are waiting to GC:");
14059                    printed = true;
14060                }
14061                pw.print("    Process "); pw.println(proc);
14062                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14063                        pw.print(", last gced=");
14064                        pw.print(now-proc.lastRequestedGc);
14065                        pw.print(" ms ago, last lowMem=");
14066                        pw.print(now-proc.lastLowMemory);
14067                        pw.println(" ms ago");
14068
14069            }
14070        }
14071        return needSep;
14072    }
14073
14074    void printOomLevel(PrintWriter pw, String name, int adj) {
14075        pw.print("    ");
14076        if (adj >= 0) {
14077            pw.print(' ');
14078            if (adj < 10) pw.print(' ');
14079        } else {
14080            if (adj > -10) pw.print(' ');
14081        }
14082        pw.print(adj);
14083        pw.print(": ");
14084        pw.print(name);
14085        pw.print(" (");
14086        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14087        pw.println(")");
14088    }
14089
14090    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14091            int opti, boolean dumpAll) {
14092        boolean needSep = false;
14093
14094        if (mLruProcesses.size() > 0) {
14095            if (needSep) pw.println();
14096            needSep = true;
14097            pw.println("  OOM levels:");
14098            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14099            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14100            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14101            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14102            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14103            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14104            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14105            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14106            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14107            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14108            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14109            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14110            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14111            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14112
14113            if (needSep) pw.println();
14114            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14115                    pw.print(" total, non-act at ");
14116                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14117                    pw.print(", non-svc at ");
14118                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14119                    pw.println("):");
14120            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14121            needSep = true;
14122        }
14123
14124        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14125
14126        pw.println();
14127        pw.println("  mHomeProcess: " + mHomeProcess);
14128        pw.println("  mPreviousProcess: " + mPreviousProcess);
14129        if (mHeavyWeightProcess != null) {
14130            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14131        }
14132
14133        return true;
14134    }
14135
14136    /**
14137     * There are three ways to call this:
14138     *  - no provider specified: dump all the providers
14139     *  - a flattened component name that matched an existing provider was specified as the
14140     *    first arg: dump that one provider
14141     *  - the first arg isn't the flattened component name of an existing provider:
14142     *    dump all providers whose component contains the first arg as a substring
14143     */
14144    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14145            int opti, boolean dumpAll) {
14146        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14147    }
14148
14149    static class ItemMatcher {
14150        ArrayList<ComponentName> components;
14151        ArrayList<String> strings;
14152        ArrayList<Integer> objects;
14153        boolean all;
14154
14155        ItemMatcher() {
14156            all = true;
14157        }
14158
14159        void build(String name) {
14160            ComponentName componentName = ComponentName.unflattenFromString(name);
14161            if (componentName != null) {
14162                if (components == null) {
14163                    components = new ArrayList<ComponentName>();
14164                }
14165                components.add(componentName);
14166                all = false;
14167            } else {
14168                int objectId = 0;
14169                // Not a '/' separated full component name; maybe an object ID?
14170                try {
14171                    objectId = Integer.parseInt(name, 16);
14172                    if (objects == null) {
14173                        objects = new ArrayList<Integer>();
14174                    }
14175                    objects.add(objectId);
14176                    all = false;
14177                } catch (RuntimeException e) {
14178                    // Not an integer; just do string match.
14179                    if (strings == null) {
14180                        strings = new ArrayList<String>();
14181                    }
14182                    strings.add(name);
14183                    all = false;
14184                }
14185            }
14186        }
14187
14188        int build(String[] args, int opti) {
14189            for (; opti<args.length; opti++) {
14190                String name = args[opti];
14191                if ("--".equals(name)) {
14192                    return opti+1;
14193                }
14194                build(name);
14195            }
14196            return opti;
14197        }
14198
14199        boolean match(Object object, ComponentName comp) {
14200            if (all) {
14201                return true;
14202            }
14203            if (components != null) {
14204                for (int i=0; i<components.size(); i++) {
14205                    if (components.get(i).equals(comp)) {
14206                        return true;
14207                    }
14208                }
14209            }
14210            if (objects != null) {
14211                for (int i=0; i<objects.size(); i++) {
14212                    if (System.identityHashCode(object) == objects.get(i)) {
14213                        return true;
14214                    }
14215                }
14216            }
14217            if (strings != null) {
14218                String flat = comp.flattenToString();
14219                for (int i=0; i<strings.size(); i++) {
14220                    if (flat.contains(strings.get(i))) {
14221                        return true;
14222                    }
14223                }
14224            }
14225            return false;
14226        }
14227    }
14228
14229    /**
14230     * There are three things that cmd can be:
14231     *  - a flattened component name that matches an existing activity
14232     *  - the cmd arg isn't the flattened component name of an existing activity:
14233     *    dump all activity whose component contains the cmd as a substring
14234     *  - A hex number of the ActivityRecord object instance.
14235     */
14236    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14237            int opti, boolean dumpAll) {
14238        ArrayList<ActivityRecord> activities;
14239
14240        synchronized (this) {
14241            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14242        }
14243
14244        if (activities.size() <= 0) {
14245            return false;
14246        }
14247
14248        String[] newArgs = new String[args.length - opti];
14249        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14250
14251        TaskRecord lastTask = null;
14252        boolean needSep = false;
14253        for (int i=activities.size()-1; i>=0; i--) {
14254            ActivityRecord r = activities.get(i);
14255            if (needSep) {
14256                pw.println();
14257            }
14258            needSep = true;
14259            synchronized (this) {
14260                if (lastTask != r.task) {
14261                    lastTask = r.task;
14262                    pw.print("TASK "); pw.print(lastTask.affinity);
14263                            pw.print(" id="); pw.println(lastTask.taskId);
14264                    if (dumpAll) {
14265                        lastTask.dump(pw, "  ");
14266                    }
14267                }
14268            }
14269            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14270        }
14271        return true;
14272    }
14273
14274    /**
14275     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14276     * there is a thread associated with the activity.
14277     */
14278    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14279            final ActivityRecord r, String[] args, boolean dumpAll) {
14280        String innerPrefix = prefix + "  ";
14281        synchronized (this) {
14282            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14283                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14284                    pw.print(" pid=");
14285                    if (r.app != null) pw.println(r.app.pid);
14286                    else pw.println("(not running)");
14287            if (dumpAll) {
14288                r.dump(pw, innerPrefix);
14289            }
14290        }
14291        if (r.app != null && r.app.thread != null) {
14292            // flush anything that is already in the PrintWriter since the thread is going
14293            // to write to the file descriptor directly
14294            pw.flush();
14295            try {
14296                TransferPipe tp = new TransferPipe();
14297                try {
14298                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14299                            r.appToken, innerPrefix, args);
14300                    tp.go(fd);
14301                } finally {
14302                    tp.kill();
14303                }
14304            } catch (IOException e) {
14305                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14306            } catch (RemoteException e) {
14307                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14308            }
14309        }
14310    }
14311
14312    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14313            int opti, boolean dumpAll, String dumpPackage) {
14314        boolean needSep = false;
14315        boolean onlyHistory = false;
14316        boolean printedAnything = false;
14317
14318        if ("history".equals(dumpPackage)) {
14319            if (opti < args.length && "-s".equals(args[opti])) {
14320                dumpAll = false;
14321            }
14322            onlyHistory = true;
14323            dumpPackage = null;
14324        }
14325
14326        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14327        if (!onlyHistory && dumpAll) {
14328            if (mRegisteredReceivers.size() > 0) {
14329                boolean printed = false;
14330                Iterator it = mRegisteredReceivers.values().iterator();
14331                while (it.hasNext()) {
14332                    ReceiverList r = (ReceiverList)it.next();
14333                    if (dumpPackage != null && (r.app == null ||
14334                            !dumpPackage.equals(r.app.info.packageName))) {
14335                        continue;
14336                    }
14337                    if (!printed) {
14338                        pw.println("  Registered Receivers:");
14339                        needSep = true;
14340                        printed = true;
14341                        printedAnything = true;
14342                    }
14343                    pw.print("  * "); pw.println(r);
14344                    r.dump(pw, "    ");
14345                }
14346            }
14347
14348            if (mReceiverResolver.dump(pw, needSep ?
14349                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14350                    "    ", dumpPackage, false, false)) {
14351                needSep = true;
14352                printedAnything = true;
14353            }
14354        }
14355
14356        for (BroadcastQueue q : mBroadcastQueues) {
14357            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14358            printedAnything |= needSep;
14359        }
14360
14361        needSep = true;
14362
14363        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14364            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14365                if (needSep) {
14366                    pw.println();
14367                }
14368                needSep = true;
14369                printedAnything = true;
14370                pw.print("  Sticky broadcasts for user ");
14371                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14372                StringBuilder sb = new StringBuilder(128);
14373                for (Map.Entry<String, ArrayList<Intent>> ent
14374                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14375                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14376                    if (dumpAll) {
14377                        pw.println(":");
14378                        ArrayList<Intent> intents = ent.getValue();
14379                        final int N = intents.size();
14380                        for (int i=0; i<N; i++) {
14381                            sb.setLength(0);
14382                            sb.append("    Intent: ");
14383                            intents.get(i).toShortString(sb, false, true, false, false);
14384                            pw.println(sb.toString());
14385                            Bundle bundle = intents.get(i).getExtras();
14386                            if (bundle != null) {
14387                                pw.print("      ");
14388                                pw.println(bundle.toString());
14389                            }
14390                        }
14391                    } else {
14392                        pw.println("");
14393                    }
14394                }
14395            }
14396        }
14397
14398        if (!onlyHistory && dumpAll) {
14399            pw.println();
14400            for (BroadcastQueue queue : mBroadcastQueues) {
14401                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14402                        + queue.mBroadcastsScheduled);
14403            }
14404            pw.println("  mHandler:");
14405            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14406            needSep = true;
14407            printedAnything = true;
14408        }
14409
14410        if (!printedAnything) {
14411            pw.println("  (nothing)");
14412        }
14413    }
14414
14415    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14416            int opti, boolean dumpAll, String dumpPackage) {
14417        boolean needSep;
14418        boolean printedAnything = false;
14419
14420        ItemMatcher matcher = new ItemMatcher();
14421        matcher.build(args, opti);
14422
14423        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14424
14425        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14426        printedAnything |= needSep;
14427
14428        if (mLaunchingProviders.size() > 0) {
14429            boolean printed = false;
14430            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14431                ContentProviderRecord r = mLaunchingProviders.get(i);
14432                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14433                    continue;
14434                }
14435                if (!printed) {
14436                    if (needSep) pw.println();
14437                    needSep = true;
14438                    pw.println("  Launching content providers:");
14439                    printed = true;
14440                    printedAnything = true;
14441                }
14442                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14443                        pw.println(r);
14444            }
14445        }
14446
14447        if (!printedAnything) {
14448            pw.println("  (nothing)");
14449        }
14450    }
14451
14452    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14453            int opti, boolean dumpAll, String dumpPackage) {
14454        boolean needSep = false;
14455        boolean printedAnything = false;
14456
14457        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14458
14459        if (mGrantedUriPermissions.size() > 0) {
14460            boolean printed = false;
14461            int dumpUid = -2;
14462            if (dumpPackage != null) {
14463                try {
14464                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14465                } catch (NameNotFoundException e) {
14466                    dumpUid = -1;
14467                }
14468            }
14469            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14470                int uid = mGrantedUriPermissions.keyAt(i);
14471                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14472                    continue;
14473                }
14474                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14475                if (!printed) {
14476                    if (needSep) pw.println();
14477                    needSep = true;
14478                    pw.println("  Granted Uri Permissions:");
14479                    printed = true;
14480                    printedAnything = true;
14481                }
14482                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14483                for (UriPermission perm : perms.values()) {
14484                    pw.print("    "); pw.println(perm);
14485                    if (dumpAll) {
14486                        perm.dump(pw, "      ");
14487                    }
14488                }
14489            }
14490        }
14491
14492        if (!printedAnything) {
14493            pw.println("  (nothing)");
14494        }
14495    }
14496
14497    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14498            int opti, boolean dumpAll, String dumpPackage) {
14499        boolean printed = false;
14500
14501        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14502
14503        if (mIntentSenderRecords.size() > 0) {
14504            Iterator<WeakReference<PendingIntentRecord>> it
14505                    = mIntentSenderRecords.values().iterator();
14506            while (it.hasNext()) {
14507                WeakReference<PendingIntentRecord> ref = it.next();
14508                PendingIntentRecord rec = ref != null ? ref.get(): null;
14509                if (dumpPackage != null && (rec == null
14510                        || !dumpPackage.equals(rec.key.packageName))) {
14511                    continue;
14512                }
14513                printed = true;
14514                if (rec != null) {
14515                    pw.print("  * "); pw.println(rec);
14516                    if (dumpAll) {
14517                        rec.dump(pw, "    ");
14518                    }
14519                } else {
14520                    pw.print("  * "); pw.println(ref);
14521                }
14522            }
14523        }
14524
14525        if (!printed) {
14526            pw.println("  (nothing)");
14527        }
14528    }
14529
14530    private static final int dumpProcessList(PrintWriter pw,
14531            ActivityManagerService service, List list,
14532            String prefix, String normalLabel, String persistentLabel,
14533            String dumpPackage) {
14534        int numPers = 0;
14535        final int N = list.size()-1;
14536        for (int i=N; i>=0; i--) {
14537            ProcessRecord r = (ProcessRecord)list.get(i);
14538            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14539                continue;
14540            }
14541            pw.println(String.format("%s%s #%2d: %s",
14542                    prefix, (r.persistent ? persistentLabel : normalLabel),
14543                    i, r.toString()));
14544            if (r.persistent) {
14545                numPers++;
14546            }
14547        }
14548        return numPers;
14549    }
14550
14551    private static final boolean dumpProcessOomList(PrintWriter pw,
14552            ActivityManagerService service, List<ProcessRecord> origList,
14553            String prefix, String normalLabel, String persistentLabel,
14554            boolean inclDetails, String dumpPackage) {
14555
14556        ArrayList<Pair<ProcessRecord, Integer>> list
14557                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14558        for (int i=0; i<origList.size(); i++) {
14559            ProcessRecord r = origList.get(i);
14560            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14561                continue;
14562            }
14563            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14564        }
14565
14566        if (list.size() <= 0) {
14567            return false;
14568        }
14569
14570        Comparator<Pair<ProcessRecord, Integer>> comparator
14571                = new Comparator<Pair<ProcessRecord, Integer>>() {
14572            @Override
14573            public int compare(Pair<ProcessRecord, Integer> object1,
14574                    Pair<ProcessRecord, Integer> object2) {
14575                if (object1.first.setAdj != object2.first.setAdj) {
14576                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14577                }
14578                if (object1.first.setProcState != object2.first.setProcState) {
14579                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14580                }
14581                if (object1.second.intValue() != object2.second.intValue()) {
14582                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14583                }
14584                return 0;
14585            }
14586        };
14587
14588        Collections.sort(list, comparator);
14589
14590        final long curRealtime = SystemClock.elapsedRealtime();
14591        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14592        final long curUptime = SystemClock.uptimeMillis();
14593        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14594
14595        for (int i=list.size()-1; i>=0; i--) {
14596            ProcessRecord r = list.get(i).first;
14597            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14598            char schedGroup;
14599            switch (r.setSchedGroup) {
14600                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14601                    schedGroup = 'B';
14602                    break;
14603                case Process.THREAD_GROUP_DEFAULT:
14604                    schedGroup = 'F';
14605                    break;
14606                default:
14607                    schedGroup = '?';
14608                    break;
14609            }
14610            char foreground;
14611            if (r.foregroundActivities) {
14612                foreground = 'A';
14613            } else if (r.foregroundServices) {
14614                foreground = 'S';
14615            } else {
14616                foreground = ' ';
14617            }
14618            String procState = ProcessList.makeProcStateString(r.curProcState);
14619            pw.print(prefix);
14620            pw.print(r.persistent ? persistentLabel : normalLabel);
14621            pw.print(" #");
14622            int num = (origList.size()-1)-list.get(i).second;
14623            if (num < 10) pw.print(' ');
14624            pw.print(num);
14625            pw.print(": ");
14626            pw.print(oomAdj);
14627            pw.print(' ');
14628            pw.print(schedGroup);
14629            pw.print('/');
14630            pw.print(foreground);
14631            pw.print('/');
14632            pw.print(procState);
14633            pw.print(" trm:");
14634            if (r.trimMemoryLevel < 10) pw.print(' ');
14635            pw.print(r.trimMemoryLevel);
14636            pw.print(' ');
14637            pw.print(r.toShortString());
14638            pw.print(" (");
14639            pw.print(r.adjType);
14640            pw.println(')');
14641            if (r.adjSource != null || r.adjTarget != null) {
14642                pw.print(prefix);
14643                pw.print("    ");
14644                if (r.adjTarget instanceof ComponentName) {
14645                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14646                } else if (r.adjTarget != null) {
14647                    pw.print(r.adjTarget.toString());
14648                } else {
14649                    pw.print("{null}");
14650                }
14651                pw.print("<=");
14652                if (r.adjSource instanceof ProcessRecord) {
14653                    pw.print("Proc{");
14654                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14655                    pw.println("}");
14656                } else if (r.adjSource != null) {
14657                    pw.println(r.adjSource.toString());
14658                } else {
14659                    pw.println("{null}");
14660                }
14661            }
14662            if (inclDetails) {
14663                pw.print(prefix);
14664                pw.print("    ");
14665                pw.print("oom: max="); pw.print(r.maxAdj);
14666                pw.print(" curRaw="); pw.print(r.curRawAdj);
14667                pw.print(" setRaw="); pw.print(r.setRawAdj);
14668                pw.print(" cur="); pw.print(r.curAdj);
14669                pw.print(" set="); pw.println(r.setAdj);
14670                pw.print(prefix);
14671                pw.print("    ");
14672                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14673                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14674                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14675                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14676                pw.println();
14677                pw.print(prefix);
14678                pw.print("    ");
14679                pw.print("cached="); pw.print(r.cached);
14680                pw.print(" empty="); pw.print(r.empty);
14681                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14682
14683                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14684                    if (r.lastWakeTime != 0) {
14685                        long wtime;
14686                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14687                        synchronized (stats) {
14688                            wtime = stats.getProcessWakeTime(r.info.uid,
14689                                    r.pid, curRealtime);
14690                        }
14691                        long timeUsed = wtime - r.lastWakeTime;
14692                        pw.print(prefix);
14693                        pw.print("    ");
14694                        pw.print("keep awake over ");
14695                        TimeUtils.formatDuration(realtimeSince, pw);
14696                        pw.print(" used ");
14697                        TimeUtils.formatDuration(timeUsed, pw);
14698                        pw.print(" (");
14699                        pw.print((timeUsed*100)/realtimeSince);
14700                        pw.println("%)");
14701                    }
14702                    if (r.lastCpuTime != 0) {
14703                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14704                        pw.print(prefix);
14705                        pw.print("    ");
14706                        pw.print("run cpu over ");
14707                        TimeUtils.formatDuration(uptimeSince, pw);
14708                        pw.print(" used ");
14709                        TimeUtils.formatDuration(timeUsed, pw);
14710                        pw.print(" (");
14711                        pw.print((timeUsed*100)/uptimeSince);
14712                        pw.println("%)");
14713                    }
14714                }
14715            }
14716        }
14717        return true;
14718    }
14719
14720    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14721            String[] args) {
14722        ArrayList<ProcessRecord> procs;
14723        synchronized (this) {
14724            if (args != null && args.length > start
14725                    && args[start].charAt(0) != '-') {
14726                procs = new ArrayList<ProcessRecord>();
14727                int pid = -1;
14728                try {
14729                    pid = Integer.parseInt(args[start]);
14730                } catch (NumberFormatException e) {
14731                }
14732                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14733                    ProcessRecord proc = mLruProcesses.get(i);
14734                    if (proc.pid == pid) {
14735                        procs.add(proc);
14736                    } else if (allPkgs && proc.pkgList != null
14737                            && proc.pkgList.containsKey(args[start])) {
14738                        procs.add(proc);
14739                    } else if (proc.processName.equals(args[start])) {
14740                        procs.add(proc);
14741                    }
14742                }
14743                if (procs.size() <= 0) {
14744                    return null;
14745                }
14746            } else {
14747                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14748            }
14749        }
14750        return procs;
14751    }
14752
14753    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14754            PrintWriter pw, String[] args) {
14755        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14756        if (procs == null) {
14757            pw.println("No process found for: " + args[0]);
14758            return;
14759        }
14760
14761        long uptime = SystemClock.uptimeMillis();
14762        long realtime = SystemClock.elapsedRealtime();
14763        pw.println("Applications Graphics Acceleration Info:");
14764        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14765
14766        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14767            ProcessRecord r = procs.get(i);
14768            if (r.thread != null) {
14769                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14770                pw.flush();
14771                try {
14772                    TransferPipe tp = new TransferPipe();
14773                    try {
14774                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14775                        tp.go(fd);
14776                    } finally {
14777                        tp.kill();
14778                    }
14779                } catch (IOException e) {
14780                    pw.println("Failure while dumping the app: " + r);
14781                    pw.flush();
14782                } catch (RemoteException e) {
14783                    pw.println("Got a RemoteException while dumping the app " + r);
14784                    pw.flush();
14785                }
14786            }
14787        }
14788    }
14789
14790    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14791        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14792        if (procs == null) {
14793            pw.println("No process found for: " + args[0]);
14794            return;
14795        }
14796
14797        pw.println("Applications Database Info:");
14798
14799        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14800            ProcessRecord r = procs.get(i);
14801            if (r.thread != null) {
14802                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14803                pw.flush();
14804                try {
14805                    TransferPipe tp = new TransferPipe();
14806                    try {
14807                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14808                        tp.go(fd);
14809                    } finally {
14810                        tp.kill();
14811                    }
14812                } catch (IOException e) {
14813                    pw.println("Failure while dumping the app: " + r);
14814                    pw.flush();
14815                } catch (RemoteException e) {
14816                    pw.println("Got a RemoteException while dumping the app " + r);
14817                    pw.flush();
14818                }
14819            }
14820        }
14821    }
14822
14823    final static class MemItem {
14824        final boolean isProc;
14825        final String label;
14826        final String shortLabel;
14827        final long pss;
14828        final int id;
14829        final boolean hasActivities;
14830        ArrayList<MemItem> subitems;
14831
14832        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14833                boolean _hasActivities) {
14834            isProc = true;
14835            label = _label;
14836            shortLabel = _shortLabel;
14837            pss = _pss;
14838            id = _id;
14839            hasActivities = _hasActivities;
14840        }
14841
14842        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14843            isProc = false;
14844            label = _label;
14845            shortLabel = _shortLabel;
14846            pss = _pss;
14847            id = _id;
14848            hasActivities = false;
14849        }
14850    }
14851
14852    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14853            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14854        if (sort && !isCompact) {
14855            Collections.sort(items, new Comparator<MemItem>() {
14856                @Override
14857                public int compare(MemItem lhs, MemItem rhs) {
14858                    if (lhs.pss < rhs.pss) {
14859                        return 1;
14860                    } else if (lhs.pss > rhs.pss) {
14861                        return -1;
14862                    }
14863                    return 0;
14864                }
14865            });
14866        }
14867
14868        for (int i=0; i<items.size(); i++) {
14869            MemItem mi = items.get(i);
14870            if (!isCompact) {
14871                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14872            } else if (mi.isProc) {
14873                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14874                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14875                pw.println(mi.hasActivities ? ",a" : ",e");
14876            } else {
14877                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14878                pw.println(mi.pss);
14879            }
14880            if (mi.subitems != null) {
14881                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14882                        true, isCompact);
14883            }
14884        }
14885    }
14886
14887    // These are in KB.
14888    static final long[] DUMP_MEM_BUCKETS = new long[] {
14889        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14890        120*1024, 160*1024, 200*1024,
14891        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14892        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14893    };
14894
14895    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14896            boolean stackLike) {
14897        int start = label.lastIndexOf('.');
14898        if (start >= 0) start++;
14899        else start = 0;
14900        int end = label.length();
14901        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14902            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14903                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14904                out.append(bucket);
14905                out.append(stackLike ? "MB." : "MB ");
14906                out.append(label, start, end);
14907                return;
14908            }
14909        }
14910        out.append(memKB/1024);
14911        out.append(stackLike ? "MB." : "MB ");
14912        out.append(label, start, end);
14913    }
14914
14915    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14916            ProcessList.NATIVE_ADJ,
14917            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14918            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14919            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14920            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14921            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14922            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14923    };
14924    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14925            "Native",
14926            "System", "Persistent", "Persistent Service", "Foreground",
14927            "Visible", "Perceptible",
14928            "Heavy Weight", "Backup",
14929            "A Services", "Home",
14930            "Previous", "B Services", "Cached"
14931    };
14932    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14933            "native",
14934            "sys", "pers", "persvc", "fore",
14935            "vis", "percept",
14936            "heavy", "backup",
14937            "servicea", "home",
14938            "prev", "serviceb", "cached"
14939    };
14940
14941    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14942            long realtime, boolean isCheckinRequest, boolean isCompact) {
14943        if (isCheckinRequest || isCompact) {
14944            // short checkin version
14945            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14946        } else {
14947            pw.println("Applications Memory Usage (in Kilobytes):");
14948            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14949        }
14950    }
14951
14952    private static final int KSM_SHARED = 0;
14953    private static final int KSM_SHARING = 1;
14954    private static final int KSM_UNSHARED = 2;
14955    private static final int KSM_VOLATILE = 3;
14956
14957    private final long[] getKsmInfo() {
14958        long[] longOut = new long[4];
14959        final int[] SINGLE_LONG_FORMAT = new int[] {
14960            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14961        };
14962        long[] longTmp = new long[1];
14963        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14964                SINGLE_LONG_FORMAT, null, longTmp, null);
14965        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14966        longTmp[0] = 0;
14967        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14968                SINGLE_LONG_FORMAT, null, longTmp, null);
14969        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14970        longTmp[0] = 0;
14971        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14972                SINGLE_LONG_FORMAT, null, longTmp, null);
14973        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14974        longTmp[0] = 0;
14975        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14976                SINGLE_LONG_FORMAT, null, longTmp, null);
14977        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14978        return longOut;
14979    }
14980
14981    private static String stringifySize(long size, int order) {
14982        Locale locale = Locale.US;
14983        switch (order) {
14984            case 1:
14985                return String.format(locale, "%,13d", size);
14986            case 1024:
14987                return String.format(locale, "%,9dK", size / 1024);
14988            case 1024 * 1024:
14989                return String.format(locale, "%,5dM", size / 1024 / 1024);
14990            case 1024 * 1024 * 1024:
14991                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
14992            default:
14993                throw new IllegalArgumentException("Invalid size order");
14994        }
14995    }
14996
14997    private static String stringifyKBSize(long size) {
14998        return stringifySize(size * 1024, 1024);
14999    }
15000
15001    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15002            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15003        boolean dumpDetails = false;
15004        boolean dumpFullDetails = false;
15005        boolean dumpDalvik = false;
15006        boolean dumpSummaryOnly = false;
15007        boolean oomOnly = false;
15008        boolean isCompact = false;
15009        boolean localOnly = false;
15010        boolean packages = false;
15011
15012        int opti = 0;
15013        while (opti < args.length) {
15014            String opt = args[opti];
15015            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15016                break;
15017            }
15018            opti++;
15019            if ("-a".equals(opt)) {
15020                dumpDetails = true;
15021                dumpFullDetails = true;
15022                dumpDalvik = true;
15023            } else if ("-d".equals(opt)) {
15024                dumpDalvik = true;
15025            } else if ("-c".equals(opt)) {
15026                isCompact = true;
15027            } else if ("-s".equals(opt)) {
15028                dumpDetails = true;
15029                dumpSummaryOnly = true;
15030            } else if ("--oom".equals(opt)) {
15031                oomOnly = true;
15032            } else if ("--local".equals(opt)) {
15033                localOnly = true;
15034            } else if ("--package".equals(opt)) {
15035                packages = true;
15036            } else if ("-h".equals(opt)) {
15037                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15038                pw.println("  -a: include all available information for each process.");
15039                pw.println("  -d: include dalvik details.");
15040                pw.println("  -c: dump in a compact machine-parseable representation.");
15041                pw.println("  -s: dump only summary of application memory usage.");
15042                pw.println("  --oom: only show processes organized by oom adj.");
15043                pw.println("  --local: only collect details locally, don't call process.");
15044                pw.println("  --package: interpret process arg as package, dumping all");
15045                pw.println("             processes that have loaded that package.");
15046                pw.println("If [process] is specified it can be the name or ");
15047                pw.println("pid of a specific process to dump.");
15048                return;
15049            } else {
15050                pw.println("Unknown argument: " + opt + "; use -h for help");
15051            }
15052        }
15053
15054        final boolean isCheckinRequest = scanArgs(args, "--checkin");
15055        long uptime = SystemClock.uptimeMillis();
15056        long realtime = SystemClock.elapsedRealtime();
15057        final long[] tmpLong = new long[1];
15058
15059        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15060        if (procs == null) {
15061            // No Java processes.  Maybe they want to print a native process.
15062            if (args != null && args.length > opti
15063                    && args[opti].charAt(0) != '-') {
15064                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15065                        = new ArrayList<ProcessCpuTracker.Stats>();
15066                updateCpuStatsNow();
15067                int findPid = -1;
15068                try {
15069                    findPid = Integer.parseInt(args[opti]);
15070                } catch (NumberFormatException e) {
15071                }
15072                synchronized (mProcessCpuTracker) {
15073                    final int N = mProcessCpuTracker.countStats();
15074                    for (int i=0; i<N; i++) {
15075                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15076                        if (st.pid == findPid || (st.baseName != null
15077                                && st.baseName.equals(args[opti]))) {
15078                            nativeProcs.add(st);
15079                        }
15080                    }
15081                }
15082                if (nativeProcs.size() > 0) {
15083                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15084                            isCompact);
15085                    Debug.MemoryInfo mi = null;
15086                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15087                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15088                        final int pid = r.pid;
15089                        if (!isCheckinRequest && dumpDetails) {
15090                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15091                        }
15092                        if (mi == null) {
15093                            mi = new Debug.MemoryInfo();
15094                        }
15095                        if (dumpDetails || (!brief && !oomOnly)) {
15096                            Debug.getMemoryInfo(pid, mi);
15097                        } else {
15098                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15099                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15100                        }
15101                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15102                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15103                        if (isCheckinRequest) {
15104                            pw.println();
15105                        }
15106                    }
15107                    return;
15108                }
15109            }
15110            pw.println("No process found for: " + args[opti]);
15111            return;
15112        }
15113
15114        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15115            dumpDetails = true;
15116        }
15117
15118        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15119
15120        String[] innerArgs = new String[args.length-opti];
15121        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15122
15123        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15124        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15125        long nativePss = 0;
15126        long dalvikPss = 0;
15127        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15128                EmptyArray.LONG;
15129        long otherPss = 0;
15130        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15131
15132        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15133        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15134                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15135
15136        long totalPss = 0;
15137        long cachedPss = 0;
15138
15139        Debug.MemoryInfo mi = null;
15140        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15141            final ProcessRecord r = procs.get(i);
15142            final IApplicationThread thread;
15143            final int pid;
15144            final int oomAdj;
15145            final boolean hasActivities;
15146            synchronized (this) {
15147                thread = r.thread;
15148                pid = r.pid;
15149                oomAdj = r.getSetAdjWithServices();
15150                hasActivities = r.activities.size() > 0;
15151            }
15152            if (thread != null) {
15153                if (!isCheckinRequest && dumpDetails) {
15154                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15155                }
15156                if (mi == null) {
15157                    mi = new Debug.MemoryInfo();
15158                }
15159                if (dumpDetails || (!brief && !oomOnly)) {
15160                    Debug.getMemoryInfo(pid, mi);
15161                } else {
15162                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15163                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15164                }
15165                if (dumpDetails) {
15166                    if (localOnly) {
15167                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15168                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15169                        if (isCheckinRequest) {
15170                            pw.println();
15171                        }
15172                    } else {
15173                        try {
15174                            pw.flush();
15175                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15176                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15177                        } catch (RemoteException e) {
15178                            if (!isCheckinRequest) {
15179                                pw.println("Got RemoteException!");
15180                                pw.flush();
15181                            }
15182                        }
15183                    }
15184                }
15185
15186                final long myTotalPss = mi.getTotalPss();
15187                final long myTotalUss = mi.getTotalUss();
15188
15189                synchronized (this) {
15190                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15191                        // Record this for posterity if the process has been stable.
15192                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15193                    }
15194                }
15195
15196                if (!isCheckinRequest && mi != null) {
15197                    totalPss += myTotalPss;
15198                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15199                            (hasActivities ? " / activities)" : ")"),
15200                            r.processName, myTotalPss, pid, hasActivities);
15201                    procMems.add(pssItem);
15202                    procMemsMap.put(pid, pssItem);
15203
15204                    nativePss += mi.nativePss;
15205                    dalvikPss += mi.dalvikPss;
15206                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15207                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15208                    }
15209                    otherPss += mi.otherPss;
15210                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15211                        long mem = mi.getOtherPss(j);
15212                        miscPss[j] += mem;
15213                        otherPss -= mem;
15214                    }
15215
15216                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15217                        cachedPss += myTotalPss;
15218                    }
15219
15220                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15221                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15222                                || oomIndex == (oomPss.length-1)) {
15223                            oomPss[oomIndex] += myTotalPss;
15224                            if (oomProcs[oomIndex] == null) {
15225                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15226                            }
15227                            oomProcs[oomIndex].add(pssItem);
15228                            break;
15229                        }
15230                    }
15231                }
15232            }
15233        }
15234
15235        long nativeProcTotalPss = 0;
15236
15237        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15238            // If we are showing aggregations, also look for native processes to
15239            // include so that our aggregations are more accurate.
15240            updateCpuStatsNow();
15241            mi = null;
15242            synchronized (mProcessCpuTracker) {
15243                final int N = mProcessCpuTracker.countStats();
15244                for (int i=0; i<N; i++) {
15245                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15246                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15247                        if (mi == null) {
15248                            mi = new Debug.MemoryInfo();
15249                        }
15250                        if (!brief && !oomOnly) {
15251                            Debug.getMemoryInfo(st.pid, mi);
15252                        } else {
15253                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15254                            mi.nativePrivateDirty = (int)tmpLong[0];
15255                        }
15256
15257                        final long myTotalPss = mi.getTotalPss();
15258                        totalPss += myTotalPss;
15259                        nativeProcTotalPss += myTotalPss;
15260
15261                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15262                                st.name, myTotalPss, st.pid, false);
15263                        procMems.add(pssItem);
15264
15265                        nativePss += mi.nativePss;
15266                        dalvikPss += mi.dalvikPss;
15267                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15268                            dalvikSubitemPss[j] += mi.getOtherPss(
15269                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15270                        }
15271                        otherPss += mi.otherPss;
15272                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15273                            long mem = mi.getOtherPss(j);
15274                            miscPss[j] += mem;
15275                            otherPss -= mem;
15276                        }
15277                        oomPss[0] += myTotalPss;
15278                        if (oomProcs[0] == null) {
15279                            oomProcs[0] = new ArrayList<MemItem>();
15280                        }
15281                        oomProcs[0].add(pssItem);
15282                    }
15283                }
15284            }
15285
15286            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15287
15288            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15289            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15290            if (dalvikSubitemPss.length > 0) {
15291                dalvikItem.subitems = new ArrayList<MemItem>();
15292                for (int j=0; j<dalvikSubitemPss.length; j++) {
15293                    final String name = Debug.MemoryInfo.getOtherLabel(
15294                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15295                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15296                }
15297            }
15298            catMems.add(dalvikItem);
15299            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15300            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15301                String label = Debug.MemoryInfo.getOtherLabel(j);
15302                catMems.add(new MemItem(label, label, miscPss[j], j));
15303            }
15304
15305            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15306            for (int j=0; j<oomPss.length; j++) {
15307                if (oomPss[j] != 0) {
15308                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15309                            : DUMP_MEM_OOM_LABEL[j];
15310                    MemItem item = new MemItem(label, label, oomPss[j],
15311                            DUMP_MEM_OOM_ADJ[j]);
15312                    item.subitems = oomProcs[j];
15313                    oomMems.add(item);
15314                }
15315            }
15316
15317            if (!brief && !oomOnly && !isCompact) {
15318                pw.println();
15319                pw.println("Total PSS by process:");
15320                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15321                pw.println();
15322            }
15323            if (!isCompact) {
15324                pw.println("Total PSS by OOM adjustment:");
15325            }
15326            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15327            if (!brief && !oomOnly) {
15328                PrintWriter out = categoryPw != null ? categoryPw : pw;
15329                if (!isCompact) {
15330                    out.println();
15331                    out.println("Total PSS by category:");
15332                }
15333                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15334            }
15335            if (!isCompact) {
15336                pw.println();
15337            }
15338            MemInfoReader memInfo = new MemInfoReader();
15339            memInfo.readMemInfo();
15340            if (nativeProcTotalPss > 0) {
15341                synchronized (this) {
15342                    final long cachedKb = memInfo.getCachedSizeKb();
15343                    final long freeKb = memInfo.getFreeSizeKb();
15344                    final long zramKb = memInfo.getZramTotalSizeKb();
15345                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15346                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15347                            kernelKb*1024, nativeProcTotalPss*1024);
15348                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15349                            nativeProcTotalPss);
15350                }
15351            }
15352            if (!brief) {
15353                if (!isCompact) {
15354                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15355                    pw.print(" (status ");
15356                    switch (mLastMemoryLevel) {
15357                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15358                            pw.println("normal)");
15359                            break;
15360                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15361                            pw.println("moderate)");
15362                            break;
15363                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15364                            pw.println("low)");
15365                            break;
15366                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15367                            pw.println("critical)");
15368                            break;
15369                        default:
15370                            pw.print(mLastMemoryLevel);
15371                            pw.println(")");
15372                            break;
15373                    }
15374                    pw.print(" Free RAM: ");
15375                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15376                            + memInfo.getFreeSizeKb()));
15377                    pw.print(" (");
15378                    pw.print(stringifyKBSize(cachedPss));
15379                    pw.print(" cached pss + ");
15380                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15381                    pw.print(" cached kernel + ");
15382                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15383                    pw.println(" free)");
15384                } else {
15385                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15386                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15387                            + memInfo.getFreeSizeKb()); pw.print(",");
15388                    pw.println(totalPss - cachedPss);
15389                }
15390            }
15391            if (!isCompact) {
15392                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15393                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15394                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15395                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15396                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15397                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15398                        - memInfo.getKernelUsedSizeKb()));
15399            }
15400            if (!brief) {
15401                if (memInfo.getZramTotalSizeKb() != 0) {
15402                    if (!isCompact) {
15403                        pw.print("     ZRAM: ");
15404                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15405                                pw.print(" physical used for ");
15406                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15407                                        - memInfo.getSwapFreeSizeKb()));
15408                                pw.print(" in swap (");
15409                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15410                                pw.println(" total swap)");
15411                    } else {
15412                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15413                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15414                                pw.println(memInfo.getSwapFreeSizeKb());
15415                    }
15416                }
15417                final long[] ksm = getKsmInfo();
15418                if (!isCompact) {
15419                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15420                            || ksm[KSM_VOLATILE] != 0) {
15421                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15422                                pw.print(" saved from shared ");
15423                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15424                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15425                                pw.print(" unshared; ");
15426                                pw.print(stringifyKBSize(
15427                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15428                    }
15429                    pw.print("   Tuning: ");
15430                    pw.print(ActivityManager.staticGetMemoryClass());
15431                    pw.print(" (large ");
15432                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15433                    pw.print("), oom ");
15434                    pw.print(stringifySize(
15435                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15436                    pw.print(", restore limit ");
15437                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15438                    if (ActivityManager.isLowRamDeviceStatic()) {
15439                        pw.print(" (low-ram)");
15440                    }
15441                    if (ActivityManager.isHighEndGfx()) {
15442                        pw.print(" (high-end-gfx)");
15443                    }
15444                    pw.println();
15445                } else {
15446                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15447                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15448                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15449                    pw.print("tuning,");
15450                    pw.print(ActivityManager.staticGetMemoryClass());
15451                    pw.print(',');
15452                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15453                    pw.print(',');
15454                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15455                    if (ActivityManager.isLowRamDeviceStatic()) {
15456                        pw.print(",low-ram");
15457                    }
15458                    if (ActivityManager.isHighEndGfx()) {
15459                        pw.print(",high-end-gfx");
15460                    }
15461                    pw.println();
15462                }
15463            }
15464        }
15465    }
15466
15467    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15468            long memtrack, String name) {
15469        sb.append("  ");
15470        sb.append(ProcessList.makeOomAdjString(oomAdj));
15471        sb.append(' ');
15472        sb.append(ProcessList.makeProcStateString(procState));
15473        sb.append(' ');
15474        ProcessList.appendRamKb(sb, pss);
15475        sb.append(": ");
15476        sb.append(name);
15477        if (memtrack > 0) {
15478            sb.append(" (");
15479            sb.append(stringifyKBSize(memtrack));
15480            sb.append(" memtrack)");
15481        }
15482    }
15483
15484    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15485        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15486        sb.append(" (pid ");
15487        sb.append(mi.pid);
15488        sb.append(") ");
15489        sb.append(mi.adjType);
15490        sb.append('\n');
15491        if (mi.adjReason != null) {
15492            sb.append("                      ");
15493            sb.append(mi.adjReason);
15494            sb.append('\n');
15495        }
15496    }
15497
15498    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15499        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15500        for (int i=0, N=memInfos.size(); i<N; i++) {
15501            ProcessMemInfo mi = memInfos.get(i);
15502            infoMap.put(mi.pid, mi);
15503        }
15504        updateCpuStatsNow();
15505        long[] memtrackTmp = new long[1];
15506        synchronized (mProcessCpuTracker) {
15507            final int N = mProcessCpuTracker.countStats();
15508            for (int i=0; i<N; i++) {
15509                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15510                if (st.vsize > 0) {
15511                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15512                    if (pss > 0) {
15513                        if (infoMap.indexOfKey(st.pid) < 0) {
15514                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15515                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15516                            mi.pss = pss;
15517                            mi.memtrack = memtrackTmp[0];
15518                            memInfos.add(mi);
15519                        }
15520                    }
15521                }
15522            }
15523        }
15524
15525        long totalPss = 0;
15526        long totalMemtrack = 0;
15527        for (int i=0, N=memInfos.size(); i<N; i++) {
15528            ProcessMemInfo mi = memInfos.get(i);
15529            if (mi.pss == 0) {
15530                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15531                mi.memtrack = memtrackTmp[0];
15532            }
15533            totalPss += mi.pss;
15534            totalMemtrack += mi.memtrack;
15535        }
15536        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15537            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15538                if (lhs.oomAdj != rhs.oomAdj) {
15539                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15540                }
15541                if (lhs.pss != rhs.pss) {
15542                    return lhs.pss < rhs.pss ? 1 : -1;
15543                }
15544                return 0;
15545            }
15546        });
15547
15548        StringBuilder tag = new StringBuilder(128);
15549        StringBuilder stack = new StringBuilder(128);
15550        tag.append("Low on memory -- ");
15551        appendMemBucket(tag, totalPss, "total", false);
15552        appendMemBucket(stack, totalPss, "total", true);
15553
15554        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15555        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15556        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15557
15558        boolean firstLine = true;
15559        int lastOomAdj = Integer.MIN_VALUE;
15560        long extraNativeRam = 0;
15561        long extraNativeMemtrack = 0;
15562        long cachedPss = 0;
15563        for (int i=0, N=memInfos.size(); i<N; i++) {
15564            ProcessMemInfo mi = memInfos.get(i);
15565
15566            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15567                cachedPss += mi.pss;
15568            }
15569
15570            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15571                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15572                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15573                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15574                if (lastOomAdj != mi.oomAdj) {
15575                    lastOomAdj = mi.oomAdj;
15576                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15577                        tag.append(" / ");
15578                    }
15579                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15580                        if (firstLine) {
15581                            stack.append(":");
15582                            firstLine = false;
15583                        }
15584                        stack.append("\n\t at ");
15585                    } else {
15586                        stack.append("$");
15587                    }
15588                } else {
15589                    tag.append(" ");
15590                    stack.append("$");
15591                }
15592                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15593                    appendMemBucket(tag, mi.pss, mi.name, false);
15594                }
15595                appendMemBucket(stack, mi.pss, mi.name, true);
15596                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15597                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15598                    stack.append("(");
15599                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15600                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15601                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15602                            stack.append(":");
15603                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15604                        }
15605                    }
15606                    stack.append(")");
15607                }
15608            }
15609
15610            appendMemInfo(fullNativeBuilder, mi);
15611            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15612                // The short form only has native processes that are >= 512K.
15613                if (mi.pss >= 512) {
15614                    appendMemInfo(shortNativeBuilder, mi);
15615                } else {
15616                    extraNativeRam += mi.pss;
15617                    extraNativeMemtrack += mi.memtrack;
15618                }
15619            } else {
15620                // Short form has all other details, but if we have collected RAM
15621                // from smaller native processes let's dump a summary of that.
15622                if (extraNativeRam > 0) {
15623                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15624                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15625                    shortNativeBuilder.append('\n');
15626                    extraNativeRam = 0;
15627                }
15628                appendMemInfo(fullJavaBuilder, mi);
15629            }
15630        }
15631
15632        fullJavaBuilder.append("           ");
15633        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15634        fullJavaBuilder.append(": TOTAL");
15635        if (totalMemtrack > 0) {
15636            fullJavaBuilder.append(" (");
15637            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15638            fullJavaBuilder.append(" memtrack)");
15639        } else {
15640        }
15641        fullJavaBuilder.append("\n");
15642
15643        MemInfoReader memInfo = new MemInfoReader();
15644        memInfo.readMemInfo();
15645        final long[] infos = memInfo.getRawInfo();
15646
15647        StringBuilder memInfoBuilder = new StringBuilder(1024);
15648        Debug.getMemInfo(infos);
15649        memInfoBuilder.append("  MemInfo: ");
15650        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15651        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15652        memInfoBuilder.append(stringifyKBSize(
15653                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15654        memInfoBuilder.append(stringifyKBSize(
15655                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15656        memInfoBuilder.append(stringifyKBSize(
15657                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15658        memInfoBuilder.append("           ");
15659        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15660        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15661        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15662        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15663        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15664            memInfoBuilder.append("  ZRAM: ");
15665            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15666            memInfoBuilder.append(" RAM, ");
15667            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15668            memInfoBuilder.append(" swap total, ");
15669            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15670            memInfoBuilder.append(" swap free\n");
15671        }
15672        final long[] ksm = getKsmInfo();
15673        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15674                || ksm[KSM_VOLATILE] != 0) {
15675            memInfoBuilder.append("  KSM: ");
15676            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15677            memInfoBuilder.append(" saved from shared ");
15678            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15679            memInfoBuilder.append("\n       ");
15680            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15681            memInfoBuilder.append(" unshared; ");
15682            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15683            memInfoBuilder.append(" volatile\n");
15684        }
15685        memInfoBuilder.append("  Free RAM: ");
15686        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15687                + memInfo.getFreeSizeKb()));
15688        memInfoBuilder.append("\n");
15689        memInfoBuilder.append("  Used RAM: ");
15690        memInfoBuilder.append(stringifyKBSize(
15691                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15692        memInfoBuilder.append("\n");
15693        memInfoBuilder.append("  Lost RAM: ");
15694        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15695                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15696                - memInfo.getKernelUsedSizeKb()));
15697        memInfoBuilder.append("\n");
15698        Slog.i(TAG, "Low on memory:");
15699        Slog.i(TAG, shortNativeBuilder.toString());
15700        Slog.i(TAG, fullJavaBuilder.toString());
15701        Slog.i(TAG, memInfoBuilder.toString());
15702
15703        StringBuilder dropBuilder = new StringBuilder(1024);
15704        /*
15705        StringWriter oomSw = new StringWriter();
15706        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15707        StringWriter catSw = new StringWriter();
15708        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15709        String[] emptyArgs = new String[] { };
15710        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15711        oomPw.flush();
15712        String oomString = oomSw.toString();
15713        */
15714        dropBuilder.append("Low on memory:");
15715        dropBuilder.append(stack);
15716        dropBuilder.append('\n');
15717        dropBuilder.append(fullNativeBuilder);
15718        dropBuilder.append(fullJavaBuilder);
15719        dropBuilder.append('\n');
15720        dropBuilder.append(memInfoBuilder);
15721        dropBuilder.append('\n');
15722        /*
15723        dropBuilder.append(oomString);
15724        dropBuilder.append('\n');
15725        */
15726        StringWriter catSw = new StringWriter();
15727        synchronized (ActivityManagerService.this) {
15728            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15729            String[] emptyArgs = new String[] { };
15730            catPw.println();
15731            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15732            catPw.println();
15733            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15734                    false, false, null);
15735            catPw.println();
15736            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15737            catPw.flush();
15738        }
15739        dropBuilder.append(catSw.toString());
15740        addErrorToDropBox("lowmem", null, "system_server", null,
15741                null, tag.toString(), dropBuilder.toString(), null, null);
15742        //Slog.i(TAG, "Sent to dropbox:");
15743        //Slog.i(TAG, dropBuilder.toString());
15744        synchronized (ActivityManagerService.this) {
15745            long now = SystemClock.uptimeMillis();
15746            if (mLastMemUsageReportTime < now) {
15747                mLastMemUsageReportTime = now;
15748            }
15749        }
15750    }
15751
15752    /**
15753     * Searches array of arguments for the specified string
15754     * @param args array of argument strings
15755     * @param value value to search for
15756     * @return true if the value is contained in the array
15757     */
15758    private static boolean scanArgs(String[] args, String value) {
15759        if (args != null) {
15760            for (String arg : args) {
15761                if (value.equals(arg)) {
15762                    return true;
15763                }
15764            }
15765        }
15766        return false;
15767    }
15768
15769    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15770            ContentProviderRecord cpr, boolean always) {
15771        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15772
15773        if (!inLaunching || always) {
15774            synchronized (cpr) {
15775                cpr.launchingApp = null;
15776                cpr.notifyAll();
15777            }
15778            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15779            String names[] = cpr.info.authority.split(";");
15780            for (int j = 0; j < names.length; j++) {
15781                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15782            }
15783        }
15784
15785        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15786            ContentProviderConnection conn = cpr.connections.get(i);
15787            if (conn.waiting) {
15788                // If this connection is waiting for the provider, then we don't
15789                // need to mess with its process unless we are always removing
15790                // or for some reason the provider is not currently launching.
15791                if (inLaunching && !always) {
15792                    continue;
15793                }
15794            }
15795            ProcessRecord capp = conn.client;
15796            conn.dead = true;
15797            if (conn.stableCount > 0) {
15798                if (!capp.persistent && capp.thread != null
15799                        && capp.pid != 0
15800                        && capp.pid != MY_PID) {
15801                    capp.kill("depends on provider "
15802                            + cpr.name.flattenToShortString()
15803                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15804                }
15805            } else if (capp.thread != null && conn.provider.provider != null) {
15806                try {
15807                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15808                } catch (RemoteException e) {
15809                }
15810                // In the protocol here, we don't expect the client to correctly
15811                // clean up this connection, we'll just remove it.
15812                cpr.connections.remove(i);
15813                if (conn.client.conProviders.remove(conn)) {
15814                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15815                }
15816            }
15817        }
15818
15819        if (inLaunching && always) {
15820            mLaunchingProviders.remove(cpr);
15821        }
15822        return inLaunching;
15823    }
15824
15825    /**
15826     * Main code for cleaning up a process when it has gone away.  This is
15827     * called both as a result of the process dying, or directly when stopping
15828     * a process when running in single process mode.
15829     *
15830     * @return Returns true if the given process has been restarted, so the
15831     * app that was passed in must remain on the process lists.
15832     */
15833    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15834            boolean restarting, boolean allowRestart, int index) {
15835        if (index >= 0) {
15836            removeLruProcessLocked(app);
15837            ProcessList.remove(app.pid);
15838        }
15839
15840        mProcessesToGc.remove(app);
15841        mPendingPssProcesses.remove(app);
15842
15843        // Dismiss any open dialogs.
15844        if (app.crashDialog != null && !app.forceCrashReport) {
15845            app.crashDialog.dismiss();
15846            app.crashDialog = null;
15847        }
15848        if (app.anrDialog != null) {
15849            app.anrDialog.dismiss();
15850            app.anrDialog = null;
15851        }
15852        if (app.waitDialog != null) {
15853            app.waitDialog.dismiss();
15854            app.waitDialog = null;
15855        }
15856
15857        app.crashing = false;
15858        app.notResponding = false;
15859
15860        app.resetPackageList(mProcessStats);
15861        app.unlinkDeathRecipient();
15862        app.makeInactive(mProcessStats);
15863        app.waitingToKill = null;
15864        app.forcingToForeground = null;
15865        updateProcessForegroundLocked(app, false, false);
15866        app.foregroundActivities = false;
15867        app.hasShownUi = false;
15868        app.treatLikeActivity = false;
15869        app.hasAboveClient = false;
15870        app.hasClientActivities = false;
15871
15872        mServices.killServicesLocked(app, allowRestart);
15873
15874        boolean restart = false;
15875
15876        // Remove published content providers.
15877        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15878            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15879            final boolean always = app.bad || !allowRestart;
15880            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15881            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15882                // We left the provider in the launching list, need to
15883                // restart it.
15884                restart = true;
15885            }
15886
15887            cpr.provider = null;
15888            cpr.proc = null;
15889        }
15890        app.pubProviders.clear();
15891
15892        // Take care of any launching providers waiting for this process.
15893        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15894            restart = true;
15895        }
15896
15897        // Unregister from connected content providers.
15898        if (!app.conProviders.isEmpty()) {
15899            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15900                ContentProviderConnection conn = app.conProviders.get(i);
15901                conn.provider.connections.remove(conn);
15902                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15903                        conn.provider.name);
15904            }
15905            app.conProviders.clear();
15906        }
15907
15908        // At this point there may be remaining entries in mLaunchingProviders
15909        // where we were the only one waiting, so they are no longer of use.
15910        // Look for these and clean up if found.
15911        // XXX Commented out for now.  Trying to figure out a way to reproduce
15912        // the actual situation to identify what is actually going on.
15913        if (false) {
15914            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15915                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15916                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15917                    synchronized (cpr) {
15918                        cpr.launchingApp = null;
15919                        cpr.notifyAll();
15920                    }
15921                }
15922            }
15923        }
15924
15925        skipCurrentReceiverLocked(app);
15926
15927        // Unregister any receivers.
15928        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15929            removeReceiverLocked(app.receivers.valueAt(i));
15930        }
15931        app.receivers.clear();
15932
15933        // If the app is undergoing backup, tell the backup manager about it
15934        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15935            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15936                    + mBackupTarget.appInfo + " died during backup");
15937            try {
15938                IBackupManager bm = IBackupManager.Stub.asInterface(
15939                        ServiceManager.getService(Context.BACKUP_SERVICE));
15940                bm.agentDisconnected(app.info.packageName);
15941            } catch (RemoteException e) {
15942                // can't happen; backup manager is local
15943            }
15944        }
15945
15946        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15947            ProcessChangeItem item = mPendingProcessChanges.get(i);
15948            if (item.pid == app.pid) {
15949                mPendingProcessChanges.remove(i);
15950                mAvailProcessChanges.add(item);
15951            }
15952        }
15953        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
15954                null).sendToTarget();
15955
15956        // If the caller is restarting this app, then leave it in its
15957        // current lists and let the caller take care of it.
15958        if (restarting) {
15959            return false;
15960        }
15961
15962        if (!app.persistent || app.isolated) {
15963            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15964                    "Removing non-persistent process during cleanup: " + app);
15965            removeProcessNameLocked(app.processName, app.uid);
15966            if (mHeavyWeightProcess == app) {
15967                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15968                        mHeavyWeightProcess.userId, 0));
15969                mHeavyWeightProcess = null;
15970            }
15971        } else if (!app.removed) {
15972            // This app is persistent, so we need to keep its record around.
15973            // If it is not already on the pending app list, add it there
15974            // and start a new process for it.
15975            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15976                mPersistentStartingProcesses.add(app);
15977                restart = true;
15978            }
15979        }
15980        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15981                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15982        mProcessesOnHold.remove(app);
15983
15984        if (app == mHomeProcess) {
15985            mHomeProcess = null;
15986        }
15987        if (app == mPreviousProcess) {
15988            mPreviousProcess = null;
15989        }
15990
15991        if (restart && !app.isolated) {
15992            // We have components that still need to be running in the
15993            // process, so re-launch it.
15994            if (index < 0) {
15995                ProcessList.remove(app.pid);
15996            }
15997            addProcessNameLocked(app);
15998            startProcessLocked(app, "restart", app.processName);
15999            return true;
16000        } else if (app.pid > 0 && app.pid != MY_PID) {
16001            // Goodbye!
16002            boolean removed;
16003            synchronized (mPidsSelfLocked) {
16004                mPidsSelfLocked.remove(app.pid);
16005                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16006            }
16007            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16008            if (app.isolated) {
16009                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16010            }
16011            app.setPid(0);
16012        }
16013        return false;
16014    }
16015
16016    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16017        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16018            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16019            if (cpr.launchingApp == app) {
16020                return true;
16021            }
16022        }
16023        return false;
16024    }
16025
16026    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16027        // Look through the content providers we are waiting to have launched,
16028        // and if any run in this process then either schedule a restart of
16029        // the process or kill the client waiting for it if this process has
16030        // gone bad.
16031        boolean restart = false;
16032        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16033            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16034            if (cpr.launchingApp == app) {
16035                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16036                    restart = true;
16037                } else {
16038                    removeDyingProviderLocked(app, cpr, true);
16039                }
16040            }
16041        }
16042        return restart;
16043    }
16044
16045    // =========================================================
16046    // SERVICES
16047    // =========================================================
16048
16049    @Override
16050    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16051            int flags) {
16052        enforceNotIsolatedCaller("getServices");
16053        synchronized (this) {
16054            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16055        }
16056    }
16057
16058    @Override
16059    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16060        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16061        synchronized (this) {
16062            return mServices.getRunningServiceControlPanelLocked(name);
16063        }
16064    }
16065
16066    @Override
16067    public ComponentName startService(IApplicationThread caller, Intent service,
16068            String resolvedType, String callingPackage, int userId)
16069            throws TransactionTooLargeException {
16070        enforceNotIsolatedCaller("startService");
16071        // Refuse possible leaked file descriptors
16072        if (service != null && service.hasFileDescriptors() == true) {
16073            throw new IllegalArgumentException("File descriptors passed in Intent");
16074        }
16075
16076        if (callingPackage == null) {
16077            throw new IllegalArgumentException("callingPackage cannot be null");
16078        }
16079
16080        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16081                "startService: " + service + " type=" + resolvedType);
16082        synchronized(this) {
16083            final int callingPid = Binder.getCallingPid();
16084            final int callingUid = Binder.getCallingUid();
16085            final long origId = Binder.clearCallingIdentity();
16086            ComponentName res = mServices.startServiceLocked(caller, service,
16087                    resolvedType, callingPid, callingUid, callingPackage, userId);
16088            Binder.restoreCallingIdentity(origId);
16089            return res;
16090        }
16091    }
16092
16093    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16094            String callingPackage, int userId)
16095            throws TransactionTooLargeException {
16096        synchronized(this) {
16097            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16098                    "startServiceInPackage: " + service + " type=" + resolvedType);
16099            final long origId = Binder.clearCallingIdentity();
16100            ComponentName res = mServices.startServiceLocked(null, service,
16101                    resolvedType, -1, uid, callingPackage, userId);
16102            Binder.restoreCallingIdentity(origId);
16103            return res;
16104        }
16105    }
16106
16107    @Override
16108    public int stopService(IApplicationThread caller, Intent service,
16109            String resolvedType, int userId) {
16110        enforceNotIsolatedCaller("stopService");
16111        // Refuse possible leaked file descriptors
16112        if (service != null && service.hasFileDescriptors() == true) {
16113            throw new IllegalArgumentException("File descriptors passed in Intent");
16114        }
16115
16116        synchronized(this) {
16117            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16118        }
16119    }
16120
16121    @Override
16122    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16123        enforceNotIsolatedCaller("peekService");
16124        // Refuse possible leaked file descriptors
16125        if (service != null && service.hasFileDescriptors() == true) {
16126            throw new IllegalArgumentException("File descriptors passed in Intent");
16127        }
16128
16129        if (callingPackage == null) {
16130            throw new IllegalArgumentException("callingPackage cannot be null");
16131        }
16132
16133        synchronized(this) {
16134            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16135        }
16136    }
16137
16138    @Override
16139    public boolean stopServiceToken(ComponentName className, IBinder token,
16140            int startId) {
16141        synchronized(this) {
16142            return mServices.stopServiceTokenLocked(className, token, startId);
16143        }
16144    }
16145
16146    @Override
16147    public void setServiceForeground(ComponentName className, IBinder token,
16148            int id, Notification notification, boolean removeNotification) {
16149        synchronized(this) {
16150            mServices.setServiceForegroundLocked(className, token, id, notification,
16151                    removeNotification);
16152        }
16153    }
16154
16155    @Override
16156    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16157            boolean requireFull, String name, String callerPackage) {
16158        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16159                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16160    }
16161
16162    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16163            String className, int flags) {
16164        boolean result = false;
16165        // For apps that don't have pre-defined UIDs, check for permission
16166        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16167            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16168                if (ActivityManager.checkUidPermission(
16169                        INTERACT_ACROSS_USERS,
16170                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16171                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16172                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16173                            + " requests FLAG_SINGLE_USER, but app does not hold "
16174                            + INTERACT_ACROSS_USERS;
16175                    Slog.w(TAG, msg);
16176                    throw new SecurityException(msg);
16177                }
16178                // Permission passed
16179                result = true;
16180            }
16181        } else if ("system".equals(componentProcessName)) {
16182            result = true;
16183        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16184            // Phone app and persistent apps are allowed to export singleuser providers.
16185            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16186                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16187        }
16188        if (DEBUG_MU) Slog.v(TAG_MU,
16189                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16190                + Integer.toHexString(flags) + ") = " + result);
16191        return result;
16192    }
16193
16194    /**
16195     * Checks to see if the caller is in the same app as the singleton
16196     * component, or the component is in a special app. It allows special apps
16197     * to export singleton components but prevents exporting singleton
16198     * components for regular apps.
16199     */
16200    boolean isValidSingletonCall(int callingUid, int componentUid) {
16201        int componentAppId = UserHandle.getAppId(componentUid);
16202        return UserHandle.isSameApp(callingUid, componentUid)
16203                || componentAppId == Process.SYSTEM_UID
16204                || componentAppId == Process.PHONE_UID
16205                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16206                        == PackageManager.PERMISSION_GRANTED;
16207    }
16208
16209    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16210            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16211            int userId) throws TransactionTooLargeException {
16212        enforceNotIsolatedCaller("bindService");
16213
16214        // Refuse possible leaked file descriptors
16215        if (service != null && service.hasFileDescriptors() == true) {
16216            throw new IllegalArgumentException("File descriptors passed in Intent");
16217        }
16218
16219        if (callingPackage == null) {
16220            throw new IllegalArgumentException("callingPackage cannot be null");
16221        }
16222
16223        synchronized(this) {
16224            return mServices.bindServiceLocked(caller, token, service,
16225                    resolvedType, connection, flags, callingPackage, userId);
16226        }
16227    }
16228
16229    public boolean unbindService(IServiceConnection connection) {
16230        synchronized (this) {
16231            return mServices.unbindServiceLocked(connection);
16232        }
16233    }
16234
16235    public void publishService(IBinder token, Intent intent, IBinder service) {
16236        // Refuse possible leaked file descriptors
16237        if (intent != null && intent.hasFileDescriptors() == true) {
16238            throw new IllegalArgumentException("File descriptors passed in Intent");
16239        }
16240
16241        synchronized(this) {
16242            if (!(token instanceof ServiceRecord)) {
16243                throw new IllegalArgumentException("Invalid service token");
16244            }
16245            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16246        }
16247    }
16248
16249    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16250        // Refuse possible leaked file descriptors
16251        if (intent != null && intent.hasFileDescriptors() == true) {
16252            throw new IllegalArgumentException("File descriptors passed in Intent");
16253        }
16254
16255        synchronized(this) {
16256            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16257        }
16258    }
16259
16260    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16261        synchronized(this) {
16262            if (!(token instanceof ServiceRecord)) {
16263                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16264                throw new IllegalArgumentException("Invalid service token");
16265            }
16266            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16267        }
16268    }
16269
16270    // =========================================================
16271    // BACKUP AND RESTORE
16272    // =========================================================
16273
16274    // Cause the target app to be launched if necessary and its backup agent
16275    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16276    // activity manager to announce its creation.
16277    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16278        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16279                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16280        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16281
16282        synchronized(this) {
16283            // !!! TODO: currently no check here that we're already bound
16284            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16285            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16286            synchronized (stats) {
16287                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16288            }
16289
16290            // Backup agent is now in use, its package can't be stopped.
16291            try {
16292                AppGlobals.getPackageManager().setPackageStoppedState(
16293                        app.packageName, false, UserHandle.getUserId(app.uid));
16294            } catch (RemoteException e) {
16295            } catch (IllegalArgumentException e) {
16296                Slog.w(TAG, "Failed trying to unstop package "
16297                        + app.packageName + ": " + e);
16298            }
16299
16300            BackupRecord r = new BackupRecord(ss, app, backupMode);
16301            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16302                    ? new ComponentName(app.packageName, app.backupAgentName)
16303                    : new ComponentName("android", "FullBackupAgent");
16304            // startProcessLocked() returns existing proc's record if it's already running
16305            ProcessRecord proc = startProcessLocked(app.processName, app,
16306                    false, 0, "backup", hostingName, false, false, false);
16307            if (proc == null) {
16308                Slog.e(TAG, "Unable to start backup agent process " + r);
16309                return false;
16310            }
16311
16312            r.app = proc;
16313            mBackupTarget = r;
16314            mBackupAppName = app.packageName;
16315
16316            // Try not to kill the process during backup
16317            updateOomAdjLocked(proc);
16318
16319            // If the process is already attached, schedule the creation of the backup agent now.
16320            // If it is not yet live, this will be done when it attaches to the framework.
16321            if (proc.thread != null) {
16322                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16323                try {
16324                    proc.thread.scheduleCreateBackupAgent(app,
16325                            compatibilityInfoForPackageLocked(app), backupMode);
16326                } catch (RemoteException e) {
16327                    // Will time out on the backup manager side
16328                }
16329            } else {
16330                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16331            }
16332            // Invariants: at this point, the target app process exists and the application
16333            // is either already running or in the process of coming up.  mBackupTarget and
16334            // mBackupAppName describe the app, so that when it binds back to the AM we
16335            // know that it's scheduled for a backup-agent operation.
16336        }
16337
16338        return true;
16339    }
16340
16341    @Override
16342    public void clearPendingBackup() {
16343        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16344        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16345
16346        synchronized (this) {
16347            mBackupTarget = null;
16348            mBackupAppName = null;
16349        }
16350    }
16351
16352    // A backup agent has just come up
16353    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16354        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16355                + " = " + agent);
16356
16357        synchronized(this) {
16358            if (!agentPackageName.equals(mBackupAppName)) {
16359                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16360                return;
16361            }
16362        }
16363
16364        long oldIdent = Binder.clearCallingIdentity();
16365        try {
16366            IBackupManager bm = IBackupManager.Stub.asInterface(
16367                    ServiceManager.getService(Context.BACKUP_SERVICE));
16368            bm.agentConnected(agentPackageName, agent);
16369        } catch (RemoteException e) {
16370            // can't happen; the backup manager service is local
16371        } catch (Exception e) {
16372            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16373            e.printStackTrace();
16374        } finally {
16375            Binder.restoreCallingIdentity(oldIdent);
16376        }
16377    }
16378
16379    // done with this agent
16380    public void unbindBackupAgent(ApplicationInfo appInfo) {
16381        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16382        if (appInfo == null) {
16383            Slog.w(TAG, "unbind backup agent for null app");
16384            return;
16385        }
16386
16387        synchronized(this) {
16388            try {
16389                if (mBackupAppName == null) {
16390                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16391                    return;
16392                }
16393
16394                if (!mBackupAppName.equals(appInfo.packageName)) {
16395                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16396                    return;
16397                }
16398
16399                // Not backing this app up any more; reset its OOM adjustment
16400                final ProcessRecord proc = mBackupTarget.app;
16401                updateOomAdjLocked(proc);
16402
16403                // If the app crashed during backup, 'thread' will be null here
16404                if (proc.thread != null) {
16405                    try {
16406                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16407                                compatibilityInfoForPackageLocked(appInfo));
16408                    } catch (Exception e) {
16409                        Slog.e(TAG, "Exception when unbinding backup agent:");
16410                        e.printStackTrace();
16411                    }
16412                }
16413            } finally {
16414                mBackupTarget = null;
16415                mBackupAppName = null;
16416            }
16417        }
16418    }
16419    // =========================================================
16420    // BROADCASTS
16421    // =========================================================
16422
16423    boolean isPendingBroadcastProcessLocked(int pid) {
16424        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16425                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16426    }
16427
16428    void skipPendingBroadcastLocked(int pid) {
16429            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16430            for (BroadcastQueue queue : mBroadcastQueues) {
16431                queue.skipPendingBroadcastLocked(pid);
16432            }
16433    }
16434
16435    // The app just attached; send any pending broadcasts that it should receive
16436    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16437        boolean didSomething = false;
16438        for (BroadcastQueue queue : mBroadcastQueues) {
16439            didSomething |= queue.sendPendingBroadcastsLocked(app);
16440        }
16441        return didSomething;
16442    }
16443
16444    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16445            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16446        enforceNotIsolatedCaller("registerReceiver");
16447        ArrayList<Intent> stickyIntents = null;
16448        ProcessRecord callerApp = null;
16449        int callingUid;
16450        int callingPid;
16451        synchronized(this) {
16452            if (caller != null) {
16453                callerApp = getRecordForAppLocked(caller);
16454                if (callerApp == null) {
16455                    throw new SecurityException(
16456                            "Unable to find app for caller " + caller
16457                            + " (pid=" + Binder.getCallingPid()
16458                            + ") when registering receiver " + receiver);
16459                }
16460                if (callerApp.info.uid != Process.SYSTEM_UID &&
16461                        !callerApp.pkgList.containsKey(callerPackage) &&
16462                        !"android".equals(callerPackage)) {
16463                    throw new SecurityException("Given caller package " + callerPackage
16464                            + " is not running in process " + callerApp);
16465                }
16466                callingUid = callerApp.info.uid;
16467                callingPid = callerApp.pid;
16468            } else {
16469                callerPackage = null;
16470                callingUid = Binder.getCallingUid();
16471                callingPid = Binder.getCallingPid();
16472            }
16473
16474            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16475                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16476
16477            Iterator<String> actions = filter.actionsIterator();
16478            if (actions == null) {
16479                ArrayList<String> noAction = new ArrayList<String>(1);
16480                noAction.add(null);
16481                actions = noAction.iterator();
16482            }
16483
16484            // Collect stickies of users
16485            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16486            while (actions.hasNext()) {
16487                String action = actions.next();
16488                for (int id : userIds) {
16489                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16490                    if (stickies != null) {
16491                        ArrayList<Intent> intents = stickies.get(action);
16492                        if (intents != null) {
16493                            if (stickyIntents == null) {
16494                                stickyIntents = new ArrayList<Intent>();
16495                            }
16496                            stickyIntents.addAll(intents);
16497                        }
16498                    }
16499                }
16500            }
16501        }
16502
16503        ArrayList<Intent> allSticky = null;
16504        if (stickyIntents != null) {
16505            final ContentResolver resolver = mContext.getContentResolver();
16506            // Look for any matching sticky broadcasts...
16507            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16508                Intent intent = stickyIntents.get(i);
16509                // If intent has scheme "content", it will need to acccess
16510                // provider that needs to lock mProviderMap in ActivityThread
16511                // and also it may need to wait application response, so we
16512                // cannot lock ActivityManagerService here.
16513                if (filter.match(resolver, intent, true, TAG) >= 0) {
16514                    if (allSticky == null) {
16515                        allSticky = new ArrayList<Intent>();
16516                    }
16517                    allSticky.add(intent);
16518                }
16519            }
16520        }
16521
16522        // The first sticky in the list is returned directly back to the client.
16523        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16524        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16525        if (receiver == null) {
16526            return sticky;
16527        }
16528
16529        synchronized (this) {
16530            if (callerApp != null && (callerApp.thread == null
16531                    || callerApp.thread.asBinder() != caller.asBinder())) {
16532                // Original caller already died
16533                return null;
16534            }
16535            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16536            if (rl == null) {
16537                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16538                        userId, receiver);
16539                if (rl.app != null) {
16540                    rl.app.receivers.add(rl);
16541                } else {
16542                    try {
16543                        receiver.asBinder().linkToDeath(rl, 0);
16544                    } catch (RemoteException e) {
16545                        return sticky;
16546                    }
16547                    rl.linkedToDeath = true;
16548                }
16549                mRegisteredReceivers.put(receiver.asBinder(), rl);
16550            } else if (rl.uid != callingUid) {
16551                throw new IllegalArgumentException(
16552                        "Receiver requested to register for uid " + callingUid
16553                        + " was previously registered for uid " + rl.uid);
16554            } else if (rl.pid != callingPid) {
16555                throw new IllegalArgumentException(
16556                        "Receiver requested to register for pid " + callingPid
16557                        + " was previously registered for pid " + rl.pid);
16558            } else if (rl.userId != userId) {
16559                throw new IllegalArgumentException(
16560                        "Receiver requested to register for user " + userId
16561                        + " was previously registered for user " + rl.userId);
16562            }
16563            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16564                    permission, callingUid, userId);
16565            rl.add(bf);
16566            if (!bf.debugCheck()) {
16567                Slog.w(TAG, "==> For Dynamic broadcast");
16568            }
16569            mReceiverResolver.addFilter(bf);
16570
16571            // Enqueue broadcasts for all existing stickies that match
16572            // this filter.
16573            if (allSticky != null) {
16574                ArrayList receivers = new ArrayList();
16575                receivers.add(bf);
16576
16577                final int stickyCount = allSticky.size();
16578                for (int i = 0; i < stickyCount; i++) {
16579                    Intent intent = allSticky.get(i);
16580                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16581                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16582                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16583                            null, 0, null, null, false, true, true, -1);
16584                    queue.enqueueParallelBroadcastLocked(r);
16585                    queue.scheduleBroadcastsLocked();
16586                }
16587            }
16588
16589            return sticky;
16590        }
16591    }
16592
16593    public void unregisterReceiver(IIntentReceiver receiver) {
16594        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16595
16596        final long origId = Binder.clearCallingIdentity();
16597        try {
16598            boolean doTrim = false;
16599
16600            synchronized(this) {
16601                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16602                if (rl != null) {
16603                    final BroadcastRecord r = rl.curBroadcast;
16604                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16605                        final boolean doNext = r.queue.finishReceiverLocked(
16606                                r, r.resultCode, r.resultData, r.resultExtras,
16607                                r.resultAbort, false);
16608                        if (doNext) {
16609                            doTrim = true;
16610                            r.queue.processNextBroadcast(false);
16611                        }
16612                    }
16613
16614                    if (rl.app != null) {
16615                        rl.app.receivers.remove(rl);
16616                    }
16617                    removeReceiverLocked(rl);
16618                    if (rl.linkedToDeath) {
16619                        rl.linkedToDeath = false;
16620                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16621                    }
16622                }
16623            }
16624
16625            // If we actually concluded any broadcasts, we might now be able
16626            // to trim the recipients' apps from our working set
16627            if (doTrim) {
16628                trimApplications();
16629                return;
16630            }
16631
16632        } finally {
16633            Binder.restoreCallingIdentity(origId);
16634        }
16635    }
16636
16637    void removeReceiverLocked(ReceiverList rl) {
16638        mRegisteredReceivers.remove(rl.receiver.asBinder());
16639        for (int i = rl.size() - 1; i >= 0; i--) {
16640            mReceiverResolver.removeFilter(rl.get(i));
16641        }
16642    }
16643
16644    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16645        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16646            ProcessRecord r = mLruProcesses.get(i);
16647            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16648                try {
16649                    r.thread.dispatchPackageBroadcast(cmd, packages);
16650                } catch (RemoteException ex) {
16651                }
16652            }
16653        }
16654    }
16655
16656    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16657            int callingUid, int[] users) {
16658        List<ResolveInfo> receivers = null;
16659        try {
16660            HashSet<ComponentName> singleUserReceivers = null;
16661            boolean scannedFirstReceivers = false;
16662            for (int user : users) {
16663                // Skip users that have Shell restrictions
16664                if (callingUid == Process.SHELL_UID
16665                        && mUserController.hasUserRestriction(
16666                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16667                    continue;
16668                }
16669                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16670                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16671                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16672                    // If this is not the system user, we need to check for
16673                    // any receivers that should be filtered out.
16674                    for (int i=0; i<newReceivers.size(); i++) {
16675                        ResolveInfo ri = newReceivers.get(i);
16676                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16677                            newReceivers.remove(i);
16678                            i--;
16679                        }
16680                    }
16681                }
16682                if (newReceivers != null && newReceivers.size() == 0) {
16683                    newReceivers = null;
16684                }
16685                if (receivers == null) {
16686                    receivers = newReceivers;
16687                } else if (newReceivers != null) {
16688                    // We need to concatenate the additional receivers
16689                    // found with what we have do far.  This would be easy,
16690                    // but we also need to de-dup any receivers that are
16691                    // singleUser.
16692                    if (!scannedFirstReceivers) {
16693                        // Collect any single user receivers we had already retrieved.
16694                        scannedFirstReceivers = true;
16695                        for (int i=0; i<receivers.size(); i++) {
16696                            ResolveInfo ri = receivers.get(i);
16697                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16698                                ComponentName cn = new ComponentName(
16699                                        ri.activityInfo.packageName, ri.activityInfo.name);
16700                                if (singleUserReceivers == null) {
16701                                    singleUserReceivers = new HashSet<ComponentName>();
16702                                }
16703                                singleUserReceivers.add(cn);
16704                            }
16705                        }
16706                    }
16707                    // Add the new results to the existing results, tracking
16708                    // and de-dupping single user receivers.
16709                    for (int i=0; i<newReceivers.size(); i++) {
16710                        ResolveInfo ri = newReceivers.get(i);
16711                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16712                            ComponentName cn = new ComponentName(
16713                                    ri.activityInfo.packageName, ri.activityInfo.name);
16714                            if (singleUserReceivers == null) {
16715                                singleUserReceivers = new HashSet<ComponentName>();
16716                            }
16717                            if (!singleUserReceivers.contains(cn)) {
16718                                singleUserReceivers.add(cn);
16719                                receivers.add(ri);
16720                            }
16721                        } else {
16722                            receivers.add(ri);
16723                        }
16724                    }
16725                }
16726            }
16727        } catch (RemoteException ex) {
16728            // pm is in same process, this will never happen.
16729        }
16730        return receivers;
16731    }
16732
16733    final int broadcastIntentLocked(ProcessRecord callerApp,
16734            String callerPackage, Intent intent, String resolvedType,
16735            IIntentReceiver resultTo, int resultCode, String resultData,
16736            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16737            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16738        intent = new Intent(intent);
16739
16740        // By default broadcasts do not go to stopped apps.
16741        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16742
16743        // If we have not finished booting, don't allow this to launch new processes.
16744        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16745            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16746        }
16747
16748        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16749                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16750                + " ordered=" + ordered + " userid=" + userId);
16751        if ((resultTo != null) && !ordered) {
16752            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16753        }
16754
16755        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16756                ALLOW_NON_FULL, "broadcast", callerPackage);
16757
16758        // Make sure that the user who is receiving this broadcast is running.
16759        // If not, we will just skip it. Make an exception for shutdown broadcasts
16760        // and upgrade steps.
16761
16762        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16763            if ((callingUid != Process.SYSTEM_UID
16764                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16765                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16766                Slog.w(TAG, "Skipping broadcast of " + intent
16767                        + ": user " + userId + " is stopped");
16768                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16769            }
16770        }
16771
16772        BroadcastOptions brOptions = null;
16773        if (bOptions != null) {
16774            brOptions = new BroadcastOptions(bOptions);
16775            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16776                // See if the caller is allowed to do this.  Note we are checking against
16777                // the actual real caller (not whoever provided the operation as say a
16778                // PendingIntent), because that who is actually supplied the arguments.
16779                if (checkComponentPermission(
16780                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16781                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16782                        != PackageManager.PERMISSION_GRANTED) {
16783                    String msg = "Permission Denial: " + intent.getAction()
16784                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16785                            + ", uid=" + callingUid + ")"
16786                            + " requires "
16787                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16788                    Slog.w(TAG, msg);
16789                    throw new SecurityException(msg);
16790                }
16791            }
16792        }
16793
16794        /*
16795         * Prevent non-system code (defined here to be non-persistent
16796         * processes) from sending protected broadcasts.
16797         */
16798        int callingAppId = UserHandle.getAppId(callingUid);
16799        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16800            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16801            || callingAppId == Process.NFC_UID || callingUid == 0) {
16802            // Always okay.
16803        } else if (callerApp == null || !callerApp.persistent) {
16804            try {
16805                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16806                        intent.getAction())) {
16807                    String msg = "Permission Denial: not allowed to send broadcast "
16808                            + intent.getAction() + " from pid="
16809                            + callingPid + ", uid=" + callingUid;
16810                    Slog.w(TAG, msg);
16811                    throw new SecurityException(msg);
16812                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16813                    // Special case for compatibility: we don't want apps to send this,
16814                    // but historically it has not been protected and apps may be using it
16815                    // to poke their own app widget.  So, instead of making it protected,
16816                    // just limit it to the caller.
16817                    if (callerApp == null) {
16818                        String msg = "Permission Denial: not allowed to send broadcast "
16819                                + intent.getAction() + " from unknown caller.";
16820                        Slog.w(TAG, msg);
16821                        throw new SecurityException(msg);
16822                    } else if (intent.getComponent() != null) {
16823                        // They are good enough to send to an explicit component...  verify
16824                        // it is being sent to the calling app.
16825                        if (!intent.getComponent().getPackageName().equals(
16826                                callerApp.info.packageName)) {
16827                            String msg = "Permission Denial: not allowed to send broadcast "
16828                                    + intent.getAction() + " to "
16829                                    + intent.getComponent().getPackageName() + " from "
16830                                    + callerApp.info.packageName;
16831                            Slog.w(TAG, msg);
16832                            throw new SecurityException(msg);
16833                        }
16834                    } else {
16835                        // Limit broadcast to their own package.
16836                        intent.setPackage(callerApp.info.packageName);
16837                    }
16838                }
16839            } catch (RemoteException e) {
16840                Slog.w(TAG, "Remote exception", e);
16841                return ActivityManager.BROADCAST_SUCCESS;
16842            }
16843        }
16844
16845        final String action = intent.getAction();
16846        if (action != null) {
16847            switch (action) {
16848                case Intent.ACTION_UID_REMOVED:
16849                case Intent.ACTION_PACKAGE_REMOVED:
16850                case Intent.ACTION_PACKAGE_CHANGED:
16851                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16852                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16853                    // Handle special intents: if this broadcast is from the package
16854                    // manager about a package being removed, we need to remove all of
16855                    // its activities from the history stack.
16856                    if (checkComponentPermission(
16857                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16858                            callingPid, callingUid, -1, true)
16859                            != PackageManager.PERMISSION_GRANTED) {
16860                        String msg = "Permission Denial: " + intent.getAction()
16861                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16862                                + ", uid=" + callingUid + ")"
16863                                + " requires "
16864                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16865                        Slog.w(TAG, msg);
16866                        throw new SecurityException(msg);
16867                    }
16868                    switch (action) {
16869                        case Intent.ACTION_UID_REMOVED:
16870                            final Bundle intentExtras = intent.getExtras();
16871                            final int uid = intentExtras != null
16872                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16873                            if (uid >= 0) {
16874                                mBatteryStatsService.removeUid(uid);
16875                                mAppOpsService.uidRemoved(uid);
16876                            }
16877                            break;
16878                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16879                            // If resources are unavailable just force stop all those packages
16880                            // and flush the attribute cache as well.
16881                            String list[] =
16882                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16883                            if (list != null && list.length > 0) {
16884                                for (int i = 0; i < list.length; i++) {
16885                                    forceStopPackageLocked(list[i], -1, false, true, true,
16886                                            false, false, userId, "storage unmount");
16887                                }
16888                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16889                                sendPackageBroadcastLocked(
16890                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16891                                        userId);
16892                            }
16893                            break;
16894                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16895                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16896                            break;
16897                        case Intent.ACTION_PACKAGE_REMOVED:
16898                        case Intent.ACTION_PACKAGE_CHANGED:
16899                            Uri data = intent.getData();
16900                            String ssp;
16901                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16902                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16903                                boolean fullUninstall = removed &&
16904                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16905                                final boolean killProcess =
16906                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16907                                if (killProcess) {
16908                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16909                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16910                                            false, true, true, false, fullUninstall, userId,
16911                                            removed ? "pkg removed" : "pkg changed");
16912                                }
16913                                if (removed) {
16914                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16915                                            new String[] {ssp}, userId);
16916                                    if (fullUninstall) {
16917                                        mAppOpsService.packageRemoved(
16918                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16919
16920                                        // Remove all permissions granted from/to this package
16921                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16922
16923                                        removeTasksByPackageNameLocked(ssp, userId);
16924                                        mBatteryStatsService.notePackageUninstalled(ssp);
16925                                    }
16926                                } else {
16927                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16928                                            intent.getStringArrayExtra(
16929                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16930                                }
16931                            }
16932                            break;
16933                    }
16934                    break;
16935                case Intent.ACTION_PACKAGE_ADDED:
16936                    // Special case for adding a package: by default turn on compatibility mode.
16937                    Uri data = intent.getData();
16938                    String ssp;
16939                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16940                        final boolean replacing =
16941                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16942                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16943
16944                        try {
16945                            ApplicationInfo ai = AppGlobals.getPackageManager().
16946                                    getApplicationInfo(ssp, 0, 0);
16947                            mBatteryStatsService.notePackageInstalled(ssp,
16948                                    ai != null ? ai.versionCode : 0);
16949                        } catch (RemoteException e) {
16950                        }
16951                    }
16952                    break;
16953                case Intent.ACTION_TIMEZONE_CHANGED:
16954                    // If this is the time zone changed action, queue up a message that will reset
16955                    // the timezone of all currently running processes. This message will get
16956                    // queued up before the broadcast happens.
16957                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16958                    break;
16959                case Intent.ACTION_TIME_CHANGED:
16960                    // If the user set the time, let all running processes know.
16961                    final int is24Hour =
16962                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16963                                    : 0;
16964                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16965                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16966                    synchronized (stats) {
16967                        stats.noteCurrentTimeChangedLocked();
16968                    }
16969                    break;
16970                case Intent.ACTION_CLEAR_DNS_CACHE:
16971                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16972                    break;
16973                case Proxy.PROXY_CHANGE_ACTION:
16974                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16975                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16976                    break;
16977            }
16978        }
16979
16980        // Add to the sticky list if requested.
16981        if (sticky) {
16982            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16983                    callingPid, callingUid)
16984                    != PackageManager.PERMISSION_GRANTED) {
16985                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16986                        + callingPid + ", uid=" + callingUid
16987                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16988                Slog.w(TAG, msg);
16989                throw new SecurityException(msg);
16990            }
16991            if (requiredPermissions != null && requiredPermissions.length > 0) {
16992                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16993                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16994                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16995            }
16996            if (intent.getComponent() != null) {
16997                throw new SecurityException(
16998                        "Sticky broadcasts can't target a specific component");
16999            }
17000            // We use userId directly here, since the "all" target is maintained
17001            // as a separate set of sticky broadcasts.
17002            if (userId != UserHandle.USER_ALL) {
17003                // But first, if this is not a broadcast to all users, then
17004                // make sure it doesn't conflict with an existing broadcast to
17005                // all users.
17006                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17007                        UserHandle.USER_ALL);
17008                if (stickies != null) {
17009                    ArrayList<Intent> list = stickies.get(intent.getAction());
17010                    if (list != null) {
17011                        int N = list.size();
17012                        int i;
17013                        for (i=0; i<N; i++) {
17014                            if (intent.filterEquals(list.get(i))) {
17015                                throw new IllegalArgumentException(
17016                                        "Sticky broadcast " + intent + " for user "
17017                                        + userId + " conflicts with existing global broadcast");
17018                            }
17019                        }
17020                    }
17021                }
17022            }
17023            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17024            if (stickies == null) {
17025                stickies = new ArrayMap<>();
17026                mStickyBroadcasts.put(userId, stickies);
17027            }
17028            ArrayList<Intent> list = stickies.get(intent.getAction());
17029            if (list == null) {
17030                list = new ArrayList<>();
17031                stickies.put(intent.getAction(), list);
17032            }
17033            final int stickiesCount = list.size();
17034            int i;
17035            for (i = 0; i < stickiesCount; i++) {
17036                if (intent.filterEquals(list.get(i))) {
17037                    // This sticky already exists, replace it.
17038                    list.set(i, new Intent(intent));
17039                    break;
17040                }
17041            }
17042            if (i >= stickiesCount) {
17043                list.add(new Intent(intent));
17044            }
17045        }
17046
17047        int[] users;
17048        if (userId == UserHandle.USER_ALL) {
17049            // Caller wants broadcast to go to all started users.
17050            users = mUserController.getStartedUserArrayLocked();
17051        } else {
17052            // Caller wants broadcast to go to one specific user.
17053            users = new int[] {userId};
17054        }
17055
17056        // Figure out who all will receive this broadcast.
17057        List receivers = null;
17058        List<BroadcastFilter> registeredReceivers = null;
17059        // Need to resolve the intent to interested receivers...
17060        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17061                 == 0) {
17062            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17063        }
17064        if (intent.getComponent() == null) {
17065            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17066                // Query one target user at a time, excluding shell-restricted users
17067                for (int i = 0; i < users.length; i++) {
17068                    if (mUserController.hasUserRestriction(
17069                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17070                        continue;
17071                    }
17072                    List<BroadcastFilter> registeredReceiversForUser =
17073                            mReceiverResolver.queryIntent(intent,
17074                                    resolvedType, false, users[i]);
17075                    if (registeredReceivers == null) {
17076                        registeredReceivers = registeredReceiversForUser;
17077                    } else if (registeredReceiversForUser != null) {
17078                        registeredReceivers.addAll(registeredReceiversForUser);
17079                    }
17080                }
17081            } else {
17082                registeredReceivers = mReceiverResolver.queryIntent(intent,
17083                        resolvedType, false, userId);
17084            }
17085        }
17086
17087        final boolean replacePending =
17088                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17089
17090        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17091                + " replacePending=" + replacePending);
17092
17093        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17094        if (!ordered && NR > 0) {
17095            // If we are not serializing this broadcast, then send the
17096            // registered receivers separately so they don't wait for the
17097            // components to be launched.
17098            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17099            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17100                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17101                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17102                    resultExtras, ordered, sticky, false, userId);
17103            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17104            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17105            if (!replaced) {
17106                queue.enqueueParallelBroadcastLocked(r);
17107                queue.scheduleBroadcastsLocked();
17108            }
17109            registeredReceivers = null;
17110            NR = 0;
17111        }
17112
17113        // Merge into one list.
17114        int ir = 0;
17115        if (receivers != null) {
17116            // A special case for PACKAGE_ADDED: do not allow the package
17117            // being added to see this broadcast.  This prevents them from
17118            // using this as a back door to get run as soon as they are
17119            // installed.  Maybe in the future we want to have a special install
17120            // broadcast or such for apps, but we'd like to deliberately make
17121            // this decision.
17122            String skipPackages[] = null;
17123            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17124                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17125                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17126                Uri data = intent.getData();
17127                if (data != null) {
17128                    String pkgName = data.getSchemeSpecificPart();
17129                    if (pkgName != null) {
17130                        skipPackages = new String[] { pkgName };
17131                    }
17132                }
17133            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17134                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17135            }
17136            if (skipPackages != null && (skipPackages.length > 0)) {
17137                for (String skipPackage : skipPackages) {
17138                    if (skipPackage != null) {
17139                        int NT = receivers.size();
17140                        for (int it=0; it<NT; it++) {
17141                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17142                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17143                                receivers.remove(it);
17144                                it--;
17145                                NT--;
17146                            }
17147                        }
17148                    }
17149                }
17150            }
17151
17152            int NT = receivers != null ? receivers.size() : 0;
17153            int it = 0;
17154            ResolveInfo curt = null;
17155            BroadcastFilter curr = null;
17156            while (it < NT && ir < NR) {
17157                if (curt == null) {
17158                    curt = (ResolveInfo)receivers.get(it);
17159                }
17160                if (curr == null) {
17161                    curr = registeredReceivers.get(ir);
17162                }
17163                if (curr.getPriority() >= curt.priority) {
17164                    // Insert this broadcast record into the final list.
17165                    receivers.add(it, curr);
17166                    ir++;
17167                    curr = null;
17168                    it++;
17169                    NT++;
17170                } else {
17171                    // Skip to the next ResolveInfo in the final list.
17172                    it++;
17173                    curt = null;
17174                }
17175            }
17176        }
17177        while (ir < NR) {
17178            if (receivers == null) {
17179                receivers = new ArrayList();
17180            }
17181            receivers.add(registeredReceivers.get(ir));
17182            ir++;
17183        }
17184
17185        if ((receivers != null && receivers.size() > 0)
17186                || resultTo != null) {
17187            BroadcastQueue queue = broadcastQueueForIntent(intent);
17188            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17189                    callerPackage, callingPid, callingUid, resolvedType,
17190                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17191                    resultData, resultExtras, ordered, sticky, false, userId);
17192
17193            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17194                    + ": prev had " + queue.mOrderedBroadcasts.size());
17195            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17196                    "Enqueueing broadcast " + r.intent.getAction());
17197
17198            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17199            if (!replaced) {
17200                queue.enqueueOrderedBroadcastLocked(r);
17201                queue.scheduleBroadcastsLocked();
17202            }
17203        }
17204
17205        return ActivityManager.BROADCAST_SUCCESS;
17206    }
17207
17208    final Intent verifyBroadcastLocked(Intent intent) {
17209        // Refuse possible leaked file descriptors
17210        if (intent != null && intent.hasFileDescriptors() == true) {
17211            throw new IllegalArgumentException("File descriptors passed in Intent");
17212        }
17213
17214        int flags = intent.getFlags();
17215
17216        if (!mProcessesReady) {
17217            // if the caller really truly claims to know what they're doing, go
17218            // ahead and allow the broadcast without launching any receivers
17219            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17220                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17221            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17222                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17223                        + " before boot completion");
17224                throw new IllegalStateException("Cannot broadcast before boot completed");
17225            }
17226        }
17227
17228        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17229            throw new IllegalArgumentException(
17230                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17231        }
17232
17233        return intent;
17234    }
17235
17236    public final int broadcastIntent(IApplicationThread caller,
17237            Intent intent, String resolvedType, IIntentReceiver resultTo,
17238            int resultCode, String resultData, Bundle resultExtras,
17239            String[] requiredPermissions, int appOp, Bundle bOptions,
17240            boolean serialized, boolean sticky, int userId) {
17241        enforceNotIsolatedCaller("broadcastIntent");
17242        synchronized(this) {
17243            intent = verifyBroadcastLocked(intent);
17244
17245            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17246            final int callingPid = Binder.getCallingPid();
17247            final int callingUid = Binder.getCallingUid();
17248            final long origId = Binder.clearCallingIdentity();
17249            int res = broadcastIntentLocked(callerApp,
17250                    callerApp != null ? callerApp.info.packageName : null,
17251                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17252                    requiredPermissions, appOp, null, serialized, sticky,
17253                    callingPid, callingUid, userId);
17254            Binder.restoreCallingIdentity(origId);
17255            return res;
17256        }
17257    }
17258
17259
17260    int broadcastIntentInPackage(String packageName, int uid,
17261            Intent intent, String resolvedType, IIntentReceiver resultTo,
17262            int resultCode, String resultData, Bundle resultExtras,
17263            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17264            int userId) {
17265        synchronized(this) {
17266            intent = verifyBroadcastLocked(intent);
17267
17268            final long origId = Binder.clearCallingIdentity();
17269            String[] requiredPermissions = requiredPermission == null ? null
17270                    : new String[] {requiredPermission};
17271            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17272                    resultTo, resultCode, resultData, resultExtras,
17273                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17274                    sticky, -1, uid, userId);
17275            Binder.restoreCallingIdentity(origId);
17276            return res;
17277        }
17278    }
17279
17280    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17281        // Refuse possible leaked file descriptors
17282        if (intent != null && intent.hasFileDescriptors() == true) {
17283            throw new IllegalArgumentException("File descriptors passed in Intent");
17284        }
17285
17286        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17287                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17288
17289        synchronized(this) {
17290            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17291                    != PackageManager.PERMISSION_GRANTED) {
17292                String msg = "Permission Denial: unbroadcastIntent() from pid="
17293                        + Binder.getCallingPid()
17294                        + ", uid=" + Binder.getCallingUid()
17295                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17296                Slog.w(TAG, msg);
17297                throw new SecurityException(msg);
17298            }
17299            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17300            if (stickies != null) {
17301                ArrayList<Intent> list = stickies.get(intent.getAction());
17302                if (list != null) {
17303                    int N = list.size();
17304                    int i;
17305                    for (i=0; i<N; i++) {
17306                        if (intent.filterEquals(list.get(i))) {
17307                            list.remove(i);
17308                            break;
17309                        }
17310                    }
17311                    if (list.size() <= 0) {
17312                        stickies.remove(intent.getAction());
17313                    }
17314                }
17315                if (stickies.size() <= 0) {
17316                    mStickyBroadcasts.remove(userId);
17317                }
17318            }
17319        }
17320    }
17321
17322    void backgroundServicesFinishedLocked(int userId) {
17323        for (BroadcastQueue queue : mBroadcastQueues) {
17324            queue.backgroundServicesFinishedLocked(userId);
17325        }
17326    }
17327
17328    public void finishReceiver(IBinder who, int resultCode, String resultData,
17329            Bundle resultExtras, boolean resultAbort, int flags) {
17330        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17331
17332        // Refuse possible leaked file descriptors
17333        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17334            throw new IllegalArgumentException("File descriptors passed in Bundle");
17335        }
17336
17337        final long origId = Binder.clearCallingIdentity();
17338        try {
17339            boolean doNext = false;
17340            BroadcastRecord r;
17341
17342            synchronized(this) {
17343                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17344                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17345                r = queue.getMatchingOrderedReceiver(who);
17346                if (r != null) {
17347                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17348                        resultData, resultExtras, resultAbort, true);
17349                }
17350            }
17351
17352            if (doNext) {
17353                r.queue.processNextBroadcast(false);
17354            }
17355            trimApplications();
17356        } finally {
17357            Binder.restoreCallingIdentity(origId);
17358        }
17359    }
17360
17361    // =========================================================
17362    // INSTRUMENTATION
17363    // =========================================================
17364
17365    public boolean startInstrumentation(ComponentName className,
17366            String profileFile, int flags, Bundle arguments,
17367            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17368            int userId, String abiOverride) {
17369        enforceNotIsolatedCaller("startInstrumentation");
17370        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17371                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17372        // Refuse possible leaked file descriptors
17373        if (arguments != null && arguments.hasFileDescriptors()) {
17374            throw new IllegalArgumentException("File descriptors passed in Bundle");
17375        }
17376
17377        synchronized(this) {
17378            InstrumentationInfo ii = null;
17379            ApplicationInfo ai = null;
17380            try {
17381                ii = mContext.getPackageManager().getInstrumentationInfo(
17382                    className, STOCK_PM_FLAGS);
17383                ai = AppGlobals.getPackageManager().getApplicationInfo(
17384                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17385            } catch (PackageManager.NameNotFoundException e) {
17386            } catch (RemoteException e) {
17387            }
17388            if (ii == null) {
17389                reportStartInstrumentationFailure(watcher, className,
17390                        "Unable to find instrumentation info for: " + className);
17391                return false;
17392            }
17393            if (ai == null) {
17394                reportStartInstrumentationFailure(watcher, className,
17395                        "Unable to find instrumentation target package: " + ii.targetPackage);
17396                return false;
17397            }
17398
17399            int match = mContext.getPackageManager().checkSignatures(
17400                    ii.targetPackage, ii.packageName);
17401            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17402                String msg = "Permission Denial: starting instrumentation "
17403                        + className + " from pid="
17404                        + Binder.getCallingPid()
17405                        + ", uid=" + Binder.getCallingPid()
17406                        + " not allowed because package " + ii.packageName
17407                        + " does not have a signature matching the target "
17408                        + ii.targetPackage;
17409                reportStartInstrumentationFailure(watcher, className, msg);
17410                throw new SecurityException(msg);
17411            }
17412
17413            final long origId = Binder.clearCallingIdentity();
17414            // Instrumentation can kill and relaunch even persistent processes
17415            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17416                    "start instr");
17417            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17418            app.instrumentationClass = className;
17419            app.instrumentationInfo = ai;
17420            app.instrumentationProfileFile = profileFile;
17421            app.instrumentationArguments = arguments;
17422            app.instrumentationWatcher = watcher;
17423            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17424            app.instrumentationResultClass = className;
17425            Binder.restoreCallingIdentity(origId);
17426        }
17427
17428        return true;
17429    }
17430
17431    /**
17432     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17433     * error to the logs, but if somebody is watching, send the report there too.  This enables
17434     * the "am" command to report errors with more information.
17435     *
17436     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17437     * @param cn The component name of the instrumentation.
17438     * @param report The error report.
17439     */
17440    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17441            ComponentName cn, String report) {
17442        Slog.w(TAG, report);
17443        try {
17444            if (watcher != null) {
17445                Bundle results = new Bundle();
17446                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17447                results.putString("Error", report);
17448                watcher.instrumentationStatus(cn, -1, results);
17449            }
17450        } catch (RemoteException e) {
17451            Slog.w(TAG, e);
17452        }
17453    }
17454
17455    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17456        if (app.instrumentationWatcher != null) {
17457            try {
17458                // NOTE:  IInstrumentationWatcher *must* be oneway here
17459                app.instrumentationWatcher.instrumentationFinished(
17460                    app.instrumentationClass,
17461                    resultCode,
17462                    results);
17463            } catch (RemoteException e) {
17464            }
17465        }
17466
17467        // Can't call out of the system process with a lock held, so post a message.
17468        if (app.instrumentationUiAutomationConnection != null) {
17469            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17470                    app.instrumentationUiAutomationConnection).sendToTarget();
17471        }
17472
17473        app.instrumentationWatcher = null;
17474        app.instrumentationUiAutomationConnection = null;
17475        app.instrumentationClass = null;
17476        app.instrumentationInfo = null;
17477        app.instrumentationProfileFile = null;
17478        app.instrumentationArguments = null;
17479
17480        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17481                "finished inst");
17482    }
17483
17484    public void finishInstrumentation(IApplicationThread target,
17485            int resultCode, Bundle results) {
17486        int userId = UserHandle.getCallingUserId();
17487        // Refuse possible leaked file descriptors
17488        if (results != null && results.hasFileDescriptors()) {
17489            throw new IllegalArgumentException("File descriptors passed in Intent");
17490        }
17491
17492        synchronized(this) {
17493            ProcessRecord app = getRecordForAppLocked(target);
17494            if (app == null) {
17495                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17496                return;
17497            }
17498            final long origId = Binder.clearCallingIdentity();
17499            finishInstrumentationLocked(app, resultCode, results);
17500            Binder.restoreCallingIdentity(origId);
17501        }
17502    }
17503
17504    // =========================================================
17505    // CONFIGURATION
17506    // =========================================================
17507
17508    public ConfigurationInfo getDeviceConfigurationInfo() {
17509        ConfigurationInfo config = new ConfigurationInfo();
17510        synchronized (this) {
17511            config.reqTouchScreen = mConfiguration.touchscreen;
17512            config.reqKeyboardType = mConfiguration.keyboard;
17513            config.reqNavigation = mConfiguration.navigation;
17514            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17515                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17516                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17517            }
17518            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17519                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17520                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17521            }
17522            config.reqGlEsVersion = GL_ES_VERSION;
17523        }
17524        return config;
17525    }
17526
17527    ActivityStack getFocusedStack() {
17528        return mStackSupervisor.getFocusedStack();
17529    }
17530
17531    @Override
17532    public int getFocusedStackId() throws RemoteException {
17533        ActivityStack focusedStack = getFocusedStack();
17534        if (focusedStack != null) {
17535            return focusedStack.getStackId();
17536        }
17537        return -1;
17538    }
17539
17540    public Configuration getConfiguration() {
17541        Configuration ci;
17542        synchronized(this) {
17543            ci = new Configuration(mConfiguration);
17544            ci.userSetLocale = false;
17545        }
17546        return ci;
17547    }
17548
17549    @Override
17550    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17551        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17552                "suppressResizeConfigChanges()");
17553        synchronized (this) {
17554            mSuppressResizeConfigChanges = suppress;
17555        }
17556    }
17557
17558    @Override
17559    public void removeStack(int stackId) {
17560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17561                "detahStack()");
17562        if (stackId == HOME_STACK_ID) {
17563            throw new IllegalArgumentException("Removing home stack is not allowed.");
17564        }
17565        synchronized (this) {
17566            long origId = Binder.clearCallingIdentity();
17567            ActivityStack stack = mStackSupervisor.getStack(stackId);
17568            if (stack != null) {
17569                ArrayList<TaskRecord> tasks = stack.getAllTasks();
17570                for (int i = tasks.size() - 1; i >= 0; i--) {
17571                    removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
17572                            !REMOVE_FROM_RECENTS);
17573                }
17574            }
17575            Binder.restoreCallingIdentity(origId);
17576        }
17577    }
17578
17579    @Override
17580    public void updatePersistentConfiguration(Configuration values) {
17581        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17582                "updateConfiguration()");
17583        enforceWriteSettingsPermission("updateConfiguration()");
17584        if (values == null) {
17585            throw new NullPointerException("Configuration must not be null");
17586        }
17587
17588        int userId = UserHandle.getCallingUserId();
17589
17590        synchronized(this) {
17591            final long origId = Binder.clearCallingIdentity();
17592            updateConfigurationLocked(values, null, false, true, userId);
17593            Binder.restoreCallingIdentity(origId);
17594        }
17595    }
17596
17597    private void enforceWriteSettingsPermission(String func) {
17598        int uid = Binder.getCallingUid();
17599        if (uid == Process.ROOT_UID) {
17600            return;
17601        }
17602
17603        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17604                Settings.getPackageNameForUid(mContext, uid), false)) {
17605            return;
17606        }
17607
17608        String msg = "Permission Denial: " + func + " from pid="
17609                + Binder.getCallingPid()
17610                + ", uid=" + uid
17611                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17612        Slog.w(TAG, msg);
17613        throw new SecurityException(msg);
17614    }
17615
17616    public void updateConfiguration(Configuration values) {
17617        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17618                "updateConfiguration()");
17619
17620        synchronized(this) {
17621            if (values == null && mWindowManager != null) {
17622                // sentinel: fetch the current configuration from the window manager
17623                values = mWindowManager.computeNewConfiguration();
17624            }
17625
17626            if (mWindowManager != null) {
17627                mProcessList.applyDisplaySize(mWindowManager);
17628            }
17629
17630            final long origId = Binder.clearCallingIdentity();
17631            if (values != null) {
17632                Settings.System.clearConfiguration(values);
17633            }
17634            updateConfigurationLocked(values, null, false);
17635            Binder.restoreCallingIdentity(origId);
17636        }
17637    }
17638
17639    void updateUserConfigurationLocked() {
17640        Configuration configuration = new Configuration(mConfiguration);
17641        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17642                mUserController.getCurrentUserIdLocked());
17643        updateConfigurationLocked(configuration, null, false);
17644    }
17645
17646    boolean updateConfigurationLocked(Configuration values,
17647            ActivityRecord starting, boolean initLocale) {
17648        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17649        return updateConfigurationLocked(values, starting, initLocale, false,
17650                UserHandle.USER_NULL);
17651    }
17652
17653    /**
17654     * Do either or both things: (1) change the current configuration, and (2)
17655     * make sure the given activity is running with the (now) current
17656     * configuration.  Returns true if the activity has been left running, or
17657     * false if <var>starting</var> is being destroyed to match the new
17658     * configuration.
17659     *
17660     * @param userId is only used when persistent parameter is set to true to persist configuration
17661     *               for that particular user
17662     */
17663    boolean updateConfigurationLocked(Configuration values,
17664            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17665        int changes = 0;
17666
17667        if (values != null) {
17668            Configuration newConfig = new Configuration(mConfiguration);
17669            changes = newConfig.updateFrom(values);
17670            if (changes != 0) {
17671                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17672                        "Updating configuration to: " + values);
17673
17674                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17675
17676                if (!initLocale && values.locale != null && values.userSetLocale) {
17677                    final String languageTag = values.locale.toLanguageTag();
17678                    SystemProperties.set("persist.sys.locale", languageTag);
17679                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17680                            values.locale));
17681                }
17682
17683                mConfigurationSeq++;
17684                if (mConfigurationSeq <= 0) {
17685                    mConfigurationSeq = 1;
17686                }
17687                newConfig.seq = mConfigurationSeq;
17688                mConfiguration = newConfig;
17689                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17690                mUsageStatsService.reportConfigurationChange(newConfig,
17691                        mUserController.getCurrentUserIdLocked());
17692                //mUsageStatsService.noteStartConfig(newConfig);
17693
17694                final Configuration configCopy = new Configuration(mConfiguration);
17695
17696                // TODO: If our config changes, should we auto dismiss any currently
17697                // showing dialogs?
17698                mShowDialogs = shouldShowDialogs(newConfig);
17699
17700                AttributeCache ac = AttributeCache.instance();
17701                if (ac != null) {
17702                    ac.updateConfiguration(configCopy);
17703                }
17704
17705                // Make sure all resources in our process are updated
17706                // right now, so that anyone who is going to retrieve
17707                // resource values after we return will be sure to get
17708                // the new ones.  This is especially important during
17709                // boot, where the first config change needs to guarantee
17710                // all resources have that config before following boot
17711                // code is executed.
17712                mSystemThread.applyConfigurationToResources(configCopy);
17713
17714                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17715                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17716                    msg.obj = new Configuration(configCopy);
17717                    msg.arg1 = userId;
17718                    mHandler.sendMessage(msg);
17719                }
17720
17721                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17722                    ProcessRecord app = mLruProcesses.get(i);
17723                    try {
17724                        if (app.thread != null) {
17725                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17726                                    + app.processName + " new config " + mConfiguration);
17727                            app.thread.scheduleConfigurationChanged(configCopy);
17728                        }
17729                    } catch (Exception e) {
17730                    }
17731                }
17732                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17733                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17734                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17735                        | Intent.FLAG_RECEIVER_FOREGROUND);
17736                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17737                        null, AppOpsManager.OP_NONE, null, false, false,
17738                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17739                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17740                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17741                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17742                    if (!mProcessesReady) {
17743                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17744                    }
17745                    broadcastIntentLocked(null, null, intent,
17746                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17747                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17748                }
17749            }
17750        }
17751
17752        boolean kept = true;
17753        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17754        // mainStack is null during startup.
17755        if (mainStack != null) {
17756            if (changes != 0 && starting == null) {
17757                // If the configuration changed, and the caller is not already
17758                // in the process of starting an activity, then find the top
17759                // activity to check if its configuration needs to change.
17760                starting = mainStack.topRunningActivityLocked();
17761            }
17762
17763            if (starting != null) {
17764                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17765                // And we need to make sure at this point that all other activities
17766                // are made visible with the correct configuration.
17767                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17768                        !PRESERVE_WINDOWS);
17769            }
17770        }
17771
17772        if (values != null && mWindowManager != null) {
17773            mWindowManager.setNewConfiguration(mConfiguration);
17774        }
17775
17776        return kept;
17777    }
17778
17779    /**
17780     * Decide based on the configuration whether we should shouw the ANR,
17781     * crash, etc dialogs.  The idea is that if there is no affordnace to
17782     * press the on-screen buttons, we shouldn't show the dialog.
17783     *
17784     * A thought: SystemUI might also want to get told about this, the Power
17785     * dialog / global actions also might want different behaviors.
17786     */
17787    private static final boolean shouldShowDialogs(Configuration config) {
17788        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17789                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17790                && config.navigation == Configuration.NAVIGATION_NONAV);
17791    }
17792
17793    @Override
17794    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17795        synchronized (this) {
17796            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17797            if (srec != null) {
17798                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17799            }
17800        }
17801        return false;
17802    }
17803
17804    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17805            Intent resultData) {
17806
17807        synchronized (this) {
17808            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17809            if (r != null) {
17810                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17811            }
17812            return false;
17813        }
17814    }
17815
17816    public int getLaunchedFromUid(IBinder activityToken) {
17817        ActivityRecord srec;
17818        synchronized (this) {
17819            srec = ActivityRecord.forTokenLocked(activityToken);
17820        }
17821        if (srec == null) {
17822            return -1;
17823        }
17824        return srec.launchedFromUid;
17825    }
17826
17827    public String getLaunchedFromPackage(IBinder activityToken) {
17828        ActivityRecord srec;
17829        synchronized (this) {
17830            srec = ActivityRecord.forTokenLocked(activityToken);
17831        }
17832        if (srec == null) {
17833            return null;
17834        }
17835        return srec.launchedFromPackage;
17836    }
17837
17838    // =========================================================
17839    // LIFETIME MANAGEMENT
17840    // =========================================================
17841
17842    // Returns which broadcast queue the app is the current [or imminent] receiver
17843    // on, or 'null' if the app is not an active broadcast recipient.
17844    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17845        BroadcastRecord r = app.curReceiver;
17846        if (r != null) {
17847            return r.queue;
17848        }
17849
17850        // It's not the current receiver, but it might be starting up to become one
17851        synchronized (this) {
17852            for (BroadcastQueue queue : mBroadcastQueues) {
17853                r = queue.mPendingBroadcast;
17854                if (r != null && r.curApp == app) {
17855                    // found it; report which queue it's in
17856                    return queue;
17857                }
17858            }
17859        }
17860
17861        return null;
17862    }
17863
17864    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17865            ComponentName targetComponent, String targetProcess) {
17866        if (!mTrackingAssociations) {
17867            return null;
17868        }
17869        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17870                = mAssociations.get(targetUid);
17871        if (components == null) {
17872            components = new ArrayMap<>();
17873            mAssociations.put(targetUid, components);
17874        }
17875        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17876        if (sourceUids == null) {
17877            sourceUids = new SparseArray<>();
17878            components.put(targetComponent, sourceUids);
17879        }
17880        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17881        if (sourceProcesses == null) {
17882            sourceProcesses = new ArrayMap<>();
17883            sourceUids.put(sourceUid, sourceProcesses);
17884        }
17885        Association ass = sourceProcesses.get(sourceProcess);
17886        if (ass == null) {
17887            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17888                    targetProcess);
17889            sourceProcesses.put(sourceProcess, ass);
17890        }
17891        ass.mCount++;
17892        ass.mNesting++;
17893        if (ass.mNesting == 1) {
17894            ass.mStartTime = SystemClock.uptimeMillis();
17895        }
17896        return ass;
17897    }
17898
17899    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17900            ComponentName targetComponent) {
17901        if (!mTrackingAssociations) {
17902            return;
17903        }
17904        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17905                = mAssociations.get(targetUid);
17906        if (components == null) {
17907            return;
17908        }
17909        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17910        if (sourceUids == null) {
17911            return;
17912        }
17913        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17914        if (sourceProcesses == null) {
17915            return;
17916        }
17917        Association ass = sourceProcesses.get(sourceProcess);
17918        if (ass == null || ass.mNesting <= 0) {
17919            return;
17920        }
17921        ass.mNesting--;
17922        if (ass.mNesting == 0) {
17923            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17924        }
17925    }
17926
17927    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17928            boolean doingAll, long now) {
17929        if (mAdjSeq == app.adjSeq) {
17930            // This adjustment has already been computed.
17931            return app.curRawAdj;
17932        }
17933
17934        if (app.thread == null) {
17935            app.adjSeq = mAdjSeq;
17936            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17937            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17938            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17939        }
17940
17941        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17942        app.adjSource = null;
17943        app.adjTarget = null;
17944        app.empty = false;
17945        app.cached = false;
17946
17947        final int activitiesSize = app.activities.size();
17948
17949        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17950            // The max adjustment doesn't allow this app to be anything
17951            // below foreground, so it is not worth doing work for it.
17952            app.adjType = "fixed";
17953            app.adjSeq = mAdjSeq;
17954            app.curRawAdj = app.maxAdj;
17955            app.foregroundActivities = false;
17956            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17957            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17958            // System processes can do UI, and when they do we want to have
17959            // them trim their memory after the user leaves the UI.  To
17960            // facilitate this, here we need to determine whether or not it
17961            // is currently showing UI.
17962            app.systemNoUi = true;
17963            if (app == TOP_APP) {
17964                app.systemNoUi = false;
17965            } else if (activitiesSize > 0) {
17966                for (int j = 0; j < activitiesSize; j++) {
17967                    final ActivityRecord r = app.activities.get(j);
17968                    if (r.visible) {
17969                        app.systemNoUi = false;
17970                    }
17971                }
17972            }
17973            if (!app.systemNoUi) {
17974                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17975            }
17976            return (app.curAdj=app.maxAdj);
17977        }
17978
17979        app.systemNoUi = false;
17980
17981        final int PROCESS_STATE_TOP = mTopProcessState;
17982
17983        // Determine the importance of the process, starting with most
17984        // important to least, and assign an appropriate OOM adjustment.
17985        int adj;
17986        int schedGroup;
17987        int procState;
17988        boolean foregroundActivities = false;
17989        BroadcastQueue queue;
17990        if (app == TOP_APP) {
17991            // The last app on the list is the foreground app.
17992            adj = ProcessList.FOREGROUND_APP_ADJ;
17993            schedGroup = Process.THREAD_GROUP_DEFAULT;
17994            app.adjType = "top-activity";
17995            foregroundActivities = true;
17996            procState = PROCESS_STATE_TOP;
17997        } else if (app.instrumentationClass != null) {
17998            // Don't want to kill running instrumentation.
17999            adj = ProcessList.FOREGROUND_APP_ADJ;
18000            schedGroup = Process.THREAD_GROUP_DEFAULT;
18001            app.adjType = "instrumentation";
18002            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18003        } else if ((queue = isReceivingBroadcast(app)) != null) {
18004            // An app that is currently receiving a broadcast also
18005            // counts as being in the foreground for OOM killer purposes.
18006            // It's placed in a sched group based on the nature of the
18007            // broadcast as reflected by which queue it's active in.
18008            adj = ProcessList.FOREGROUND_APP_ADJ;
18009            schedGroup = (queue == mFgBroadcastQueue)
18010                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18011            app.adjType = "broadcast";
18012            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18013        } else if (app.executingServices.size() > 0) {
18014            // An app that is currently executing a service callback also
18015            // counts as being in the foreground.
18016            adj = ProcessList.FOREGROUND_APP_ADJ;
18017            schedGroup = app.execServicesFg ?
18018                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18019            app.adjType = "exec-service";
18020            procState = ActivityManager.PROCESS_STATE_SERVICE;
18021            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18022        } else {
18023            // As far as we know the process is empty.  We may change our mind later.
18024            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18025            // At this point we don't actually know the adjustment.  Use the cached adj
18026            // value that the caller wants us to.
18027            adj = cachedAdj;
18028            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18029            app.cached = true;
18030            app.empty = true;
18031            app.adjType = "cch-empty";
18032        }
18033
18034        // Examine all activities if not already foreground.
18035        if (!foregroundActivities && activitiesSize > 0) {
18036            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18037            for (int j = 0; j < activitiesSize; j++) {
18038                final ActivityRecord r = app.activities.get(j);
18039                if (r.app != app) {
18040                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18041                            + app + "?!? Using " + r.app + " instead.");
18042                    continue;
18043                }
18044                if (r.visible) {
18045                    // App has a visible activity; only upgrade adjustment.
18046                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18047                        adj = ProcessList.VISIBLE_APP_ADJ;
18048                        app.adjType = "visible";
18049                    }
18050                    if (procState > PROCESS_STATE_TOP) {
18051                        procState = PROCESS_STATE_TOP;
18052                    }
18053                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18054                    app.cached = false;
18055                    app.empty = false;
18056                    foregroundActivities = true;
18057                    if (r.task != null && minLayer > 0) {
18058                        final int layer = r.task.mLayerRank;
18059                        if (layer >= 0 && minLayer > layer) {
18060                            minLayer = layer;
18061                        }
18062                    }
18063                    break;
18064                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18065                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18066                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18067                        app.adjType = "pausing";
18068                    }
18069                    if (procState > PROCESS_STATE_TOP) {
18070                        procState = PROCESS_STATE_TOP;
18071                    }
18072                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18073                    app.cached = false;
18074                    app.empty = false;
18075                    foregroundActivities = true;
18076                } else if (r.state == ActivityState.STOPPING) {
18077                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18078                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18079                        app.adjType = "stopping";
18080                    }
18081                    // For the process state, we will at this point consider the
18082                    // process to be cached.  It will be cached either as an activity
18083                    // or empty depending on whether the activity is finishing.  We do
18084                    // this so that we can treat the process as cached for purposes of
18085                    // memory trimming (determing current memory level, trim command to
18086                    // send to process) since there can be an arbitrary number of stopping
18087                    // processes and they should soon all go into the cached state.
18088                    if (!r.finishing) {
18089                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18090                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18091                        }
18092                    }
18093                    app.cached = false;
18094                    app.empty = false;
18095                    foregroundActivities = true;
18096                } else {
18097                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18098                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18099                        app.adjType = "cch-act";
18100                    }
18101                }
18102            }
18103            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18104                adj += minLayer;
18105            }
18106        }
18107
18108        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18109            if (app.foregroundServices) {
18110                // The user is aware of this app, so make it visible.
18111                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18112                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18113                app.cached = false;
18114                app.adjType = "fg-service";
18115                schedGroup = Process.THREAD_GROUP_DEFAULT;
18116            } else if (app.forcingToForeground != null) {
18117                // The user is aware of this app, so make it visible.
18118                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18119                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18120                app.cached = false;
18121                app.adjType = "force-fg";
18122                app.adjSource = app.forcingToForeground;
18123                schedGroup = Process.THREAD_GROUP_DEFAULT;
18124            }
18125        }
18126
18127        if (app == mHeavyWeightProcess) {
18128            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18129                // We don't want to kill the current heavy-weight process.
18130                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18131                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18132                app.cached = false;
18133                app.adjType = "heavy";
18134            }
18135            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18136                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18137            }
18138        }
18139
18140        if (app == mHomeProcess) {
18141            if (adj > ProcessList.HOME_APP_ADJ) {
18142                // This process is hosting what we currently consider to be the
18143                // home app, so we don't want to let it go into the background.
18144                adj = ProcessList.HOME_APP_ADJ;
18145                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18146                app.cached = false;
18147                app.adjType = "home";
18148            }
18149            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18150                procState = ActivityManager.PROCESS_STATE_HOME;
18151            }
18152        }
18153
18154        if (app == mPreviousProcess && app.activities.size() > 0) {
18155            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18156                // This was the previous process that showed UI to the user.
18157                // We want to try to keep it around more aggressively, to give
18158                // a good experience around switching between two apps.
18159                adj = ProcessList.PREVIOUS_APP_ADJ;
18160                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18161                app.cached = false;
18162                app.adjType = "previous";
18163            }
18164            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18165                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18166            }
18167        }
18168
18169        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18170                + " reason=" + app.adjType);
18171
18172        // By default, we use the computed adjustment.  It may be changed if
18173        // there are applications dependent on our services or providers, but
18174        // this gives us a baseline and makes sure we don't get into an
18175        // infinite recursion.
18176        app.adjSeq = mAdjSeq;
18177        app.curRawAdj = adj;
18178        app.hasStartedServices = false;
18179
18180        if (mBackupTarget != null && app == mBackupTarget.app) {
18181            // If possible we want to avoid killing apps while they're being backed up
18182            if (adj > ProcessList.BACKUP_APP_ADJ) {
18183                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18184                adj = ProcessList.BACKUP_APP_ADJ;
18185                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18186                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18187                }
18188                app.adjType = "backup";
18189                app.cached = false;
18190            }
18191            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18192                procState = ActivityManager.PROCESS_STATE_BACKUP;
18193            }
18194        }
18195
18196        boolean mayBeTop = false;
18197
18198        for (int is = app.services.size()-1;
18199                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18200                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18201                        || procState > ActivityManager.PROCESS_STATE_TOP);
18202                is--) {
18203            ServiceRecord s = app.services.valueAt(is);
18204            if (s.startRequested) {
18205                app.hasStartedServices = true;
18206                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18207                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18208                }
18209                if (app.hasShownUi && app != mHomeProcess) {
18210                    // If this process has shown some UI, let it immediately
18211                    // go to the LRU list because it may be pretty heavy with
18212                    // UI stuff.  We'll tag it with a label just to help
18213                    // debug and understand what is going on.
18214                    if (adj > ProcessList.SERVICE_ADJ) {
18215                        app.adjType = "cch-started-ui-services";
18216                    }
18217                } else {
18218                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18219                        // This service has seen some activity within
18220                        // recent memory, so we will keep its process ahead
18221                        // of the background processes.
18222                        if (adj > ProcessList.SERVICE_ADJ) {
18223                            adj = ProcessList.SERVICE_ADJ;
18224                            app.adjType = "started-services";
18225                            app.cached = false;
18226                        }
18227                    }
18228                    // If we have let the service slide into the background
18229                    // state, still have some text describing what it is doing
18230                    // even though the service no longer has an impact.
18231                    if (adj > ProcessList.SERVICE_ADJ) {
18232                        app.adjType = "cch-started-services";
18233                    }
18234                }
18235            }
18236            for (int conni = s.connections.size()-1;
18237                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18238                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18239                            || procState > ActivityManager.PROCESS_STATE_TOP);
18240                    conni--) {
18241                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18242                for (int i = 0;
18243                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18244                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18245                                || procState > ActivityManager.PROCESS_STATE_TOP);
18246                        i++) {
18247                    // XXX should compute this based on the max of
18248                    // all connected clients.
18249                    ConnectionRecord cr = clist.get(i);
18250                    if (cr.binding.client == app) {
18251                        // Binding to ourself is not interesting.
18252                        continue;
18253                    }
18254                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18255                        ProcessRecord client = cr.binding.client;
18256                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18257                                TOP_APP, doingAll, now);
18258                        int clientProcState = client.curProcState;
18259                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18260                            // If the other app is cached for any reason, for purposes here
18261                            // we are going to consider it empty.  The specific cached state
18262                            // doesn't propagate except under certain conditions.
18263                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18264                        }
18265                        String adjType = null;
18266                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18267                            // Not doing bind OOM management, so treat
18268                            // this guy more like a started service.
18269                            if (app.hasShownUi && app != mHomeProcess) {
18270                                // If this process has shown some UI, let it immediately
18271                                // go to the LRU list because it may be pretty heavy with
18272                                // UI stuff.  We'll tag it with a label just to help
18273                                // debug and understand what is going on.
18274                                if (adj > clientAdj) {
18275                                    adjType = "cch-bound-ui-services";
18276                                }
18277                                app.cached = false;
18278                                clientAdj = adj;
18279                                clientProcState = procState;
18280                            } else {
18281                                if (now >= (s.lastActivity
18282                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18283                                    // This service has not seen activity within
18284                                    // recent memory, so allow it to drop to the
18285                                    // LRU list if there is no other reason to keep
18286                                    // it around.  We'll also tag it with a label just
18287                                    // to help debug and undertand what is going on.
18288                                    if (adj > clientAdj) {
18289                                        adjType = "cch-bound-services";
18290                                    }
18291                                    clientAdj = adj;
18292                                }
18293                            }
18294                        }
18295                        if (adj > clientAdj) {
18296                            // If this process has recently shown UI, and
18297                            // the process that is binding to it is less
18298                            // important than being visible, then we don't
18299                            // care about the binding as much as we care
18300                            // about letting this process get into the LRU
18301                            // list to be killed and restarted if needed for
18302                            // memory.
18303                            if (app.hasShownUi && app != mHomeProcess
18304                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18305                                adjType = "cch-bound-ui-services";
18306                            } else {
18307                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18308                                        |Context.BIND_IMPORTANT)) != 0) {
18309                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18310                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18311                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18312                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18313                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18314                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18315                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18316                                    adj = clientAdj;
18317                                } else {
18318                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18319                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18320                                    }
18321                                }
18322                                if (!client.cached) {
18323                                    app.cached = false;
18324                                }
18325                                adjType = "service";
18326                            }
18327                        }
18328                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18329                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18330                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18331                            }
18332                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18333                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18334                                    // Special handling of clients who are in the top state.
18335                                    // We *may* want to consider this process to be in the
18336                                    // top state as well, but only if there is not another
18337                                    // reason for it to be running.  Being on the top is a
18338                                    // special state, meaning you are specifically running
18339                                    // for the current top app.  If the process is already
18340                                    // running in the background for some other reason, it
18341                                    // is more important to continue considering it to be
18342                                    // in the background state.
18343                                    mayBeTop = true;
18344                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18345                                } else {
18346                                    // Special handling for above-top states (persistent
18347                                    // processes).  These should not bring the current process
18348                                    // into the top state, since they are not on top.  Instead
18349                                    // give them the best state after that.
18350                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18351                                        clientProcState =
18352                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18353                                    } else if (mWakefulness
18354                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18355                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18356                                                    != 0) {
18357                                        clientProcState =
18358                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18359                                    } else {
18360                                        clientProcState =
18361                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18362                                    }
18363                                }
18364                            }
18365                        } else {
18366                            if (clientProcState <
18367                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18368                                clientProcState =
18369                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18370                            }
18371                        }
18372                        if (procState > clientProcState) {
18373                            procState = clientProcState;
18374                        }
18375                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18376                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18377                            app.pendingUiClean = true;
18378                        }
18379                        if (adjType != null) {
18380                            app.adjType = adjType;
18381                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18382                                    .REASON_SERVICE_IN_USE;
18383                            app.adjSource = cr.binding.client;
18384                            app.adjSourceProcState = clientProcState;
18385                            app.adjTarget = s.name;
18386                        }
18387                    }
18388                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18389                        app.treatLikeActivity = true;
18390                    }
18391                    final ActivityRecord a = cr.activity;
18392                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18393                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18394                                (a.visible || a.state == ActivityState.RESUMED
18395                                 || a.state == ActivityState.PAUSING)) {
18396                            adj = ProcessList.FOREGROUND_APP_ADJ;
18397                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18398                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18399                            }
18400                            app.cached = false;
18401                            app.adjType = "service";
18402                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18403                                    .REASON_SERVICE_IN_USE;
18404                            app.adjSource = a;
18405                            app.adjSourceProcState = procState;
18406                            app.adjTarget = s.name;
18407                        }
18408                    }
18409                }
18410            }
18411        }
18412
18413        for (int provi = app.pubProviders.size()-1;
18414                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18415                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18416                        || procState > ActivityManager.PROCESS_STATE_TOP);
18417                provi--) {
18418            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18419            for (int i = cpr.connections.size()-1;
18420                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18421                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18422                            || procState > ActivityManager.PROCESS_STATE_TOP);
18423                    i--) {
18424                ContentProviderConnection conn = cpr.connections.get(i);
18425                ProcessRecord client = conn.client;
18426                if (client == app) {
18427                    // Being our own client is not interesting.
18428                    continue;
18429                }
18430                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18431                int clientProcState = client.curProcState;
18432                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18433                    // If the other app is cached for any reason, for purposes here
18434                    // we are going to consider it empty.
18435                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18436                }
18437                if (adj > clientAdj) {
18438                    if (app.hasShownUi && app != mHomeProcess
18439                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18440                        app.adjType = "cch-ui-provider";
18441                    } else {
18442                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18443                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18444                        app.adjType = "provider";
18445                    }
18446                    app.cached &= client.cached;
18447                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18448                            .REASON_PROVIDER_IN_USE;
18449                    app.adjSource = client;
18450                    app.adjSourceProcState = clientProcState;
18451                    app.adjTarget = cpr.name;
18452                }
18453                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18454                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18455                        // Special handling of clients who are in the top state.
18456                        // We *may* want to consider this process to be in the
18457                        // top state as well, but only if there is not another
18458                        // reason for it to be running.  Being on the top is a
18459                        // special state, meaning you are specifically running
18460                        // for the current top app.  If the process is already
18461                        // running in the background for some other reason, it
18462                        // is more important to continue considering it to be
18463                        // in the background state.
18464                        mayBeTop = true;
18465                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18466                    } else {
18467                        // Special handling for above-top states (persistent
18468                        // processes).  These should not bring the current process
18469                        // into the top state, since they are not on top.  Instead
18470                        // give them the best state after that.
18471                        clientProcState =
18472                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18473                    }
18474                }
18475                if (procState > clientProcState) {
18476                    procState = clientProcState;
18477                }
18478                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18479                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18480                }
18481            }
18482            // If the provider has external (non-framework) process
18483            // dependencies, ensure that its adjustment is at least
18484            // FOREGROUND_APP_ADJ.
18485            if (cpr.hasExternalProcessHandles()) {
18486                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18487                    adj = ProcessList.FOREGROUND_APP_ADJ;
18488                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18489                    app.cached = false;
18490                    app.adjType = "provider";
18491                    app.adjTarget = cpr.name;
18492                }
18493                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18494                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18495                }
18496            }
18497        }
18498
18499        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18500            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18501                adj = ProcessList.PREVIOUS_APP_ADJ;
18502                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18503                app.cached = false;
18504                app.adjType = "provider";
18505            }
18506            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18507                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18508            }
18509        }
18510
18511        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18512            // A client of one of our services or providers is in the top state.  We
18513            // *may* want to be in the top state, but not if we are already running in
18514            // the background for some other reason.  For the decision here, we are going
18515            // to pick out a few specific states that we want to remain in when a client
18516            // is top (states that tend to be longer-term) and otherwise allow it to go
18517            // to the top state.
18518            switch (procState) {
18519                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18520                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18521                case ActivityManager.PROCESS_STATE_SERVICE:
18522                    // These all are longer-term states, so pull them up to the top
18523                    // of the background states, but not all the way to the top state.
18524                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18525                    break;
18526                default:
18527                    // Otherwise, top is a better choice, so take it.
18528                    procState = ActivityManager.PROCESS_STATE_TOP;
18529                    break;
18530            }
18531        }
18532
18533        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18534            if (app.hasClientActivities) {
18535                // This is a cached process, but with client activities.  Mark it so.
18536                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18537                app.adjType = "cch-client-act";
18538            } else if (app.treatLikeActivity) {
18539                // This is a cached process, but somebody wants us to treat it like it has
18540                // an activity, okay!
18541                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18542                app.adjType = "cch-as-act";
18543            }
18544        }
18545
18546        if (adj == ProcessList.SERVICE_ADJ) {
18547            if (doingAll) {
18548                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18549                mNewNumServiceProcs++;
18550                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18551                if (!app.serviceb) {
18552                    // This service isn't far enough down on the LRU list to
18553                    // normally be a B service, but if we are low on RAM and it
18554                    // is large we want to force it down since we would prefer to
18555                    // keep launcher over it.
18556                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18557                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18558                        app.serviceHighRam = true;
18559                        app.serviceb = true;
18560                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18561                    } else {
18562                        mNewNumAServiceProcs++;
18563                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18564                    }
18565                } else {
18566                    app.serviceHighRam = false;
18567                }
18568            }
18569            if (app.serviceb) {
18570                adj = ProcessList.SERVICE_B_ADJ;
18571            }
18572        }
18573
18574        app.curRawAdj = adj;
18575
18576        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18577        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18578        if (adj > app.maxAdj) {
18579            adj = app.maxAdj;
18580            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18581                schedGroup = Process.THREAD_GROUP_DEFAULT;
18582            }
18583        }
18584
18585        // Do final modification to adj.  Everything we do between here and applying
18586        // the final setAdj must be done in this function, because we will also use
18587        // it when computing the final cached adj later.  Note that we don't need to
18588        // worry about this for max adj above, since max adj will always be used to
18589        // keep it out of the cached vaues.
18590        app.curAdj = app.modifyRawOomAdj(adj);
18591        app.curSchedGroup = schedGroup;
18592        app.curProcState = procState;
18593        app.foregroundActivities = foregroundActivities;
18594
18595        return app.curRawAdj;
18596    }
18597
18598    /**
18599     * Record new PSS sample for a process.
18600     */
18601    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18602        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18603        proc.lastPssTime = now;
18604        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18605        if (DEBUG_PSS) Slog.d(TAG_PSS,
18606                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18607                + " state=" + ProcessList.makeProcStateString(procState));
18608        if (proc.initialIdlePss == 0) {
18609            proc.initialIdlePss = pss;
18610        }
18611        proc.lastPss = pss;
18612        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18613            proc.lastCachedPss = pss;
18614        }
18615
18616        final SparseArray<Pair<Long, String>> watchUids
18617                = mMemWatchProcesses.getMap().get(proc.processName);
18618        Long check = null;
18619        if (watchUids != null) {
18620            Pair<Long, String> val = watchUids.get(proc.uid);
18621            if (val == null) {
18622                val = watchUids.get(0);
18623            }
18624            if (val != null) {
18625                check = val.first;
18626            }
18627        }
18628        if (check != null) {
18629            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18630                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18631                if (!isDebuggable) {
18632                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18633                        isDebuggable = true;
18634                    }
18635                }
18636                if (isDebuggable) {
18637                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18638                    final ProcessRecord myProc = proc;
18639                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18640                    mMemWatchDumpProcName = proc.processName;
18641                    mMemWatchDumpFile = heapdumpFile.toString();
18642                    mMemWatchDumpPid = proc.pid;
18643                    mMemWatchDumpUid = proc.uid;
18644                    BackgroundThread.getHandler().post(new Runnable() {
18645                        @Override
18646                        public void run() {
18647                            revokeUriPermission(ActivityThread.currentActivityThread()
18648                                            .getApplicationThread(),
18649                                    DumpHeapActivity.JAVA_URI,
18650                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18651                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18652                                    UserHandle.myUserId());
18653                            ParcelFileDescriptor fd = null;
18654                            try {
18655                                heapdumpFile.delete();
18656                                fd = ParcelFileDescriptor.open(heapdumpFile,
18657                                        ParcelFileDescriptor.MODE_CREATE |
18658                                                ParcelFileDescriptor.MODE_TRUNCATE |
18659                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18660                                                ParcelFileDescriptor.MODE_APPEND);
18661                                IApplicationThread thread = myProc.thread;
18662                                if (thread != null) {
18663                                    try {
18664                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18665                                                "Requesting dump heap from "
18666                                                + myProc + " to " + heapdumpFile);
18667                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18668                                    } catch (RemoteException e) {
18669                                    }
18670                                }
18671                            } catch (FileNotFoundException e) {
18672                                e.printStackTrace();
18673                            } finally {
18674                                if (fd != null) {
18675                                    try {
18676                                        fd.close();
18677                                    } catch (IOException e) {
18678                                    }
18679                                }
18680                            }
18681                        }
18682                    });
18683                } else {
18684                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18685                            + ", but debugging not enabled");
18686                }
18687            }
18688        }
18689    }
18690
18691    /**
18692     * Schedule PSS collection of a process.
18693     */
18694    void requestPssLocked(ProcessRecord proc, int procState) {
18695        if (mPendingPssProcesses.contains(proc)) {
18696            return;
18697        }
18698        if (mPendingPssProcesses.size() == 0) {
18699            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18700        }
18701        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18702        proc.pssProcState = procState;
18703        mPendingPssProcesses.add(proc);
18704    }
18705
18706    /**
18707     * Schedule PSS collection of all processes.
18708     */
18709    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18710        if (!always) {
18711            if (now < (mLastFullPssTime +
18712                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18713                return;
18714            }
18715        }
18716        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18717        mLastFullPssTime = now;
18718        mFullPssPending = true;
18719        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18720        mPendingPssProcesses.clear();
18721        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18722            ProcessRecord app = mLruProcesses.get(i);
18723            if (app.thread == null
18724                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18725                continue;
18726            }
18727            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18728                app.pssProcState = app.setProcState;
18729                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18730                        mTestPssMode, isSleeping(), now);
18731                mPendingPssProcesses.add(app);
18732            }
18733        }
18734        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18735    }
18736
18737    public void setTestPssMode(boolean enabled) {
18738        synchronized (this) {
18739            mTestPssMode = enabled;
18740            if (enabled) {
18741                // Whenever we enable the mode, we want to take a snapshot all of current
18742                // process mem use.
18743                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18744            }
18745        }
18746    }
18747
18748    /**
18749     * Ask a given process to GC right now.
18750     */
18751    final void performAppGcLocked(ProcessRecord app) {
18752        try {
18753            app.lastRequestedGc = SystemClock.uptimeMillis();
18754            if (app.thread != null) {
18755                if (app.reportLowMemory) {
18756                    app.reportLowMemory = false;
18757                    app.thread.scheduleLowMemory();
18758                } else {
18759                    app.thread.processInBackground();
18760                }
18761            }
18762        } catch (Exception e) {
18763            // whatever.
18764        }
18765    }
18766
18767    /**
18768     * Returns true if things are idle enough to perform GCs.
18769     */
18770    private final boolean canGcNowLocked() {
18771        boolean processingBroadcasts = false;
18772        for (BroadcastQueue q : mBroadcastQueues) {
18773            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18774                processingBroadcasts = true;
18775            }
18776        }
18777        return !processingBroadcasts
18778                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18779    }
18780
18781    /**
18782     * Perform GCs on all processes that are waiting for it, but only
18783     * if things are idle.
18784     */
18785    final void performAppGcsLocked() {
18786        final int N = mProcessesToGc.size();
18787        if (N <= 0) {
18788            return;
18789        }
18790        if (canGcNowLocked()) {
18791            while (mProcessesToGc.size() > 0) {
18792                ProcessRecord proc = mProcessesToGc.remove(0);
18793                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18794                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18795                            <= SystemClock.uptimeMillis()) {
18796                        // To avoid spamming the system, we will GC processes one
18797                        // at a time, waiting a few seconds between each.
18798                        performAppGcLocked(proc);
18799                        scheduleAppGcsLocked();
18800                        return;
18801                    } else {
18802                        // It hasn't been long enough since we last GCed this
18803                        // process...  put it in the list to wait for its time.
18804                        addProcessToGcListLocked(proc);
18805                        break;
18806                    }
18807                }
18808            }
18809
18810            scheduleAppGcsLocked();
18811        }
18812    }
18813
18814    /**
18815     * If all looks good, perform GCs on all processes waiting for them.
18816     */
18817    final void performAppGcsIfAppropriateLocked() {
18818        if (canGcNowLocked()) {
18819            performAppGcsLocked();
18820            return;
18821        }
18822        // Still not idle, wait some more.
18823        scheduleAppGcsLocked();
18824    }
18825
18826    /**
18827     * Schedule the execution of all pending app GCs.
18828     */
18829    final void scheduleAppGcsLocked() {
18830        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18831
18832        if (mProcessesToGc.size() > 0) {
18833            // Schedule a GC for the time to the next process.
18834            ProcessRecord proc = mProcessesToGc.get(0);
18835            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18836
18837            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18838            long now = SystemClock.uptimeMillis();
18839            if (when < (now+GC_TIMEOUT)) {
18840                when = now + GC_TIMEOUT;
18841            }
18842            mHandler.sendMessageAtTime(msg, when);
18843        }
18844    }
18845
18846    /**
18847     * Add a process to the array of processes waiting to be GCed.  Keeps the
18848     * list in sorted order by the last GC time.  The process can't already be
18849     * on the list.
18850     */
18851    final void addProcessToGcListLocked(ProcessRecord proc) {
18852        boolean added = false;
18853        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18854            if (mProcessesToGc.get(i).lastRequestedGc <
18855                    proc.lastRequestedGc) {
18856                added = true;
18857                mProcessesToGc.add(i+1, proc);
18858                break;
18859            }
18860        }
18861        if (!added) {
18862            mProcessesToGc.add(0, proc);
18863        }
18864    }
18865
18866    /**
18867     * Set up to ask a process to GC itself.  This will either do it
18868     * immediately, or put it on the list of processes to gc the next
18869     * time things are idle.
18870     */
18871    final void scheduleAppGcLocked(ProcessRecord app) {
18872        long now = SystemClock.uptimeMillis();
18873        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18874            return;
18875        }
18876        if (!mProcessesToGc.contains(app)) {
18877            addProcessToGcListLocked(app);
18878            scheduleAppGcsLocked();
18879        }
18880    }
18881
18882    final void checkExcessivePowerUsageLocked(boolean doKills) {
18883        updateCpuStatsNow();
18884
18885        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18886        boolean doWakeKills = doKills;
18887        boolean doCpuKills = doKills;
18888        if (mLastPowerCheckRealtime == 0) {
18889            doWakeKills = false;
18890        }
18891        if (mLastPowerCheckUptime == 0) {
18892            doCpuKills = false;
18893        }
18894        if (stats.isScreenOn()) {
18895            doWakeKills = false;
18896        }
18897        final long curRealtime = SystemClock.elapsedRealtime();
18898        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18899        final long curUptime = SystemClock.uptimeMillis();
18900        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18901        mLastPowerCheckRealtime = curRealtime;
18902        mLastPowerCheckUptime = curUptime;
18903        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18904            doWakeKills = false;
18905        }
18906        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18907            doCpuKills = false;
18908        }
18909        int i = mLruProcesses.size();
18910        while (i > 0) {
18911            i--;
18912            ProcessRecord app = mLruProcesses.get(i);
18913            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18914                long wtime;
18915                synchronized (stats) {
18916                    wtime = stats.getProcessWakeTime(app.info.uid,
18917                            app.pid, curRealtime);
18918                }
18919                long wtimeUsed = wtime - app.lastWakeTime;
18920                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18921                if (DEBUG_POWER) {
18922                    StringBuilder sb = new StringBuilder(128);
18923                    sb.append("Wake for ");
18924                    app.toShortString(sb);
18925                    sb.append(": over ");
18926                    TimeUtils.formatDuration(realtimeSince, sb);
18927                    sb.append(" used ");
18928                    TimeUtils.formatDuration(wtimeUsed, sb);
18929                    sb.append(" (");
18930                    sb.append((wtimeUsed*100)/realtimeSince);
18931                    sb.append("%)");
18932                    Slog.i(TAG_POWER, sb.toString());
18933                    sb.setLength(0);
18934                    sb.append("CPU for ");
18935                    app.toShortString(sb);
18936                    sb.append(": over ");
18937                    TimeUtils.formatDuration(uptimeSince, sb);
18938                    sb.append(" used ");
18939                    TimeUtils.formatDuration(cputimeUsed, sb);
18940                    sb.append(" (");
18941                    sb.append((cputimeUsed*100)/uptimeSince);
18942                    sb.append("%)");
18943                    Slog.i(TAG_POWER, sb.toString());
18944                }
18945                // If a process has held a wake lock for more
18946                // than 50% of the time during this period,
18947                // that sounds bad.  Kill!
18948                if (doWakeKills && realtimeSince > 0
18949                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18950                    synchronized (stats) {
18951                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18952                                realtimeSince, wtimeUsed);
18953                    }
18954                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18955                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18956                } else if (doCpuKills && uptimeSince > 0
18957                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18958                    synchronized (stats) {
18959                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18960                                uptimeSince, cputimeUsed);
18961                    }
18962                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18963                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18964                } else {
18965                    app.lastWakeTime = wtime;
18966                    app.lastCpuTime = app.curCpuTime;
18967                }
18968            }
18969        }
18970    }
18971
18972    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18973            long nowElapsed) {
18974        boolean success = true;
18975
18976        if (app.curRawAdj != app.setRawAdj) {
18977            app.setRawAdj = app.curRawAdj;
18978        }
18979
18980        int changes = 0;
18981
18982        if (app.curAdj != app.setAdj) {
18983            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18984            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18985                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18986                    + app.adjType);
18987            app.setAdj = app.curAdj;
18988        }
18989
18990        if (app.setSchedGroup != app.curSchedGroup) {
18991            app.setSchedGroup = app.curSchedGroup;
18992            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18993                    "Setting process group of " + app.processName
18994                    + " to " + app.curSchedGroup);
18995            if (app.waitingToKill != null && app.curReceiver == null
18996                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18997                app.kill(app.waitingToKill, true);
18998                success = false;
18999            } else {
19000                if (true) {
19001                    long oldId = Binder.clearCallingIdentity();
19002                    try {
19003                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19004                    } catch (Exception e) {
19005                        Slog.w(TAG, "Failed setting process group of " + app.pid
19006                                + " to " + app.curSchedGroup);
19007                        e.printStackTrace();
19008                    } finally {
19009                        Binder.restoreCallingIdentity(oldId);
19010                    }
19011                } else {
19012                    if (app.thread != null) {
19013                        try {
19014                            app.thread.setSchedulingGroup(app.curSchedGroup);
19015                        } catch (RemoteException e) {
19016                        }
19017                    }
19018                }
19019                Process.setSwappiness(app.pid,
19020                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
19021            }
19022        }
19023        if (app.repForegroundActivities != app.foregroundActivities) {
19024            app.repForegroundActivities = app.foregroundActivities;
19025            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19026        }
19027        if (app.repProcState != app.curProcState) {
19028            app.repProcState = app.curProcState;
19029            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19030            if (app.thread != null) {
19031                try {
19032                    if (false) {
19033                        //RuntimeException h = new RuntimeException("here");
19034                        Slog.i(TAG, "Sending new process state " + app.repProcState
19035                                + " to " + app /*, h*/);
19036                    }
19037                    app.thread.setProcessState(app.repProcState);
19038                } catch (RemoteException e) {
19039                }
19040            }
19041        }
19042        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19043                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19044            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19045                // Experimental code to more aggressively collect pss while
19046                // running test...  the problem is that this tends to collect
19047                // the data right when a process is transitioning between process
19048                // states, which well tend to give noisy data.
19049                long start = SystemClock.uptimeMillis();
19050                long pss = Debug.getPss(app.pid, mTmpLong, null);
19051                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19052                mPendingPssProcesses.remove(app);
19053                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19054                        + " to " + app.curProcState + ": "
19055                        + (SystemClock.uptimeMillis()-start) + "ms");
19056            }
19057            app.lastStateTime = now;
19058            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19059                    mTestPssMode, isSleeping(), now);
19060            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19061                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19062                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19063                    + (app.nextPssTime-now) + ": " + app);
19064        } else {
19065            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19066                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19067                    mTestPssMode)))) {
19068                requestPssLocked(app, app.setProcState);
19069                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19070                        mTestPssMode, isSleeping(), now);
19071            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19072                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19073        }
19074        if (app.setProcState != app.curProcState) {
19075            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19076                    "Proc state change of " + app.processName
19077                            + " to " + app.curProcState);
19078            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19079            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19080            if (setImportant && !curImportant) {
19081                // This app is no longer something we consider important enough to allow to
19082                // use arbitrary amounts of battery power.  Note
19083                // its current wake lock time to later know to kill it if
19084                // it is not behaving well.
19085                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19086                synchronized (stats) {
19087                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19088                            app.pid, nowElapsed);
19089                }
19090                app.lastCpuTime = app.curCpuTime;
19091
19092            }
19093            // Inform UsageStats of important process state change
19094            // Must be called before updating setProcState
19095            maybeUpdateUsageStatsLocked(app, nowElapsed);
19096
19097            app.setProcState = app.curProcState;
19098            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19099                app.notCachedSinceIdle = false;
19100            }
19101            if (!doingAll) {
19102                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19103            } else {
19104                app.procStateChanged = true;
19105            }
19106        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19107                > USAGE_STATS_INTERACTION_INTERVAL) {
19108            // For apps that sit around for a long time in the interactive state, we need
19109            // to report this at least once a day so they don't go idle.
19110            maybeUpdateUsageStatsLocked(app, nowElapsed);
19111        }
19112
19113        if (changes != 0) {
19114            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19115                    "Changes in " + app + ": " + changes);
19116            int i = mPendingProcessChanges.size()-1;
19117            ProcessChangeItem item = null;
19118            while (i >= 0) {
19119                item = mPendingProcessChanges.get(i);
19120                if (item.pid == app.pid) {
19121                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19122                            "Re-using existing item: " + item);
19123                    break;
19124                }
19125                i--;
19126            }
19127            if (i < 0) {
19128                // No existing item in pending changes; need a new one.
19129                final int NA = mAvailProcessChanges.size();
19130                if (NA > 0) {
19131                    item = mAvailProcessChanges.remove(NA-1);
19132                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19133                            "Retrieving available item: " + item);
19134                } else {
19135                    item = new ProcessChangeItem();
19136                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19137                            "Allocating new item: " + item);
19138                }
19139                item.changes = 0;
19140                item.pid = app.pid;
19141                item.uid = app.info.uid;
19142                if (mPendingProcessChanges.size() == 0) {
19143                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19144                            "*** Enqueueing dispatch processes changed!");
19145                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19146                }
19147                mPendingProcessChanges.add(item);
19148            }
19149            item.changes |= changes;
19150            item.processState = app.repProcState;
19151            item.foregroundActivities = app.repForegroundActivities;
19152            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19153                    "Item " + Integer.toHexString(System.identityHashCode(item))
19154                    + " " + app.toShortString() + ": changes=" + item.changes
19155                    + " procState=" + item.processState
19156                    + " foreground=" + item.foregroundActivities
19157                    + " type=" + app.adjType + " source=" + app.adjSource
19158                    + " target=" + app.adjTarget);
19159        }
19160
19161        return success;
19162    }
19163
19164    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19165        final UidRecord.ChangeItem pendingChange;
19166        if (uidRec == null || uidRec.pendingChange == null) {
19167            if (mPendingUidChanges.size() == 0) {
19168                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19169                        "*** Enqueueing dispatch uid changed!");
19170                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19171            }
19172            final int NA = mAvailUidChanges.size();
19173            if (NA > 0) {
19174                pendingChange = mAvailUidChanges.remove(NA-1);
19175                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19176                        "Retrieving available item: " + pendingChange);
19177            } else {
19178                pendingChange = new UidRecord.ChangeItem();
19179                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19180                        "Allocating new item: " + pendingChange);
19181            }
19182            if (uidRec != null) {
19183                uidRec.pendingChange = pendingChange;
19184                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19185                    // If this uid is going away, and we haven't yet reported it is gone,
19186                    // then do so now.
19187                    change = UidRecord.CHANGE_GONE_IDLE;
19188                }
19189            } else if (uid < 0) {
19190                throw new IllegalArgumentException("No UidRecord or uid");
19191            }
19192            pendingChange.uidRecord = uidRec;
19193            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19194            mPendingUidChanges.add(pendingChange);
19195        } else {
19196            pendingChange = uidRec.pendingChange;
19197            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19198                change = UidRecord.CHANGE_GONE_IDLE;
19199            }
19200        }
19201        pendingChange.change = change;
19202        pendingChange.processState = uidRec != null
19203                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19204    }
19205
19206    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19207            String authority) {
19208        if (app == null) return;
19209        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19210            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19211            if (userState == null) return;
19212            final long now = SystemClock.elapsedRealtime();
19213            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19214            if (lastReported == null || lastReported < now - 60 * 1000L) {
19215                mUsageStatsService.reportContentProviderUsage(
19216                        authority, providerPkgName, app.userId);
19217                userState.mProviderLastReportedFg.put(authority, now);
19218            }
19219        }
19220    }
19221
19222    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19223        if (DEBUG_USAGE_STATS) {
19224            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19225                    + "] state changes: old = " + app.setProcState + ", new = "
19226                    + app.curProcState);
19227        }
19228        if (mUsageStatsService == null) {
19229            return;
19230        }
19231        boolean isInteraction;
19232        // To avoid some abuse patterns, we are going to be careful about what we consider
19233        // to be an app interaction.  Being the top activity doesn't count while the display
19234        // is sleeping, nor do short foreground services.
19235        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19236            isInteraction = true;
19237            app.fgInteractionTime = 0;
19238        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19239            if (app.fgInteractionTime == 0) {
19240                app.fgInteractionTime = nowElapsed;
19241                isInteraction = false;
19242            } else {
19243                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19244            }
19245        } else {
19246            isInteraction = app.curProcState
19247                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19248            app.fgInteractionTime = 0;
19249        }
19250        if (isInteraction && (!app.reportedInteraction
19251                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19252            app.interactionEventTime = nowElapsed;
19253            String[] packages = app.getPackageList();
19254            if (packages != null) {
19255                for (int i = 0; i < packages.length; i++) {
19256                    mUsageStatsService.reportEvent(packages[i], app.userId,
19257                            UsageEvents.Event.SYSTEM_INTERACTION);
19258                }
19259            }
19260        }
19261        app.reportedInteraction = isInteraction;
19262        if (!isInteraction) {
19263            app.interactionEventTime = 0;
19264        }
19265    }
19266
19267    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19268        if (proc.thread != null) {
19269            if (proc.baseProcessTracker != null) {
19270                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19271            }
19272            if (proc.repProcState >= 0) {
19273                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19274                        proc.repProcState);
19275            }
19276        }
19277    }
19278
19279    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19280            ProcessRecord TOP_APP, boolean doingAll, long now) {
19281        if (app.thread == null) {
19282            return false;
19283        }
19284
19285        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19286
19287        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19288    }
19289
19290    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19291            boolean oomAdj) {
19292        if (isForeground != proc.foregroundServices) {
19293            proc.foregroundServices = isForeground;
19294            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19295                    proc.info.uid);
19296            if (isForeground) {
19297                if (curProcs == null) {
19298                    curProcs = new ArrayList<ProcessRecord>();
19299                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19300                }
19301                if (!curProcs.contains(proc)) {
19302                    curProcs.add(proc);
19303                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19304                            proc.info.packageName, proc.info.uid);
19305                }
19306            } else {
19307                if (curProcs != null) {
19308                    if (curProcs.remove(proc)) {
19309                        mBatteryStatsService.noteEvent(
19310                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19311                                proc.info.packageName, proc.info.uid);
19312                        if (curProcs.size() <= 0) {
19313                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19314                        }
19315                    }
19316                }
19317            }
19318            if (oomAdj) {
19319                updateOomAdjLocked();
19320            }
19321        }
19322    }
19323
19324    private final ActivityRecord resumedAppLocked() {
19325        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19326        String pkg;
19327        int uid;
19328        if (act != null) {
19329            pkg = act.packageName;
19330            uid = act.info.applicationInfo.uid;
19331        } else {
19332            pkg = null;
19333            uid = -1;
19334        }
19335        // Has the UID or resumed package name changed?
19336        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19337                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19338            if (mCurResumedPackage != null) {
19339                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19340                        mCurResumedPackage, mCurResumedUid);
19341            }
19342            mCurResumedPackage = pkg;
19343            mCurResumedUid = uid;
19344            if (mCurResumedPackage != null) {
19345                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19346                        mCurResumedPackage, mCurResumedUid);
19347            }
19348        }
19349        return act;
19350    }
19351
19352    final boolean updateOomAdjLocked(ProcessRecord app) {
19353        final ActivityRecord TOP_ACT = resumedAppLocked();
19354        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19355        final boolean wasCached = app.cached;
19356
19357        mAdjSeq++;
19358
19359        // This is the desired cached adjusment we want to tell it to use.
19360        // If our app is currently cached, we know it, and that is it.  Otherwise,
19361        // we don't know it yet, and it needs to now be cached we will then
19362        // need to do a complete oom adj.
19363        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19364                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19365        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19366                SystemClock.uptimeMillis());
19367        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19368            // Changed to/from cached state, so apps after it in the LRU
19369            // list may also be changed.
19370            updateOomAdjLocked();
19371        }
19372        return success;
19373    }
19374
19375    final void updateOomAdjLocked() {
19376        final ActivityRecord TOP_ACT = resumedAppLocked();
19377        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19378        final long now = SystemClock.uptimeMillis();
19379        final long nowElapsed = SystemClock.elapsedRealtime();
19380        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19381        final int N = mLruProcesses.size();
19382
19383        if (false) {
19384            RuntimeException e = new RuntimeException();
19385            e.fillInStackTrace();
19386            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19387        }
19388
19389        // Reset state in all uid records.
19390        for (int i=mActiveUids.size()-1; i>=0; i--) {
19391            final UidRecord uidRec = mActiveUids.valueAt(i);
19392            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19393                    "Starting update of " + uidRec);
19394            uidRec.reset();
19395        }
19396
19397        mStackSupervisor.rankTaskLayersIfNeeded();
19398
19399        mAdjSeq++;
19400        mNewNumServiceProcs = 0;
19401        mNewNumAServiceProcs = 0;
19402
19403        final int emptyProcessLimit;
19404        final int cachedProcessLimit;
19405        if (mProcessLimit <= 0) {
19406            emptyProcessLimit = cachedProcessLimit = 0;
19407        } else if (mProcessLimit == 1) {
19408            emptyProcessLimit = 1;
19409            cachedProcessLimit = 0;
19410        } else {
19411            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19412            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19413        }
19414
19415        // Let's determine how many processes we have running vs.
19416        // how many slots we have for background processes; we may want
19417        // to put multiple processes in a slot of there are enough of
19418        // them.
19419        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19420                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19421        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19422        if (numEmptyProcs > cachedProcessLimit) {
19423            // If there are more empty processes than our limit on cached
19424            // processes, then use the cached process limit for the factor.
19425            // This ensures that the really old empty processes get pushed
19426            // down to the bottom, so if we are running low on memory we will
19427            // have a better chance at keeping around more cached processes
19428            // instead of a gazillion empty processes.
19429            numEmptyProcs = cachedProcessLimit;
19430        }
19431        int emptyFactor = numEmptyProcs/numSlots;
19432        if (emptyFactor < 1) emptyFactor = 1;
19433        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19434        if (cachedFactor < 1) cachedFactor = 1;
19435        int stepCached = 0;
19436        int stepEmpty = 0;
19437        int numCached = 0;
19438        int numEmpty = 0;
19439        int numTrimming = 0;
19440
19441        mNumNonCachedProcs = 0;
19442        mNumCachedHiddenProcs = 0;
19443
19444        // First update the OOM adjustment for each of the
19445        // application processes based on their current state.
19446        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19447        int nextCachedAdj = curCachedAdj+1;
19448        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19449        int nextEmptyAdj = curEmptyAdj+2;
19450        for (int i=N-1; i>=0; i--) {
19451            ProcessRecord app = mLruProcesses.get(i);
19452            if (!app.killedByAm && app.thread != null) {
19453                app.procStateChanged = false;
19454                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19455
19456                // If we haven't yet assigned the final cached adj
19457                // to the process, do that now.
19458                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19459                    switch (app.curProcState) {
19460                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19461                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19462                            // This process is a cached process holding activities...
19463                            // assign it the next cached value for that type, and then
19464                            // step that cached level.
19465                            app.curRawAdj = curCachedAdj;
19466                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19467                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19468                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19469                                    + ")");
19470                            if (curCachedAdj != nextCachedAdj) {
19471                                stepCached++;
19472                                if (stepCached >= cachedFactor) {
19473                                    stepCached = 0;
19474                                    curCachedAdj = nextCachedAdj;
19475                                    nextCachedAdj += 2;
19476                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19477                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19478                                    }
19479                                }
19480                            }
19481                            break;
19482                        default:
19483                            // For everything else, assign next empty cached process
19484                            // level and bump that up.  Note that this means that
19485                            // long-running services that have dropped down to the
19486                            // cached level will be treated as empty (since their process
19487                            // state is still as a service), which is what we want.
19488                            app.curRawAdj = curEmptyAdj;
19489                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19490                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19491                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19492                                    + ")");
19493                            if (curEmptyAdj != nextEmptyAdj) {
19494                                stepEmpty++;
19495                                if (stepEmpty >= emptyFactor) {
19496                                    stepEmpty = 0;
19497                                    curEmptyAdj = nextEmptyAdj;
19498                                    nextEmptyAdj += 2;
19499                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19500                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19501                                    }
19502                                }
19503                            }
19504                            break;
19505                    }
19506                }
19507
19508                applyOomAdjLocked(app, true, now, nowElapsed);
19509
19510                // Count the number of process types.
19511                switch (app.curProcState) {
19512                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19513                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19514                        mNumCachedHiddenProcs++;
19515                        numCached++;
19516                        if (numCached > cachedProcessLimit) {
19517                            app.kill("cached #" + numCached, true);
19518                        }
19519                        break;
19520                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19521                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19522                                && app.lastActivityTime < oldTime) {
19523                            app.kill("empty for "
19524                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19525                                    / 1000) + "s", true);
19526                        } else {
19527                            numEmpty++;
19528                            if (numEmpty > emptyProcessLimit) {
19529                                app.kill("empty #" + numEmpty, true);
19530                            }
19531                        }
19532                        break;
19533                    default:
19534                        mNumNonCachedProcs++;
19535                        break;
19536                }
19537
19538                if (app.isolated && app.services.size() <= 0) {
19539                    // If this is an isolated process, and there are no
19540                    // services running in it, then the process is no longer
19541                    // needed.  We agressively kill these because we can by
19542                    // definition not re-use the same process again, and it is
19543                    // good to avoid having whatever code was running in them
19544                    // left sitting around after no longer needed.
19545                    app.kill("isolated not needed", true);
19546                } else {
19547                    // Keeping this process, update its uid.
19548                    final UidRecord uidRec = app.uidRecord;
19549                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19550                        uidRec.curProcState = app.curProcState;
19551                    }
19552                }
19553
19554                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19555                        && !app.killedByAm) {
19556                    numTrimming++;
19557                }
19558            }
19559        }
19560
19561        mNumServiceProcs = mNewNumServiceProcs;
19562
19563        // Now determine the memory trimming level of background processes.
19564        // Unfortunately we need to start at the back of the list to do this
19565        // properly.  We only do this if the number of background apps we
19566        // are managing to keep around is less than half the maximum we desire;
19567        // if we are keeping a good number around, we'll let them use whatever
19568        // memory they want.
19569        final int numCachedAndEmpty = numCached + numEmpty;
19570        int memFactor;
19571        if (numCached <= ProcessList.TRIM_CACHED_APPS
19572                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19573            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19574                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19575            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19576                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19577            } else {
19578                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19579            }
19580        } else {
19581            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19582        }
19583        // We always allow the memory level to go up (better).  We only allow it to go
19584        // down if we are in a state where that is allowed, *and* the total number of processes
19585        // has gone down since last time.
19586        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19587                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19588                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19589        if (memFactor > mLastMemoryLevel) {
19590            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19591                memFactor = mLastMemoryLevel;
19592                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19593            }
19594        }
19595        mLastMemoryLevel = memFactor;
19596        mLastNumProcesses = mLruProcesses.size();
19597        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19598        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19599        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19600            if (mLowRamStartTime == 0) {
19601                mLowRamStartTime = now;
19602            }
19603            int step = 0;
19604            int fgTrimLevel;
19605            switch (memFactor) {
19606                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19607                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19608                    break;
19609                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19610                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19611                    break;
19612                default:
19613                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19614                    break;
19615            }
19616            int factor = numTrimming/3;
19617            int minFactor = 2;
19618            if (mHomeProcess != null) minFactor++;
19619            if (mPreviousProcess != null) minFactor++;
19620            if (factor < minFactor) factor = minFactor;
19621            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19622            for (int i=N-1; i>=0; i--) {
19623                ProcessRecord app = mLruProcesses.get(i);
19624                if (allChanged || app.procStateChanged) {
19625                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19626                    app.procStateChanged = false;
19627                }
19628                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19629                        && !app.killedByAm) {
19630                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19631                        try {
19632                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19633                                    "Trimming memory of " + app.processName + " to " + curLevel);
19634                            app.thread.scheduleTrimMemory(curLevel);
19635                        } catch (RemoteException e) {
19636                        }
19637                        if (false) {
19638                            // For now we won't do this; our memory trimming seems
19639                            // to be good enough at this point that destroying
19640                            // activities causes more harm than good.
19641                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19642                                    && app != mHomeProcess && app != mPreviousProcess) {
19643                                // Need to do this on its own message because the stack may not
19644                                // be in a consistent state at this point.
19645                                // For these apps we will also finish their activities
19646                                // to help them free memory.
19647                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19648                            }
19649                        }
19650                    }
19651                    app.trimMemoryLevel = curLevel;
19652                    step++;
19653                    if (step >= factor) {
19654                        step = 0;
19655                        switch (curLevel) {
19656                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19657                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19658                                break;
19659                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19660                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19661                                break;
19662                        }
19663                    }
19664                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19665                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19666                            && app.thread != null) {
19667                        try {
19668                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19669                                    "Trimming memory of heavy-weight " + app.processName
19670                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19671                            app.thread.scheduleTrimMemory(
19672                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19673                        } catch (RemoteException e) {
19674                        }
19675                    }
19676                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19677                } else {
19678                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19679                            || app.systemNoUi) && app.pendingUiClean) {
19680                        // If this application is now in the background and it
19681                        // had done UI, then give it the special trim level to
19682                        // have it free UI resources.
19683                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19684                        if (app.trimMemoryLevel < level && app.thread != null) {
19685                            try {
19686                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19687                                        "Trimming memory of bg-ui " + app.processName
19688                                        + " to " + level);
19689                                app.thread.scheduleTrimMemory(level);
19690                            } catch (RemoteException e) {
19691                            }
19692                        }
19693                        app.pendingUiClean = false;
19694                    }
19695                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19696                        try {
19697                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19698                                    "Trimming memory of fg " + app.processName
19699                                    + " to " + fgTrimLevel);
19700                            app.thread.scheduleTrimMemory(fgTrimLevel);
19701                        } catch (RemoteException e) {
19702                        }
19703                    }
19704                    app.trimMemoryLevel = fgTrimLevel;
19705                }
19706            }
19707        } else {
19708            if (mLowRamStartTime != 0) {
19709                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19710                mLowRamStartTime = 0;
19711            }
19712            for (int i=N-1; i>=0; i--) {
19713                ProcessRecord app = mLruProcesses.get(i);
19714                if (allChanged || app.procStateChanged) {
19715                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19716                    app.procStateChanged = false;
19717                }
19718                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19719                        || app.systemNoUi) && app.pendingUiClean) {
19720                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19721                            && app.thread != null) {
19722                        try {
19723                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19724                                    "Trimming memory of ui hidden " + app.processName
19725                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19726                            app.thread.scheduleTrimMemory(
19727                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19728                        } catch (RemoteException e) {
19729                        }
19730                    }
19731                    app.pendingUiClean = false;
19732                }
19733                app.trimMemoryLevel = 0;
19734            }
19735        }
19736
19737        if (mAlwaysFinishActivities) {
19738            // Need to do this on its own message because the stack may not
19739            // be in a consistent state at this point.
19740            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19741        }
19742
19743        if (allChanged) {
19744            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19745        }
19746
19747        // Update from any uid changes.
19748        for (int i=mActiveUids.size()-1; i>=0; i--) {
19749            final UidRecord uidRec = mActiveUids.valueAt(i);
19750            int uidChange = UidRecord.CHANGE_PROCSTATE;
19751            if (uidRec.setProcState != uidRec.curProcState) {
19752                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19753                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19754                        + " to " + uidRec.curProcState);
19755                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19756                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19757                        uidRec.lastBackgroundTime = nowElapsed;
19758                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19759                            // Note: the background settle time is in elapsed realtime, while
19760                            // the handler time base is uptime.  All this means is that we may
19761                            // stop background uids later than we had intended, but that only
19762                            // happens because the device was sleeping so we are okay anyway.
19763                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19764                        }
19765                    }
19766                } else {
19767                    if (uidRec.idle) {
19768                        uidChange = UidRecord.CHANGE_ACTIVE;
19769                        uidRec.idle = false;
19770                    }
19771                    uidRec.lastBackgroundTime = 0;
19772                }
19773                uidRec.setProcState = uidRec.curProcState;
19774                enqueueUidChangeLocked(uidRec, -1, uidChange);
19775            }
19776        }
19777
19778        if (mProcessStats.shouldWriteNowLocked(now)) {
19779            mHandler.post(new Runnable() {
19780                @Override public void run() {
19781                    synchronized (ActivityManagerService.this) {
19782                        mProcessStats.writeStateAsyncLocked();
19783                    }
19784                }
19785            });
19786        }
19787
19788        if (DEBUG_OOM_ADJ) {
19789            final long duration = SystemClock.uptimeMillis() - now;
19790            if (false) {
19791                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19792                        new RuntimeException("here").fillInStackTrace());
19793            } else {
19794                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19795            }
19796        }
19797    }
19798
19799    final void idleUids() {
19800        synchronized (this) {
19801            final long nowElapsed = SystemClock.elapsedRealtime();
19802            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
19803            long nextTime = 0;
19804            for (int i=mActiveUids.size()-1; i>=0; i--) {
19805                final UidRecord uidRec = mActiveUids.valueAt(i);
19806                final long bgTime = uidRec.lastBackgroundTime;
19807                if (bgTime > 0 && !uidRec.idle) {
19808                    if (bgTime <= maxBgTime) {
19809                        uidRec.idle = true;
19810                        doStopUidLocked(uidRec.uid, uidRec);
19811                    } else {
19812                        if (nextTime == 0 || nextTime > bgTime) {
19813                            nextTime = bgTime;
19814                        }
19815                    }
19816                }
19817            }
19818            if (nextTime > 0) {
19819                mHandler.removeMessages(IDLE_UIDS_MSG);
19820                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
19821                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
19822            }
19823        }
19824    }
19825
19826    final void runInBackgroundDisabled(int uid) {
19827        synchronized (this) {
19828            UidRecord uidRec = mActiveUids.get(uid);
19829            if (uidRec != null) {
19830                // This uid is actually running...  should it be considered background now?
19831                if (uidRec.idle) {
19832                    doStopUidLocked(uidRec.uid, uidRec);
19833                }
19834            } else {
19835                // This uid isn't actually running...  still send a report about it being "stopped".
19836                doStopUidLocked(uid, null);
19837            }
19838        }
19839    }
19840
19841    final void doStopUidLocked(int uid, final UidRecord uidRec) {
19842        mServices.stopInBackgroundLocked(uid);
19843        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
19844    }
19845
19846    final void trimApplications() {
19847        synchronized (this) {
19848            int i;
19849
19850            // First remove any unused application processes whose package
19851            // has been removed.
19852            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19853                final ProcessRecord app = mRemovedProcesses.get(i);
19854                if (app.activities.size() == 0
19855                        && app.curReceiver == null && app.services.size() == 0) {
19856                    Slog.i(
19857                        TAG, "Exiting empty application process "
19858                        + app.processName + " ("
19859                        + (app.thread != null ? app.thread.asBinder() : null)
19860                        + ")\n");
19861                    if (app.pid > 0 && app.pid != MY_PID) {
19862                        app.kill("empty", false);
19863                    } else {
19864                        try {
19865                            app.thread.scheduleExit();
19866                        } catch (Exception e) {
19867                            // Ignore exceptions.
19868                        }
19869                    }
19870                    cleanUpApplicationRecordLocked(app, false, true, -1);
19871                    mRemovedProcesses.remove(i);
19872
19873                    if (app.persistent) {
19874                        addAppLocked(app.info, false, null /* ABI override */);
19875                    }
19876                }
19877            }
19878
19879            // Now update the oom adj for all processes.
19880            updateOomAdjLocked();
19881        }
19882    }
19883
19884    /** This method sends the specified signal to each of the persistent apps */
19885    public void signalPersistentProcesses(int sig) throws RemoteException {
19886        if (sig != Process.SIGNAL_USR1) {
19887            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19888        }
19889
19890        synchronized (this) {
19891            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19892                    != PackageManager.PERMISSION_GRANTED) {
19893                throw new SecurityException("Requires permission "
19894                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19895            }
19896
19897            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19898                ProcessRecord r = mLruProcesses.get(i);
19899                if (r.thread != null && r.persistent) {
19900                    Process.sendSignal(r.pid, sig);
19901                }
19902            }
19903        }
19904    }
19905
19906    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19907        if (proc == null || proc == mProfileProc) {
19908            proc = mProfileProc;
19909            profileType = mProfileType;
19910            clearProfilerLocked();
19911        }
19912        if (proc == null) {
19913            return;
19914        }
19915        try {
19916            proc.thread.profilerControl(false, null, profileType);
19917        } catch (RemoteException e) {
19918            throw new IllegalStateException("Process disappeared");
19919        }
19920    }
19921
19922    private void clearProfilerLocked() {
19923        if (mProfileFd != null) {
19924            try {
19925                mProfileFd.close();
19926            } catch (IOException e) {
19927            }
19928        }
19929        mProfileApp = null;
19930        mProfileProc = null;
19931        mProfileFile = null;
19932        mProfileType = 0;
19933        mAutoStopProfiler = false;
19934        mSamplingInterval = 0;
19935    }
19936
19937    public boolean profileControl(String process, int userId, boolean start,
19938            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19939
19940        try {
19941            synchronized (this) {
19942                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19943                // its own permission.
19944                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19945                        != PackageManager.PERMISSION_GRANTED) {
19946                    throw new SecurityException("Requires permission "
19947                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19948                }
19949
19950                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19951                    throw new IllegalArgumentException("null profile info or fd");
19952                }
19953
19954                ProcessRecord proc = null;
19955                if (process != null) {
19956                    proc = findProcessLocked(process, userId, "profileControl");
19957                }
19958
19959                if (start && (proc == null || proc.thread == null)) {
19960                    throw new IllegalArgumentException("Unknown process: " + process);
19961                }
19962
19963                if (start) {
19964                    stopProfilerLocked(null, 0);
19965                    setProfileApp(proc.info, proc.processName, profilerInfo);
19966                    mProfileProc = proc;
19967                    mProfileType = profileType;
19968                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19969                    try {
19970                        fd = fd.dup();
19971                    } catch (IOException e) {
19972                        fd = null;
19973                    }
19974                    profilerInfo.profileFd = fd;
19975                    proc.thread.profilerControl(start, profilerInfo, profileType);
19976                    fd = null;
19977                    mProfileFd = null;
19978                } else {
19979                    stopProfilerLocked(proc, profileType);
19980                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19981                        try {
19982                            profilerInfo.profileFd.close();
19983                        } catch (IOException e) {
19984                        }
19985                    }
19986                }
19987
19988                return true;
19989            }
19990        } catch (RemoteException e) {
19991            throw new IllegalStateException("Process disappeared");
19992        } finally {
19993            if (profilerInfo != null && profilerInfo.profileFd != null) {
19994                try {
19995                    profilerInfo.profileFd.close();
19996                } catch (IOException e) {
19997                }
19998            }
19999        }
20000    }
20001
20002    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20003        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20004                userId, true, ALLOW_FULL_ONLY, callName, null);
20005        ProcessRecord proc = null;
20006        try {
20007            int pid = Integer.parseInt(process);
20008            synchronized (mPidsSelfLocked) {
20009                proc = mPidsSelfLocked.get(pid);
20010            }
20011        } catch (NumberFormatException e) {
20012        }
20013
20014        if (proc == null) {
20015            ArrayMap<String, SparseArray<ProcessRecord>> all
20016                    = mProcessNames.getMap();
20017            SparseArray<ProcessRecord> procs = all.get(process);
20018            if (procs != null && procs.size() > 0) {
20019                proc = procs.valueAt(0);
20020                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20021                    for (int i=1; i<procs.size(); i++) {
20022                        ProcessRecord thisProc = procs.valueAt(i);
20023                        if (thisProc.userId == userId) {
20024                            proc = thisProc;
20025                            break;
20026                        }
20027                    }
20028                }
20029            }
20030        }
20031
20032        return proc;
20033    }
20034
20035    public boolean dumpHeap(String process, int userId, boolean managed,
20036            String path, ParcelFileDescriptor fd) throws RemoteException {
20037
20038        try {
20039            synchronized (this) {
20040                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20041                // its own permission (same as profileControl).
20042                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20043                        != PackageManager.PERMISSION_GRANTED) {
20044                    throw new SecurityException("Requires permission "
20045                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20046                }
20047
20048                if (fd == null) {
20049                    throw new IllegalArgumentException("null fd");
20050                }
20051
20052                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20053                if (proc == null || proc.thread == null) {
20054                    throw new IllegalArgumentException("Unknown process: " + process);
20055                }
20056
20057                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20058                if (!isDebuggable) {
20059                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20060                        throw new SecurityException("Process not debuggable: " + proc);
20061                    }
20062                }
20063
20064                proc.thread.dumpHeap(managed, path, fd);
20065                fd = null;
20066                return true;
20067            }
20068        } catch (RemoteException e) {
20069            throw new IllegalStateException("Process disappeared");
20070        } finally {
20071            if (fd != null) {
20072                try {
20073                    fd.close();
20074                } catch (IOException e) {
20075                }
20076            }
20077        }
20078    }
20079
20080    @Override
20081    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20082            String reportPackage) {
20083        if (processName != null) {
20084            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20085                    "setDumpHeapDebugLimit()");
20086        } else {
20087            synchronized (mPidsSelfLocked) {
20088                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20089                if (proc == null) {
20090                    throw new SecurityException("No process found for calling pid "
20091                            + Binder.getCallingPid());
20092                }
20093                if (!Build.IS_DEBUGGABLE
20094                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20095                    throw new SecurityException("Not running a debuggable build");
20096                }
20097                processName = proc.processName;
20098                uid = proc.uid;
20099                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20100                    throw new SecurityException("Package " + reportPackage + " is not running in "
20101                            + proc);
20102                }
20103            }
20104        }
20105        synchronized (this) {
20106            if (maxMemSize > 0) {
20107                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20108            } else {
20109                if (uid != 0) {
20110                    mMemWatchProcesses.remove(processName, uid);
20111                } else {
20112                    mMemWatchProcesses.getMap().remove(processName);
20113                }
20114            }
20115        }
20116    }
20117
20118    @Override
20119    public void dumpHeapFinished(String path) {
20120        synchronized (this) {
20121            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20122                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20123                        + " does not match last pid " + mMemWatchDumpPid);
20124                return;
20125            }
20126            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20127                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20128                        + " does not match last path " + mMemWatchDumpFile);
20129                return;
20130            }
20131            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20132            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20133        }
20134    }
20135
20136    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20137    public void monitor() {
20138        synchronized (this) { }
20139    }
20140
20141    void onCoreSettingsChange(Bundle settings) {
20142        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20143            ProcessRecord processRecord = mLruProcesses.get(i);
20144            try {
20145                if (processRecord.thread != null) {
20146                    processRecord.thread.setCoreSettings(settings);
20147                }
20148            } catch (RemoteException re) {
20149                /* ignore */
20150            }
20151        }
20152    }
20153
20154    // Multi-user methods
20155
20156    /**
20157     * Start user, if its not already running, but don't bring it to foreground.
20158     */
20159    @Override
20160    public boolean startUserInBackground(final int userId) {
20161        return mUserController.startUser(userId, /* foreground */ false);
20162    }
20163
20164    @Override
20165    public boolean switchUser(final int userId) {
20166        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20167        String userName;
20168        synchronized (this) {
20169            UserInfo userInfo = mUserController.getUserInfo(userId);
20170            if (userInfo == null) {
20171                Slog.w(TAG, "No user info for user #" + userId);
20172                return false;
20173            }
20174            if (userInfo.isManagedProfile()) {
20175                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
20176                return false;
20177            }
20178            userName = userInfo.name;
20179            mUserController.setTargetUserIdLocked(userId);
20180        }
20181        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20182        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userId, 0,
20183                userName));
20184        return true;
20185    }
20186
20187    void scheduleStartProfilesLocked() {
20188        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20189            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20190                    DateUtils.SECOND_IN_MILLIS);
20191        }
20192    }
20193
20194    @Override
20195    public int stopUser(final int userId, final IStopUserCallback callback) {
20196        return mUserController.stopUser(userId, callback);
20197    }
20198
20199    void onUserRemovedLocked(int userId) {
20200        mRecentTasks.removeTasksForUserLocked(userId);
20201    }
20202
20203    @Override
20204    public UserInfo getCurrentUser() {
20205        return mUserController.getCurrentUser();
20206    }
20207
20208    @Override
20209    public boolean isUserRunning(int userId, int flags) {
20210        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20211                != PackageManager.PERMISSION_GRANTED) {
20212            String msg = "Permission Denial: isUserRunning() from pid="
20213                    + Binder.getCallingPid()
20214                    + ", uid=" + Binder.getCallingUid()
20215                    + " requires " + INTERACT_ACROSS_USERS;
20216            Slog.w(TAG, msg);
20217            throw new SecurityException(msg);
20218        }
20219        synchronized (this) {
20220            return mUserController.isUserRunningLocked(userId, flags);
20221        }
20222    }
20223
20224    @Override
20225    public int[] getRunningUserIds() {
20226        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20227                != PackageManager.PERMISSION_GRANTED) {
20228            String msg = "Permission Denial: isUserRunning() from pid="
20229                    + Binder.getCallingPid()
20230                    + ", uid=" + Binder.getCallingUid()
20231                    + " requires " + INTERACT_ACROSS_USERS;
20232            Slog.w(TAG, msg);
20233            throw new SecurityException(msg);
20234        }
20235        synchronized (this) {
20236            return mUserController.getStartedUserArrayLocked();
20237        }
20238    }
20239
20240    @Override
20241    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20242        mUserController.registerUserSwitchObserver(observer);
20243    }
20244
20245    @Override
20246    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20247        mUserController.unregisterUserSwitchObserver(observer);
20248    }
20249
20250    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20251        if (info == null) return null;
20252        ApplicationInfo newInfo = new ApplicationInfo(info);
20253        newInfo.initForUser(userId);
20254        return newInfo;
20255    }
20256
20257    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20258        if (aInfo == null
20259                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20260            return aInfo;
20261        }
20262
20263        ActivityInfo info = new ActivityInfo(aInfo);
20264        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20265        return info;
20266    }
20267
20268    private boolean processSanityChecksLocked(ProcessRecord process) {
20269        if (process == null || process.thread == null) {
20270            return false;
20271        }
20272
20273        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20274        if (!isDebuggable) {
20275            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20276                return false;
20277            }
20278        }
20279
20280        return true;
20281    }
20282
20283    public boolean startBinderTracking() throws RemoteException {
20284        synchronized (this) {
20285            mBinderTransactionTrackingEnabled = true;
20286            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20287            // permission (same as profileControl).
20288            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20289                    != PackageManager.PERMISSION_GRANTED) {
20290                throw new SecurityException("Requires permission "
20291                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20292            }
20293
20294            for (int i = 0; i < mLruProcesses.size(); i++) {
20295                ProcessRecord process = mLruProcesses.get(i);
20296                if (!processSanityChecksLocked(process)) {
20297                    continue;
20298                }
20299                try {
20300                    process.thread.startBinderTracking();
20301                } catch (RemoteException e) {
20302                    Log.v(TAG, "Process disappared");
20303                }
20304            }
20305            return true;
20306        }
20307    }
20308
20309    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20310        try {
20311            synchronized (this) {
20312                mBinderTransactionTrackingEnabled = false;
20313                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20314                // permission (same as profileControl).
20315                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20316                        != PackageManager.PERMISSION_GRANTED) {
20317                    throw new SecurityException("Requires permission "
20318                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20319                }
20320
20321                if (fd == null) {
20322                    throw new IllegalArgumentException("null fd");
20323                }
20324
20325                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20326                pw.println("Binder transaction traces for all processes.\n");
20327                for (ProcessRecord process : mLruProcesses) {
20328                    if (!processSanityChecksLocked(process)) {
20329                        continue;
20330                    }
20331
20332                    pw.println("Traces for process: " + process.processName);
20333                    pw.flush();
20334                    try {
20335                        TransferPipe tp = new TransferPipe();
20336                        try {
20337                            process.thread.stopBinderTrackingAndDump(
20338                                    tp.getWriteFd().getFileDescriptor());
20339                            tp.go(fd.getFileDescriptor());
20340                        } finally {
20341                            tp.kill();
20342                        }
20343                    } catch (IOException e) {
20344                        pw.println("Failure while dumping IPC traces from " + process +
20345                                ".  Exception: " + e);
20346                        pw.flush();
20347                    } catch (RemoteException e) {
20348                        pw.println("Got a RemoteException while dumping IPC traces from " +
20349                                process + ".  Exception: " + e);
20350                        pw.flush();
20351                    }
20352                }
20353                fd = null;
20354                return true;
20355            }
20356        } finally {
20357            if (fd != null) {
20358                try {
20359                    fd.close();
20360                } catch (IOException e) {
20361                }
20362            }
20363        }
20364    }
20365
20366    void stopReportingCrashesLocked(ProcessRecord proc) {
20367        if (mAppsNotReportingCrashes == null) {
20368            mAppsNotReportingCrashes = new ArraySet<>();
20369        }
20370        mAppsNotReportingCrashes.add(proc.info.packageName);
20371    }
20372
20373    private final class LocalService extends ActivityManagerInternal {
20374        @Override
20375        public void onWakefulnessChanged(int wakefulness) {
20376            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20377        }
20378
20379        @Override
20380        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20381                String processName, String abiOverride, int uid, Runnable crashHandler) {
20382            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20383                    processName, abiOverride, uid, crashHandler);
20384        }
20385
20386        @Override
20387        public SleepToken acquireSleepToken(String tag) {
20388            Preconditions.checkNotNull(tag);
20389
20390            synchronized (ActivityManagerService.this) {
20391                SleepTokenImpl token = new SleepTokenImpl(tag);
20392                mSleepTokens.add(token);
20393                updateSleepIfNeededLocked();
20394                return token;
20395            }
20396        }
20397
20398        @Override
20399        public ComponentName getHomeActivityForUser(int userId) {
20400            synchronized (ActivityManagerService.this) {
20401                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20402                return homeActivity == null ? null : homeActivity.realActivity;
20403            }
20404        }
20405
20406        @Override
20407        public void onUserRemoved(int userId) {
20408            synchronized (ActivityManagerService.this) {
20409                ActivityManagerService.this.onUserRemovedLocked(userId);
20410            }
20411        }
20412    }
20413
20414    private final class SleepTokenImpl extends SleepToken {
20415        private final String mTag;
20416        private final long mAcquireTime;
20417
20418        public SleepTokenImpl(String tag) {
20419            mTag = tag;
20420            mAcquireTime = SystemClock.uptimeMillis();
20421        }
20422
20423        @Override
20424        public void release() {
20425            synchronized (ActivityManagerService.this) {
20426                if (mSleepTokens.remove(this)) {
20427                    updateSleepIfNeededLocked();
20428                }
20429            }
20430        }
20431
20432        @Override
20433        public String toString() {
20434            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20435        }
20436    }
20437
20438    /**
20439     * An implementation of IAppTask, that allows an app to manage its own tasks via
20440     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20441     * only the process that calls getAppTasks() can call the AppTask methods.
20442     */
20443    class AppTaskImpl extends IAppTask.Stub {
20444        private int mTaskId;
20445        private int mCallingUid;
20446
20447        public AppTaskImpl(int taskId, int callingUid) {
20448            mTaskId = taskId;
20449            mCallingUid = callingUid;
20450        }
20451
20452        private void checkCaller() {
20453            if (mCallingUid != Binder.getCallingUid()) {
20454                throw new SecurityException("Caller " + mCallingUid
20455                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20456            }
20457        }
20458
20459        @Override
20460        public void finishAndRemoveTask() {
20461            checkCaller();
20462
20463            synchronized (ActivityManagerService.this) {
20464                long origId = Binder.clearCallingIdentity();
20465                try {
20466                    // We remove the task from recents to preserve backwards
20467                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20468                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20469                    }
20470                } finally {
20471                    Binder.restoreCallingIdentity(origId);
20472                }
20473            }
20474        }
20475
20476        @Override
20477        public ActivityManager.RecentTaskInfo getTaskInfo() {
20478            checkCaller();
20479
20480            synchronized (ActivityManagerService.this) {
20481                long origId = Binder.clearCallingIdentity();
20482                try {
20483                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20484                    if (tr == null) {
20485                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20486                    }
20487                    return createRecentTaskInfoFromTaskRecord(tr);
20488                } finally {
20489                    Binder.restoreCallingIdentity(origId);
20490                }
20491            }
20492        }
20493
20494        @Override
20495        public void moveToFront() {
20496            checkCaller();
20497            // Will bring task to front if it already has a root activity.
20498            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20499        }
20500
20501        @Override
20502        public int startActivity(IBinder whoThread, String callingPackage,
20503                Intent intent, String resolvedType, Bundle bOptions) {
20504            checkCaller();
20505
20506            int callingUser = UserHandle.getCallingUserId();
20507            TaskRecord tr;
20508            IApplicationThread appThread;
20509            synchronized (ActivityManagerService.this) {
20510                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20511                if (tr == null) {
20512                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20513                }
20514                appThread = ApplicationThreadNative.asInterface(whoThread);
20515                if (appThread == null) {
20516                    throw new IllegalArgumentException("Bad app thread " + appThread);
20517                }
20518            }
20519            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20520                    resolvedType, null, null, null, null, 0, 0, null, null,
20521                    null, bOptions, false, callingUser, null, tr);
20522        }
20523
20524        @Override
20525        public void setExcludeFromRecents(boolean exclude) {
20526            checkCaller();
20527
20528            synchronized (ActivityManagerService.this) {
20529                long origId = Binder.clearCallingIdentity();
20530                try {
20531                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20532                    if (tr == null) {
20533                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20534                    }
20535                    Intent intent = tr.getBaseIntent();
20536                    if (exclude) {
20537                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20538                    } else {
20539                        intent.setFlags(intent.getFlags()
20540                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20541                    }
20542                } finally {
20543                    Binder.restoreCallingIdentity(origId);
20544                }
20545            }
20546        }
20547    }
20548}
20549