ActivityManagerService.java revision bac13378ca2490e98e814908984bc9184ed1d42b
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.DOCKED_STACK_ID;
23import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
24import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
25import static android.app.ActivityManager.HOME_STACK_ID;
26import static android.app.ActivityManager.INVALID_STACK_ID;
27import static android.app.ActivityManager.PINNED_STACK_ID;
28import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29import static android.content.pm.PackageManager.PERMISSION_GRANTED;
30import static com.android.internal.util.XmlUtils.readBooleanAttribute;
31import static com.android.internal.util.XmlUtils.readIntAttribute;
32import static com.android.internal.util.XmlUtils.readLongAttribute;
33import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
34import static com.android.internal.util.XmlUtils.writeIntAttribute;
35import static com.android.internal.util.XmlUtils.writeLongAttribute;
36import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
37import static com.android.server.am.ActivityManagerDebugConfig.*;
38import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
39import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
40import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
41import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
42import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
43import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
44import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
45import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
46import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
47import static org.xmlpull.v1.XmlPullParser.START_TAG;
48
49import android.Manifest;
50import android.app.AppOpsManager;
51import android.app.ApplicationThreadNative;
52import android.app.BroadcastOptions;
53import android.app.IActivityContainer;
54import android.app.IActivityContainerCallback;
55import android.app.IAppTask;
56import android.app.ITaskStackListener;
57import android.app.ProfilerInfo;
58import android.app.assist.AssistContent;
59import android.app.assist.AssistStructure;
60import android.app.usage.UsageEvents;
61import android.app.usage.UsageStatsManagerInternal;
62import android.appwidget.AppWidgetManager;
63import android.content.pm.AppsQueryHelper;
64import android.content.pm.PermissionInfo;
65import android.content.res.Resources;
66import android.graphics.Bitmap;
67import android.graphics.Point;
68import android.graphics.Rect;
69import android.os.BatteryStats;
70import android.os.PersistableBundle;
71import android.os.PowerManager;
72import android.os.ResultReceiver;
73import android.os.Trace;
74import android.os.TransactionTooLargeException;
75import android.os.WorkSource;
76import android.os.storage.IMountService;
77import android.os.storage.MountServiceInternal;
78import android.os.storage.StorageManager;
79import android.provider.Settings.Global;
80import android.service.voice.IVoiceInteractionSession;
81import android.service.voice.VoiceInteractionSession;
82import android.util.ArrayMap;
83import android.util.ArraySet;
84import android.util.DebugUtils;
85import android.view.Display;
86
87import com.android.internal.R;
88import com.android.internal.annotations.GuardedBy;
89import com.android.internal.app.AssistUtils;
90import com.android.internal.app.DumpHeapActivity;
91import com.android.internal.app.IAppOpsService;
92import com.android.internal.app.IVoiceInteractor;
93import com.android.internal.app.ProcessMap;
94import com.android.internal.app.ProcessStats;
95import com.android.internal.os.BackgroundThread;
96import com.android.internal.os.BatteryStatsImpl;
97import com.android.internal.os.IResultReceiver;
98import com.android.internal.os.ProcessCpuTracker;
99import com.android.internal.os.TransferPipe;
100import com.android.internal.os.Zygote;
101import com.android.internal.util.ArrayUtils;
102import com.android.internal.util.FastPrintWriter;
103import com.android.internal.util.FastXmlSerializer;
104import com.android.internal.util.MemInfoReader;
105import com.android.internal.util.Preconditions;
106import com.android.server.AppOpsService;
107import com.android.server.AttributeCache;
108import com.android.server.DeviceIdleController;
109import com.android.server.IntentResolver;
110import com.android.server.LocalServices;
111import com.android.server.ServiceThread;
112import com.android.server.SystemConfig;
113import com.android.server.SystemService;
114import com.android.server.SystemServiceManager;
115import com.android.server.Watchdog;
116import com.android.server.am.ActivityStack.ActivityState;
117import com.android.server.firewall.IntentFirewall;
118import com.android.server.pm.Installer;
119import com.android.server.pm.UserManagerService;
120import com.android.server.statusbar.StatusBarManagerInternal;
121import com.android.server.wm.AppTransition;
122import com.android.server.wm.WindowManagerService;
123import com.google.android.collect.Lists;
124import com.google.android.collect.Maps;
125
126import libcore.io.IoUtils;
127import libcore.util.EmptyArray;
128
129import org.xmlpull.v1.XmlPullParser;
130import org.xmlpull.v1.XmlPullParserException;
131import org.xmlpull.v1.XmlSerializer;
132
133import android.app.Activity;
134import android.app.ActivityManager;
135import android.app.ActivityManager.RunningTaskInfo;
136import android.app.ActivityManager.StackInfo;
137import android.app.ActivityManagerInternal;
138import android.app.ActivityManagerInternal.SleepToken;
139import android.app.ActivityManagerNative;
140import android.app.ActivityOptions;
141import android.app.ActivityThread;
142import android.app.AlertDialog;
143import android.app.AppGlobals;
144import android.app.ApplicationErrorReport;
145import android.app.Dialog;
146import android.app.IActivityController;
147import android.app.IApplicationThread;
148import android.app.IInstrumentationWatcher;
149import android.app.INotificationManager;
150import android.app.IProcessObserver;
151import android.app.IServiceConnection;
152import android.app.IStopUserCallback;
153import android.app.IUidObserver;
154import android.app.IUiAutomationConnection;
155import android.app.IUserSwitchObserver;
156import android.app.Instrumentation;
157import android.app.Notification;
158import android.app.NotificationManager;
159import android.app.PendingIntent;
160import android.app.backup.IBackupManager;
161import android.app.admin.DevicePolicyManager;
162import android.content.ActivityNotFoundException;
163import android.content.BroadcastReceiver;
164import android.content.ClipData;
165import android.content.ComponentCallbacks2;
166import android.content.ComponentName;
167import android.content.ContentProvider;
168import android.content.ContentResolver;
169import android.content.Context;
170import android.content.DialogInterface;
171import android.content.IContentProvider;
172import android.content.IIntentReceiver;
173import android.content.IIntentSender;
174import android.content.Intent;
175import android.content.IntentFilter;
176import android.content.IntentSender;
177import android.content.pm.ActivityInfo;
178import android.content.pm.ApplicationInfo;
179import android.content.pm.ConfigurationInfo;
180import android.content.pm.IPackageDataObserver;
181import android.content.pm.IPackageManager;
182import android.content.pm.InstrumentationInfo;
183import android.content.pm.PackageInfo;
184import android.content.pm.PackageManager;
185import android.content.pm.ParceledListSlice;
186import android.content.pm.UserInfo;
187import android.content.pm.PackageManager.NameNotFoundException;
188import android.content.pm.PathPermission;
189import android.content.pm.ProviderInfo;
190import android.content.pm.ResolveInfo;
191import android.content.pm.ServiceInfo;
192import android.content.res.CompatibilityInfo;
193import android.content.res.Configuration;
194import android.net.Proxy;
195import android.net.ProxyInfo;
196import android.net.Uri;
197import android.os.Binder;
198import android.os.Build;
199import android.os.Bundle;
200import android.os.Debug;
201import android.os.DropBoxManager;
202import android.os.Environment;
203import android.os.FactoryTest;
204import android.os.FileObserver;
205import android.os.FileUtils;
206import android.os.Handler;
207import android.os.IBinder;
208import android.os.IPermissionController;
209import android.os.IProcessInfoService;
210import android.os.IUserManager;
211import android.os.Looper;
212import android.os.Message;
213import android.os.Parcel;
214import android.os.ParcelFileDescriptor;
215import android.os.PowerManagerInternal;
216import android.os.Process;
217import android.os.RemoteCallbackList;
218import android.os.RemoteException;
219import android.os.ServiceManager;
220import android.os.StrictMode;
221import android.os.SystemClock;
222import android.os.SystemProperties;
223import android.os.UpdateLock;
224import android.os.UserHandle;
225import android.os.UserManager;
226import android.provider.Settings;
227import android.text.format.DateUtils;
228import android.text.format.Time;
229import android.util.AtomicFile;
230import android.util.EventLog;
231import android.util.Log;
232import android.util.Pair;
233import android.util.PrintWriterPrinter;
234import android.util.Slog;
235import android.util.SparseArray;
236import android.util.TimeUtils;
237import android.util.Xml;
238import android.view.Gravity;
239import android.view.LayoutInflater;
240import android.view.View;
241import android.view.WindowManager;
242
243import dalvik.system.VMRuntime;
244
245import java.io.BufferedInputStream;
246import java.io.BufferedOutputStream;
247import java.io.DataInputStream;
248import java.io.DataOutputStream;
249import java.io.File;
250import java.io.FileDescriptor;
251import java.io.FileInputStream;
252import java.io.FileNotFoundException;
253import java.io.FileOutputStream;
254import java.io.IOException;
255import java.io.InputStreamReader;
256import java.io.PrintWriter;
257import java.io.StringWriter;
258import java.lang.ref.WeakReference;
259import java.nio.charset.StandardCharsets;
260import java.util.ArrayList;
261import java.util.Arrays;
262import java.util.Collections;
263import java.util.Comparator;
264import java.util.HashMap;
265import java.util.HashSet;
266import java.util.Iterator;
267import java.util.List;
268import java.util.Locale;
269import java.util.Map;
270import java.util.Set;
271import java.util.concurrent.atomic.AtomicBoolean;
272import java.util.concurrent.atomic.AtomicLong;
273
274public final class ActivityManagerService extends ActivityManagerNative
275        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
276
277    // File that stores last updated system version and called preboot receivers
278    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
279
280    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
281    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
282    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
283    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
284    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
285    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
286    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
287    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
288    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
289    private static final String TAG_LRU = TAG + POSTFIX_LRU;
290    private static final String TAG_MU = TAG + POSTFIX_MU;
291    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
292    private static final String TAG_POWER = TAG + POSTFIX_POWER;
293    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
294    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
295    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
296    private static final String TAG_PSS = TAG + POSTFIX_PSS;
297    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
298    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
299    private static final String TAG_STACK = TAG + POSTFIX_STACK;
300    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
301    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
302    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
303    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
304    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
305
306    /** Control over CPU and battery monitoring */
307    // write battery stats every 30 minutes.
308    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
309    static final boolean MONITOR_CPU_USAGE = true;
310    // don't sample cpu less than every 5 seconds.
311    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
312    // wait possibly forever for next cpu sample.
313    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
314    static final boolean MONITOR_THREAD_CPU_USAGE = false;
315
316    // The flags that are set for all calls we make to the package manager.
317    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
318
319    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
320
321    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
322
323    // Amount of time after a call to stopAppSwitches() during which we will
324    // prevent further untrusted switches from happening.
325    static final long APP_SWITCH_DELAY_TIME = 5*1000;
326
327    // How long we wait for a launched process to attach to the activity manager
328    // before we decide it's never going to come up for real.
329    static final int PROC_START_TIMEOUT = 10*1000;
330    // How long we wait for an attached process to publish its content providers
331    // before we decide it must be hung.
332    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
333
334    // How long we wait for a launched process to attach to the activity manager
335    // before we decide it's never going to come up for real, when the process was
336    // started with a wrapper for instrumentation (such as Valgrind) because it
337    // could take much longer than usual.
338    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
339
340    // How long to wait after going idle before forcing apps to GC.
341    static final int GC_TIMEOUT = 5*1000;
342
343    // The minimum amount of time between successive GC requests for a process.
344    static final int GC_MIN_INTERVAL = 60*1000;
345
346    // The minimum amount of time between successive PSS requests for a process.
347    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
348
349    // The minimum amount of time between successive PSS requests for a process
350    // when the request is due to the memory state being lowered.
351    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
352
353    // The rate at which we check for apps using excessive power -- 15 mins.
354    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
355
356    // The minimum sample duration we will allow before deciding we have
357    // enough data on wake locks to start killing things.
358    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
359
360    // The minimum sample duration we will allow before deciding we have
361    // enough data on CPU usage to start killing things.
362    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
363
364    // How long we allow a receiver to run before giving up on it.
365    static final int BROADCAST_FG_TIMEOUT = 10*1000;
366    static final int BROADCAST_BG_TIMEOUT = 60*1000;
367
368    // How long we wait until we timeout on key dispatching.
369    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
370
371    // How long we wait until we timeout on key dispatching during instrumentation.
372    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
373
374    // This is the amount of time an app needs to be running a foreground service before
375    // we will consider it to be doing interaction for usage stats.
376    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
377
378    // How long to wait in getAssistContextExtras for the activity and foreground services
379    // to respond with the result.
380    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
381
382    // How long top wait when going through the modern assist (which doesn't need to block
383    // on getting this result before starting to launch its UI).
384    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
385
386    // Maximum number of persisted Uri grants a package is allowed
387    static final int MAX_PERSISTED_URI_GRANTS = 128;
388
389    static final int MY_PID = Process.myPid();
390
391    static final String[] EMPTY_STRING_ARRAY = new String[0];
392
393    // How many bytes to write into the dropbox log before truncating
394    static final int DROPBOX_MAX_SIZE = 256 * 1024;
395
396    // Access modes for handleIncomingUser.
397    static final int ALLOW_NON_FULL = 0;
398    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
399    static final int ALLOW_FULL_ONLY = 2;
400
401    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
402
403    // Delay in notifying task stack change listeners (in millis)
404    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
405
406    // Necessary ApplicationInfo flags to mark an app as persistent
407    private static final int PERSISTENT_MASK =
408            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
409
410
411    // Delay to disable app launch boost
412    static final int APP_BOOST_MESSAGE_DELAY = 3000;
413    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
414    static final int APP_BOOST_TIMEOUT = 2500;
415
416    // Used to indicate that a task is removed it should also be removed from recents.
417    private static final boolean REMOVE_FROM_RECENTS = true;
418
419    private static native int nativeMigrateToBoost();
420    private static native int nativeMigrateFromBoost();
421    private boolean mIsBoosted = false;
422    private long mBoostStartTime = 0;
423
424    /** All system services */
425    SystemServiceManager mSystemServiceManager;
426
427    private Installer mInstaller;
428
429    /** Run all ActivityStacks through this */
430    ActivityStackSupervisor mStackSupervisor;
431
432    /** Task stack change listeners. */
433    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
434            new RemoteCallbackList<ITaskStackListener>();
435
436    public IntentFirewall mIntentFirewall;
437
438    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
439    // default actuion automatically.  Important for devices without direct input
440    // devices.
441    private boolean mShowDialogs = true;
442
443    BroadcastQueue mFgBroadcastQueue;
444    BroadcastQueue mBgBroadcastQueue;
445    // Convenient for easy iteration over the queues. Foreground is first
446    // so that dispatch of foreground broadcasts gets precedence.
447    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
448
449    BroadcastQueue broadcastQueueForIntent(Intent intent) {
450        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
451        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
452                "Broadcast intent " + intent + " on "
453                + (isFg ? "foreground" : "background") + " queue");
454        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
455    }
456
457    /**
458     * Activity we have told the window manager to have key focus.
459     */
460    ActivityRecord mFocusedActivity = null;
461
462    /**
463     * User id of the last activity mFocusedActivity was set to.
464     */
465    private int mLastFocusedUserId;
466
467    /**
468     * If non-null, we are tracking the time the user spends in the currently focused app.
469     */
470    private AppTimeTracker mCurAppTimeTracker;
471
472    /**
473     * List of intents that were used to start the most recent tasks.
474     */
475    private final RecentTasks mRecentTasks;
476
477    /**
478     * For addAppTask: cached of the last activity component that was added.
479     */
480    ComponentName mLastAddedTaskComponent;
481
482    /**
483     * For addAppTask: cached of the last activity uid that was added.
484     */
485    int mLastAddedTaskUid;
486
487    /**
488     * For addAppTask: cached of the last ActivityInfo that was added.
489     */
490    ActivityInfo mLastAddedTaskActivity;
491
492    /**
493     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
494     */
495    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
496
497    /**
498     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
499     */
500    String mDeviceOwnerName;
501
502    final UserController mUserController;
503
504    public class PendingAssistExtras extends Binder implements Runnable {
505        public final ActivityRecord activity;
506        public final Bundle extras;
507        public final Intent intent;
508        public final String hint;
509        public final IResultReceiver receiver;
510        public final int userHandle;
511        public boolean haveResult = false;
512        public Bundle result = null;
513        public AssistStructure structure = null;
514        public AssistContent content = null;
515        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
516                String _hint, IResultReceiver _receiver, int _userHandle) {
517            activity = _activity;
518            extras = _extras;
519            intent = _intent;
520            hint = _hint;
521            receiver = _receiver;
522            userHandle = _userHandle;
523        }
524        @Override
525        public void run() {
526            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
527            synchronized (this) {
528                haveResult = true;
529                notifyAll();
530            }
531            pendingAssistExtrasTimedOut(this);
532        }
533    }
534
535    final ArrayList<PendingAssistExtras> mPendingAssistExtras
536            = new ArrayList<PendingAssistExtras>();
537
538    /**
539     * Process management.
540     */
541    final ProcessList mProcessList = new ProcessList();
542
543    /**
544     * All of the applications we currently have running organized by name.
545     * The keys are strings of the application package name (as
546     * returned by the package manager), and the keys are ApplicationRecord
547     * objects.
548     */
549    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
550
551    /**
552     * Tracking long-term execution of processes to look for abuse and other
553     * bad app behavior.
554     */
555    final ProcessStatsService mProcessStats;
556
557    /**
558     * The currently running isolated processes.
559     */
560    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
561
562    /**
563     * Counter for assigning isolated process uids, to avoid frequently reusing the
564     * same ones.
565     */
566    int mNextIsolatedProcessUid = 0;
567
568    /**
569     * The currently running heavy-weight process, if any.
570     */
571    ProcessRecord mHeavyWeightProcess = null;
572
573    /**
574     * The last time that various processes have crashed.
575     */
576    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
577
578    /**
579     * Information about a process that is currently marked as bad.
580     */
581    static final class BadProcessInfo {
582        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
583            this.time = time;
584            this.shortMsg = shortMsg;
585            this.longMsg = longMsg;
586            this.stack = stack;
587        }
588
589        final long time;
590        final String shortMsg;
591        final String longMsg;
592        final String stack;
593    }
594
595    /**
596     * Set of applications that we consider to be bad, and will reject
597     * incoming broadcasts from (which the user has no control over).
598     * Processes are added to this set when they have crashed twice within
599     * a minimum amount of time; they are removed from it when they are
600     * later restarted (hopefully due to some user action).  The value is the
601     * time it was added to the list.
602     */
603    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
604
605    /**
606     * All of the processes we currently have running organized by pid.
607     * The keys are the pid running the application.
608     *
609     * <p>NOTE: This object is protected by its own lock, NOT the global
610     * activity manager lock!
611     */
612    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
613
614    /**
615     * All of the processes that have been forced to be foreground.  The key
616     * is the pid of the caller who requested it (we hold a death
617     * link on it).
618     */
619    abstract class ForegroundToken implements IBinder.DeathRecipient {
620        int pid;
621        IBinder token;
622    }
623    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
624
625    /**
626     * List of records for processes that someone had tried to start before the
627     * system was ready.  We don't start them at that point, but ensure they
628     * are started by the time booting is complete.
629     */
630    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
631
632    /**
633     * List of persistent applications that are in the process
634     * of being started.
635     */
636    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
637
638    /**
639     * Processes that are being forcibly torn down.
640     */
641    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
642
643    /**
644     * List of running applications, sorted by recent usage.
645     * The first entry in the list is the least recently used.
646     */
647    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
648
649    /**
650     * Where in mLruProcesses that the processes hosting activities start.
651     */
652    int mLruProcessActivityStart = 0;
653
654    /**
655     * Where in mLruProcesses that the processes hosting services start.
656     * This is after (lower index) than mLruProcessesActivityStart.
657     */
658    int mLruProcessServiceStart = 0;
659
660    /**
661     * List of processes that should gc as soon as things are idle.
662     */
663    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
664
665    /**
666     * Processes we want to collect PSS data from.
667     */
668    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
669
670    private boolean mBinderTransactionTrackingEnabled = false;
671
672    /**
673     * Last time we requested PSS data of all processes.
674     */
675    long mLastFullPssTime = SystemClock.uptimeMillis();
676
677    /**
678     * If set, the next time we collect PSS data we should do a full collection
679     * with data from native processes and the kernel.
680     */
681    boolean mFullPssPending = false;
682
683    /**
684     * This is the process holding what we currently consider to be
685     * the "home" activity.
686     */
687    ProcessRecord mHomeProcess;
688
689    /**
690     * This is the process holding the activity the user last visited that
691     * is in a different process from the one they are currently in.
692     */
693    ProcessRecord mPreviousProcess;
694
695    /**
696     * The time at which the previous process was last visible.
697     */
698    long mPreviousProcessVisibleTime;
699
700    /**
701     * Track all uids that have actively running processes.
702     */
703    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
704
705    /**
706     * Packages that the user has asked to have run in screen size
707     * compatibility mode instead of filling the screen.
708     */
709    final CompatModePackages mCompatModePackages;
710
711    /**
712     * Set of IntentSenderRecord objects that are currently active.
713     */
714    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
715            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
716
717    /**
718     * Fingerprints (hashCode()) of stack traces that we've
719     * already logged DropBox entries for.  Guarded by itself.  If
720     * something (rogue user app) forces this over
721     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
722     */
723    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
724    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
725
726    /**
727     * Strict Mode background batched logging state.
728     *
729     * The string buffer is guarded by itself, and its lock is also
730     * used to determine if another batched write is already
731     * in-flight.
732     */
733    private final StringBuilder mStrictModeBuffer = new StringBuilder();
734
735    /**
736     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
737     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
738     */
739    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
740
741    /**
742     * Resolver for broadcast intents to registered receivers.
743     * Holds BroadcastFilter (subclass of IntentFilter).
744     */
745    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
746            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
747        @Override
748        protected boolean allowFilterResult(
749                BroadcastFilter filter, List<BroadcastFilter> dest) {
750            IBinder target = filter.receiverList.receiver.asBinder();
751            for (int i = dest.size() - 1; i >= 0; i--) {
752                if (dest.get(i).receiverList.receiver.asBinder() == target) {
753                    return false;
754                }
755            }
756            return true;
757        }
758
759        @Override
760        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
761            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
762                    || userId == filter.owningUserId) {
763                return super.newResult(filter, match, userId);
764            }
765            return null;
766        }
767
768        @Override
769        protected BroadcastFilter[] newArray(int size) {
770            return new BroadcastFilter[size];
771        }
772
773        @Override
774        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
775            return packageName.equals(filter.packageName);
776        }
777    };
778
779    /**
780     * State of all active sticky broadcasts per user.  Keys are the action of the
781     * sticky Intent, values are an ArrayList of all broadcasted intents with
782     * that action (which should usually be one).  The SparseArray is keyed
783     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
784     * for stickies that are sent to all users.
785     */
786    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
787            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
788
789    final ActiveServices mServices;
790
791    final static class Association {
792        final int mSourceUid;
793        final String mSourceProcess;
794        final int mTargetUid;
795        final ComponentName mTargetComponent;
796        final String mTargetProcess;
797
798        int mCount;
799        long mTime;
800
801        int mNesting;
802        long mStartTime;
803
804        Association(int sourceUid, String sourceProcess, int targetUid,
805                ComponentName targetComponent, String targetProcess) {
806            mSourceUid = sourceUid;
807            mSourceProcess = sourceProcess;
808            mTargetUid = targetUid;
809            mTargetComponent = targetComponent;
810            mTargetProcess = targetProcess;
811        }
812    }
813
814    /**
815     * When service association tracking is enabled, this is all of the associations we
816     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
817     * -> association data.
818     */
819    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
820            mAssociations = new SparseArray<>();
821    boolean mTrackingAssociations;
822
823    /**
824     * Backup/restore process management
825     */
826    String mBackupAppName = null;
827    BackupRecord mBackupTarget = null;
828
829    final ProviderMap mProviderMap;
830
831    /**
832     * List of content providers who have clients waiting for them.  The
833     * application is currently being launched and the provider will be
834     * removed from this list once it is published.
835     */
836    final ArrayList<ContentProviderRecord> mLaunchingProviders
837            = new ArrayList<ContentProviderRecord>();
838
839    /**
840     * File storing persisted {@link #mGrantedUriPermissions}.
841     */
842    private final AtomicFile mGrantFile;
843
844    /** XML constants used in {@link #mGrantFile} */
845    private static final String TAG_URI_GRANTS = "uri-grants";
846    private static final String TAG_URI_GRANT = "uri-grant";
847    private static final String ATTR_USER_HANDLE = "userHandle";
848    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
849    private static final String ATTR_TARGET_USER_ID = "targetUserId";
850    private static final String ATTR_SOURCE_PKG = "sourcePkg";
851    private static final String ATTR_TARGET_PKG = "targetPkg";
852    private static final String ATTR_URI = "uri";
853    private static final String ATTR_MODE_FLAGS = "modeFlags";
854    private static final String ATTR_CREATED_TIME = "createdTime";
855    private static final String ATTR_PREFIX = "prefix";
856
857    /**
858     * Global set of specific {@link Uri} permissions that have been granted.
859     * This optimized lookup structure maps from {@link UriPermission#targetUid}
860     * to {@link UriPermission#uri} to {@link UriPermission}.
861     */
862    @GuardedBy("this")
863    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
864            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
865
866    public static class GrantUri {
867        public final int sourceUserId;
868        public final Uri uri;
869        public boolean prefix;
870
871        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
872            this.sourceUserId = sourceUserId;
873            this.uri = uri;
874            this.prefix = prefix;
875        }
876
877        @Override
878        public int hashCode() {
879            int hashCode = 1;
880            hashCode = 31 * hashCode + sourceUserId;
881            hashCode = 31 * hashCode + uri.hashCode();
882            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
883            return hashCode;
884        }
885
886        @Override
887        public boolean equals(Object o) {
888            if (o instanceof GrantUri) {
889                GrantUri other = (GrantUri) o;
890                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
891                        && prefix == other.prefix;
892            }
893            return false;
894        }
895
896        @Override
897        public String toString() {
898            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
899            if (prefix) result += " [prefix]";
900            return result;
901        }
902
903        public String toSafeString() {
904            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
905            if (prefix) result += " [prefix]";
906            return result;
907        }
908
909        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
910            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
911                    ContentProvider.getUriWithoutUserId(uri), false);
912        }
913    }
914
915    CoreSettingsObserver mCoreSettingsObserver;
916
917    /**
918     * Thread-local storage used to carry caller permissions over through
919     * indirect content-provider access.
920     */
921    private class Identity {
922        public final IBinder token;
923        public final int pid;
924        public final int uid;
925
926        Identity(IBinder _token, int _pid, int _uid) {
927            token = _token;
928            pid = _pid;
929            uid = _uid;
930        }
931    }
932
933    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
934
935    /**
936     * All information we have collected about the runtime performance of
937     * any user id that can impact battery performance.
938     */
939    final BatteryStatsService mBatteryStatsService;
940
941    /**
942     * Information about component usage
943     */
944    UsageStatsManagerInternal mUsageStatsService;
945
946    /**
947     * Access to DeviceIdleController service.
948     */
949    DeviceIdleController.LocalService mLocalDeviceIdleController;
950
951    /**
952     * Information about and control over application operations
953     */
954    final AppOpsService mAppOpsService;
955
956    /**
957     * Save recent tasks information across reboots.
958     */
959    final TaskPersister mTaskPersister;
960
961    /**
962     * Current configuration information.  HistoryRecord objects are given
963     * a reference to this object to indicate which configuration they are
964     * currently running in, so this object must be kept immutable.
965     */
966    Configuration mConfiguration = new Configuration();
967
968    /**
969     * Current sequencing integer of the configuration, for skipping old
970     * configurations.
971     */
972    int mConfigurationSeq = 0;
973
974    boolean mSuppressResizeConfigChanges = false;
975
976    /**
977     * Hardware-reported OpenGLES version.
978     */
979    final int GL_ES_VERSION;
980
981    /**
982     * List of initialization arguments to pass to all processes when binding applications to them.
983     * For example, references to the commonly used services.
984     */
985    HashMap<String, IBinder> mAppBindArgs;
986
987    /**
988     * Temporary to avoid allocations.  Protected by main lock.
989     */
990    final StringBuilder mStringBuilder = new StringBuilder(256);
991
992    /**
993     * Used to control how we initialize the service.
994     */
995    ComponentName mTopComponent;
996    String mTopAction = Intent.ACTION_MAIN;
997    String mTopData;
998    boolean mProcessesReady = false;
999    boolean mSystemReady = false;
1000    boolean mBooting = false;
1001    boolean mCallFinishBooting = false;
1002    boolean mBootAnimationComplete = false;
1003    boolean mWaitingUpdate = false;
1004    boolean mDidUpdate = false;
1005    boolean mOnBattery = false;
1006    boolean mLaunchWarningShown = false;
1007
1008    Context mContext;
1009
1010    int mFactoryTest;
1011
1012    boolean mCheckedForSetup;
1013
1014    /**
1015     * The time at which we will allow normal application switches again,
1016     * after a call to {@link #stopAppSwitches()}.
1017     */
1018    long mAppSwitchesAllowedTime;
1019
1020    /**
1021     * This is set to true after the first switch after mAppSwitchesAllowedTime
1022     * is set; any switches after that will clear the time.
1023     */
1024    boolean mDidAppSwitch;
1025
1026    /**
1027     * Last time (in realtime) at which we checked for power usage.
1028     */
1029    long mLastPowerCheckRealtime;
1030
1031    /**
1032     * Last time (in uptime) at which we checked for power usage.
1033     */
1034    long mLastPowerCheckUptime;
1035
1036    /**
1037     * Set while we are wanting to sleep, to prevent any
1038     * activities from being started/resumed.
1039     */
1040    private boolean mSleeping = false;
1041
1042    /**
1043     * The process state used for processes that are running the top activities.
1044     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1045     */
1046    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1047
1048    /**
1049     * Set while we are running a voice interaction.  This overrides
1050     * sleeping while it is active.
1051     */
1052    private IVoiceInteractionSession mRunningVoice;
1053
1054    /**
1055     * For some direct access we need to power manager.
1056     */
1057    PowerManagerInternal mLocalPowerManager;
1058
1059    /**
1060     * We want to hold a wake lock while running a voice interaction session, since
1061     * this may happen with the screen off and we need to keep the CPU running to
1062     * be able to continue to interact with the user.
1063     */
1064    PowerManager.WakeLock mVoiceWakeLock;
1065
1066    /**
1067     * State of external calls telling us if the device is awake or asleep.
1068     */
1069    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1070
1071    /**
1072     * A list of tokens that cause the top activity to be put to sleep.
1073     * They are used by components that may hide and block interaction with underlying
1074     * activities.
1075     */
1076    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1077
1078    static final int LOCK_SCREEN_HIDDEN = 0;
1079    static final int LOCK_SCREEN_LEAVING = 1;
1080    static final int LOCK_SCREEN_SHOWN = 2;
1081    /**
1082     * State of external call telling us if the lock screen is shown.
1083     */
1084    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1085
1086    /**
1087     * Set if we are shutting down the system, similar to sleeping.
1088     */
1089    boolean mShuttingDown = false;
1090
1091    /**
1092     * Current sequence id for oom_adj computation traversal.
1093     */
1094    int mAdjSeq = 0;
1095
1096    /**
1097     * Current sequence id for process LRU updating.
1098     */
1099    int mLruSeq = 0;
1100
1101    /**
1102     * Keep track of the non-cached/empty process we last found, to help
1103     * determine how to distribute cached/empty processes next time.
1104     */
1105    int mNumNonCachedProcs = 0;
1106
1107    /**
1108     * Keep track of the number of cached hidden procs, to balance oom adj
1109     * distribution between those and empty procs.
1110     */
1111    int mNumCachedHiddenProcs = 0;
1112
1113    /**
1114     * Keep track of the number of service processes we last found, to
1115     * determine on the next iteration which should be B services.
1116     */
1117    int mNumServiceProcs = 0;
1118    int mNewNumAServiceProcs = 0;
1119    int mNewNumServiceProcs = 0;
1120
1121    /**
1122     * Allow the current computed overall memory level of the system to go down?
1123     * This is set to false when we are killing processes for reasons other than
1124     * memory management, so that the now smaller process list will not be taken as
1125     * an indication that memory is tighter.
1126     */
1127    boolean mAllowLowerMemLevel = false;
1128
1129    /**
1130     * The last computed memory level, for holding when we are in a state that
1131     * processes are going away for other reasons.
1132     */
1133    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1134
1135    /**
1136     * The last total number of process we have, to determine if changes actually look
1137     * like a shrinking number of process due to lower RAM.
1138     */
1139    int mLastNumProcesses;
1140
1141    /**
1142     * The uptime of the last time we performed idle maintenance.
1143     */
1144    long mLastIdleTime = SystemClock.uptimeMillis();
1145
1146    /**
1147     * Total time spent with RAM that has been added in the past since the last idle time.
1148     */
1149    long mLowRamTimeSinceLastIdle = 0;
1150
1151    /**
1152     * If RAM is currently low, when that horrible situation started.
1153     */
1154    long mLowRamStartTime = 0;
1155
1156    /**
1157     * For reporting to battery stats the current top application.
1158     */
1159    private String mCurResumedPackage = null;
1160    private int mCurResumedUid = -1;
1161
1162    /**
1163     * For reporting to battery stats the apps currently running foreground
1164     * service.  The ProcessMap is package/uid tuples; each of these contain
1165     * an array of the currently foreground processes.
1166     */
1167    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1168            = new ProcessMap<ArrayList<ProcessRecord>>();
1169
1170    /**
1171     * This is set if we had to do a delayed dexopt of an app before launching
1172     * it, to increase the ANR timeouts in that case.
1173     */
1174    boolean mDidDexOpt;
1175
1176    /**
1177     * Set if the systemServer made a call to enterSafeMode.
1178     */
1179    boolean mSafeMode;
1180
1181    /**
1182     * If true, we are running under a test environment so will sample PSS from processes
1183     * much more rapidly to try to collect better data when the tests are rapidly
1184     * running through apps.
1185     */
1186    boolean mTestPssMode = false;
1187
1188    String mDebugApp = null;
1189    boolean mWaitForDebugger = false;
1190    boolean mDebugTransient = false;
1191    String mOrigDebugApp = null;
1192    boolean mOrigWaitForDebugger = false;
1193    boolean mAlwaysFinishActivities = false;
1194    boolean mForceResizableActivites;
1195    IActivityController mController = null;
1196    String mProfileApp = null;
1197    ProcessRecord mProfileProc = null;
1198    String mProfileFile;
1199    ParcelFileDescriptor mProfileFd;
1200    int mSamplingInterval = 0;
1201    boolean mAutoStopProfiler = false;
1202    int mProfileType = 0;
1203    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1204    String mMemWatchDumpProcName;
1205    String mMemWatchDumpFile;
1206    int mMemWatchDumpPid;
1207    int mMemWatchDumpUid;
1208    String mTrackAllocationApp = null;
1209
1210    final long[] mTmpLong = new long[1];
1211
1212    static final class ProcessChangeItem {
1213        static final int CHANGE_ACTIVITIES = 1<<0;
1214        static final int CHANGE_PROCESS_STATE = 1<<1;
1215        int changes;
1216        int uid;
1217        int pid;
1218        int processState;
1219        boolean foregroundActivities;
1220    }
1221
1222    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1223    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1224
1225    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1226    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1227
1228    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1229    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1230
1231    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1232    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1233
1234    ArraySet<String> mAppsNotReportingCrashes;
1235
1236    /**
1237     * Runtime CPU use collection thread.  This object's lock is used to
1238     * perform synchronization with the thread (notifying it to run).
1239     */
1240    final Thread mProcessCpuThread;
1241
1242    /**
1243     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1244     * Must acquire this object's lock when accessing it.
1245     * NOTE: this lock will be held while doing long operations (trawling
1246     * through all processes in /proc), so it should never be acquired by
1247     * any critical paths such as when holding the main activity manager lock.
1248     */
1249    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1250            MONITOR_THREAD_CPU_USAGE);
1251    final AtomicLong mLastCpuTime = new AtomicLong(0);
1252    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1253
1254    long mLastWriteTime = 0;
1255
1256    /**
1257     * Used to retain an update lock when the foreground activity is in
1258     * immersive mode.
1259     */
1260    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1261
1262    /**
1263     * Set to true after the system has finished booting.
1264     */
1265    boolean mBooted = false;
1266
1267    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1268    int mProcessLimitOverride = -1;
1269
1270    WindowManagerService mWindowManager;
1271
1272    final ActivityThread mSystemThread;
1273
1274    private UserManagerService mUserManager;
1275
1276    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1277        final ProcessRecord mApp;
1278        final int mPid;
1279        final IApplicationThread mAppThread;
1280
1281        AppDeathRecipient(ProcessRecord app, int pid,
1282                IApplicationThread thread) {
1283            if (DEBUG_ALL) Slog.v(
1284                TAG, "New death recipient " + this
1285                + " for thread " + thread.asBinder());
1286            mApp = app;
1287            mPid = pid;
1288            mAppThread = thread;
1289        }
1290
1291        @Override
1292        public void binderDied() {
1293            if (DEBUG_ALL) Slog.v(
1294                TAG, "Death received in " + this
1295                + " for thread " + mAppThread.asBinder());
1296            synchronized(ActivityManagerService.this) {
1297                appDiedLocked(mApp, mPid, mAppThread, true);
1298            }
1299        }
1300    }
1301
1302    static final int SHOW_ERROR_MSG = 1;
1303    static final int SHOW_NOT_RESPONDING_MSG = 2;
1304    static final int SHOW_FACTORY_ERROR_MSG = 3;
1305    static final int UPDATE_CONFIGURATION_MSG = 4;
1306    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1307    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1308    static final int SERVICE_TIMEOUT_MSG = 12;
1309    static final int UPDATE_TIME_ZONE = 13;
1310    static final int SHOW_UID_ERROR_MSG = 14;
1311    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1312    static final int PROC_START_TIMEOUT_MSG = 20;
1313    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1314    static final int KILL_APPLICATION_MSG = 22;
1315    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1316    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1317    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1318    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1319    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1320    static final int CLEAR_DNS_CACHE_MSG = 28;
1321    static final int UPDATE_HTTP_PROXY_MSG = 29;
1322    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1323    static final int DISPATCH_PROCESSES_CHANGED = 31;
1324    static final int DISPATCH_PROCESS_DIED = 32;
1325    static final int REPORT_MEM_USAGE_MSG = 33;
1326    static final int REPORT_USER_SWITCH_MSG = 34;
1327    static final int CONTINUE_USER_SWITCH_MSG = 35;
1328    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1329    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1330    static final int PERSIST_URI_GRANTS_MSG = 38;
1331    static final int REQUEST_ALL_PSS_MSG = 39;
1332    static final int START_PROFILES_MSG = 40;
1333    static final int UPDATE_TIME = 41;
1334    static final int SYSTEM_USER_START_MSG = 42;
1335    static final int SYSTEM_USER_CURRENT_MSG = 43;
1336    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1337    static final int FINISH_BOOTING_MSG = 45;
1338    static final int START_USER_SWITCH_MSG = 46;
1339    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1340    static final int DISMISS_DIALOG_MSG = 48;
1341    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1342    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1343    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1344    static final int DELETE_DUMPHEAP_MSG = 52;
1345    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1346    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1347    static final int REPORT_TIME_TRACKER_MSG = 55;
1348    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1349    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1350    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1351    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1352
1353    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1354    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1355    static final int FIRST_COMPAT_MODE_MSG = 300;
1356    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1357
1358    CompatModeDialog mCompatModeDialog;
1359    long mLastMemUsageReportTime = 0;
1360
1361    /**
1362     * Flag whether the current user is a "monkey", i.e. whether
1363     * the UI is driven by a UI automation tool.
1364     */
1365    private boolean mUserIsMonkey;
1366
1367    /** Flag whether the device has a Recents UI */
1368    boolean mHasRecents;
1369
1370    /** The dimensions of the thumbnails in the Recents UI. */
1371    int mThumbnailWidth;
1372    int mThumbnailHeight;
1373
1374    final ServiceThread mHandlerThread;
1375    final MainHandler mHandler;
1376    final UiHandler mUiHandler;
1377
1378    final class UiHandler extends Handler {
1379        public UiHandler() {
1380            super(com.android.server.UiThread.get().getLooper(), null, true);
1381        }
1382
1383        @Override
1384        public void handleMessage(Message msg) {
1385            switch (msg.what) {
1386            case SHOW_ERROR_MSG: {
1387                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1388                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1389                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1390                synchronized (ActivityManagerService.this) {
1391                    ProcessRecord proc = (ProcessRecord)data.get("app");
1392                    AppErrorResult res = (AppErrorResult) data.get("result");
1393                    if (proc != null && proc.crashDialog != null) {
1394                        Slog.e(TAG, "App already has crash dialog: " + proc);
1395                        if (res != null) {
1396                            res.set(0);
1397                        }
1398                        return;
1399                    }
1400                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1401                            >= Process.FIRST_APPLICATION_UID
1402                            && proc.pid != MY_PID);
1403                    for (int userId : mUserController.mCurrentProfileIds) {
1404                        isBackground &= (proc.userId != userId);
1405                    }
1406                    if (isBackground && !showBackground) {
1407                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1408                        if (res != null) {
1409                            res.set(0);
1410                        }
1411                        return;
1412                    }
1413                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1414                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1415                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1416                        Dialog d = new AppErrorDialog(mContext,
1417                                ActivityManagerService.this, res, proc);
1418                        d.show();
1419                        proc.crashDialog = d;
1420                    } else {
1421                        // The device is asleep, so just pretend that the user
1422                        // saw a crash dialog and hit "force quit".
1423                        if (res != null) {
1424                            res.set(0);
1425                        }
1426                    }
1427                }
1428
1429                ensureBootCompleted();
1430            } break;
1431            case SHOW_NOT_RESPONDING_MSG: {
1432                synchronized (ActivityManagerService.this) {
1433                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1434                    ProcessRecord proc = (ProcessRecord)data.get("app");
1435                    if (proc != null && proc.anrDialog != null) {
1436                        Slog.e(TAG, "App already has anr dialog: " + proc);
1437                        return;
1438                    }
1439
1440                    Intent intent = new Intent("android.intent.action.ANR");
1441                    if (!mProcessesReady) {
1442                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1443                                | Intent.FLAG_RECEIVER_FOREGROUND);
1444                    }
1445                    broadcastIntentLocked(null, null, intent,
1446                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1447                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1448
1449                    if (mShowDialogs) {
1450                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1451                                mContext, proc, (ActivityRecord)data.get("activity"),
1452                                msg.arg1 != 0);
1453                        d.show();
1454                        proc.anrDialog = d;
1455                    } else {
1456                        // Just kill the app if there is no dialog to be shown.
1457                        killAppAtUsersRequest(proc, null);
1458                    }
1459                }
1460
1461                ensureBootCompleted();
1462            } break;
1463            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1464                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1465                synchronized (ActivityManagerService.this) {
1466                    ProcessRecord proc = (ProcessRecord) data.get("app");
1467                    if (proc == null) {
1468                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1469                        break;
1470                    }
1471                    if (proc.crashDialog != null) {
1472                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1473                        return;
1474                    }
1475                    AppErrorResult res = (AppErrorResult) data.get("result");
1476                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1477                        Dialog d = new StrictModeViolationDialog(mContext,
1478                                ActivityManagerService.this, res, proc);
1479                        d.show();
1480                        proc.crashDialog = d;
1481                    } else {
1482                        // The device is asleep, so just pretend that the user
1483                        // saw a crash dialog and hit "force quit".
1484                        res.set(0);
1485                    }
1486                }
1487                ensureBootCompleted();
1488            } break;
1489            case SHOW_FACTORY_ERROR_MSG: {
1490                Dialog d = new FactoryErrorDialog(
1491                    mContext, msg.getData().getCharSequence("msg"));
1492                d.show();
1493                ensureBootCompleted();
1494            } break;
1495            case WAIT_FOR_DEBUGGER_MSG: {
1496                synchronized (ActivityManagerService.this) {
1497                    ProcessRecord app = (ProcessRecord)msg.obj;
1498                    if (msg.arg1 != 0) {
1499                        if (!app.waitedForDebugger) {
1500                            Dialog d = new AppWaitingForDebuggerDialog(
1501                                    ActivityManagerService.this,
1502                                    mContext, app);
1503                            app.waitDialog = d;
1504                            app.waitedForDebugger = true;
1505                            d.show();
1506                        }
1507                    } else {
1508                        if (app.waitDialog != null) {
1509                            app.waitDialog.dismiss();
1510                            app.waitDialog = null;
1511                        }
1512                    }
1513                }
1514            } break;
1515            case SHOW_UID_ERROR_MSG: {
1516                if (mShowDialogs) {
1517                    AlertDialog d = new BaseErrorDialog(mContext);
1518                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1519                    d.setCancelable(false);
1520                    d.setTitle(mContext.getText(R.string.android_system_label));
1521                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1522                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1523                            obtainMessage(DISMISS_DIALOG_MSG, d));
1524                    d.show();
1525                }
1526            } break;
1527            case SHOW_FINGERPRINT_ERROR_MSG: {
1528                if (mShowDialogs) {
1529                    AlertDialog d = new BaseErrorDialog(mContext);
1530                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1531                    d.setCancelable(false);
1532                    d.setTitle(mContext.getText(R.string.android_system_label));
1533                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1534                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1535                            obtainMessage(DISMISS_DIALOG_MSG, d));
1536                    d.show();
1537                }
1538            } break;
1539            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1540                synchronized (ActivityManagerService.this) {
1541                    ActivityRecord ar = (ActivityRecord) msg.obj;
1542                    if (mCompatModeDialog != null) {
1543                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1544                                ar.info.applicationInfo.packageName)) {
1545                            return;
1546                        }
1547                        mCompatModeDialog.dismiss();
1548                        mCompatModeDialog = null;
1549                    }
1550                    if (ar != null && false) {
1551                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1552                                ar.packageName)) {
1553                            int mode = mCompatModePackages.computeCompatModeLocked(
1554                                    ar.info.applicationInfo);
1555                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1556                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1557                                mCompatModeDialog = new CompatModeDialog(
1558                                        ActivityManagerService.this, mContext,
1559                                        ar.info.applicationInfo);
1560                                mCompatModeDialog.show();
1561                            }
1562                        }
1563                    }
1564                }
1565                break;
1566            }
1567            case START_USER_SWITCH_MSG: {
1568                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1569                break;
1570            }
1571            case DISMISS_DIALOG_MSG: {
1572                final Dialog d = (Dialog) msg.obj;
1573                d.dismiss();
1574                break;
1575            }
1576            case DISPATCH_PROCESSES_CHANGED: {
1577                dispatchProcessesChanged();
1578                break;
1579            }
1580            case DISPATCH_PROCESS_DIED: {
1581                final int pid = msg.arg1;
1582                final int uid = msg.arg2;
1583                dispatchProcessDied(pid, uid);
1584                break;
1585            }
1586            case DISPATCH_UIDS_CHANGED_MSG: {
1587                dispatchUidsChanged();
1588            } break;
1589            }
1590        }
1591    }
1592
1593    final class MainHandler extends Handler {
1594        public MainHandler(Looper looper) {
1595            super(looper, null, true);
1596        }
1597
1598        @Override
1599        public void handleMessage(Message msg) {
1600            switch (msg.what) {
1601            case UPDATE_CONFIGURATION_MSG: {
1602                final ContentResolver resolver = mContext.getContentResolver();
1603                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1604                        msg.arg1);
1605            } break;
1606            case GC_BACKGROUND_PROCESSES_MSG: {
1607                synchronized (ActivityManagerService.this) {
1608                    performAppGcsIfAppropriateLocked();
1609                }
1610            } break;
1611            case SERVICE_TIMEOUT_MSG: {
1612                if (mDidDexOpt) {
1613                    mDidDexOpt = false;
1614                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1615                    nmsg.obj = msg.obj;
1616                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1617                    return;
1618                }
1619                mServices.serviceTimeout((ProcessRecord)msg.obj);
1620            } break;
1621            case UPDATE_TIME_ZONE: {
1622                synchronized (ActivityManagerService.this) {
1623                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1624                        ProcessRecord r = mLruProcesses.get(i);
1625                        if (r.thread != null) {
1626                            try {
1627                                r.thread.updateTimeZone();
1628                            } catch (RemoteException ex) {
1629                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1630                            }
1631                        }
1632                    }
1633                }
1634            } break;
1635            case CLEAR_DNS_CACHE_MSG: {
1636                synchronized (ActivityManagerService.this) {
1637                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1638                        ProcessRecord r = mLruProcesses.get(i);
1639                        if (r.thread != null) {
1640                            try {
1641                                r.thread.clearDnsCache();
1642                            } catch (RemoteException ex) {
1643                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1644                            }
1645                        }
1646                    }
1647                }
1648            } break;
1649            case UPDATE_HTTP_PROXY_MSG: {
1650                ProxyInfo proxy = (ProxyInfo)msg.obj;
1651                String host = "";
1652                String port = "";
1653                String exclList = "";
1654                Uri pacFileUrl = Uri.EMPTY;
1655                if (proxy != null) {
1656                    host = proxy.getHost();
1657                    port = Integer.toString(proxy.getPort());
1658                    exclList = proxy.getExclusionListAsString();
1659                    pacFileUrl = proxy.getPacFileUrl();
1660                }
1661                synchronized (ActivityManagerService.this) {
1662                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1663                        ProcessRecord r = mLruProcesses.get(i);
1664                        if (r.thread != null) {
1665                            try {
1666                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1667                            } catch (RemoteException ex) {
1668                                Slog.w(TAG, "Failed to update http proxy for: " +
1669                                        r.info.processName);
1670                            }
1671                        }
1672                    }
1673                }
1674            } break;
1675            case PROC_START_TIMEOUT_MSG: {
1676                if (mDidDexOpt) {
1677                    mDidDexOpt = false;
1678                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1679                    nmsg.obj = msg.obj;
1680                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1681                    return;
1682                }
1683                ProcessRecord app = (ProcessRecord)msg.obj;
1684                synchronized (ActivityManagerService.this) {
1685                    processStartTimedOutLocked(app);
1686                }
1687            } break;
1688            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1689                ProcessRecord app = (ProcessRecord)msg.obj;
1690                synchronized (ActivityManagerService.this) {
1691                    processContentProviderPublishTimedOutLocked(app);
1692                }
1693            } break;
1694            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1695                synchronized (ActivityManagerService.this) {
1696                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1697                }
1698            } break;
1699            case KILL_APPLICATION_MSG: {
1700                synchronized (ActivityManagerService.this) {
1701                    int appid = msg.arg1;
1702                    boolean restart = (msg.arg2 == 1);
1703                    Bundle bundle = (Bundle)msg.obj;
1704                    String pkg = bundle.getString("pkg");
1705                    String reason = bundle.getString("reason");
1706                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1707                            false, UserHandle.USER_ALL, reason);
1708                }
1709            } break;
1710            case FINALIZE_PENDING_INTENT_MSG: {
1711                ((PendingIntentRecord)msg.obj).completeFinalize();
1712            } break;
1713            case POST_HEAVY_NOTIFICATION_MSG: {
1714                INotificationManager inm = NotificationManager.getService();
1715                if (inm == null) {
1716                    return;
1717                }
1718
1719                ActivityRecord root = (ActivityRecord)msg.obj;
1720                ProcessRecord process = root.app;
1721                if (process == null) {
1722                    return;
1723                }
1724
1725                try {
1726                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1727                    String text = mContext.getString(R.string.heavy_weight_notification,
1728                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1729                    Notification notification = new Notification.Builder(context)
1730                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1731                            .setWhen(0)
1732                            .setOngoing(true)
1733                            .setTicker(text)
1734                            .setColor(mContext.getColor(
1735                                    com.android.internal.R.color.system_notification_accent_color))
1736                            .setContentTitle(text)
1737                            .setContentText(
1738                                    mContext.getText(R.string.heavy_weight_notification_detail))
1739                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1740                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1741                                    new UserHandle(root.userId)))
1742                            .build();
1743                    try {
1744                        int[] outId = new int[1];
1745                        inm.enqueueNotificationWithTag("android", "android", null,
1746                                R.string.heavy_weight_notification,
1747                                notification, outId, root.userId);
1748                    } catch (RuntimeException e) {
1749                        Slog.w(ActivityManagerService.TAG,
1750                                "Error showing notification for heavy-weight app", e);
1751                    } catch (RemoteException e) {
1752                    }
1753                } catch (NameNotFoundException e) {
1754                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1755                }
1756            } break;
1757            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1758                INotificationManager inm = NotificationManager.getService();
1759                if (inm == null) {
1760                    return;
1761                }
1762                try {
1763                    inm.cancelNotificationWithTag("android", null,
1764                            R.string.heavy_weight_notification,  msg.arg1);
1765                } catch (RuntimeException e) {
1766                    Slog.w(ActivityManagerService.TAG,
1767                            "Error canceling notification for service", e);
1768                } catch (RemoteException e) {
1769                }
1770            } break;
1771            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1772                synchronized (ActivityManagerService.this) {
1773                    checkExcessivePowerUsageLocked(true);
1774                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1775                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1776                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1777                }
1778            } break;
1779            case REPORT_MEM_USAGE_MSG: {
1780                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1781                Thread thread = new Thread() {
1782                    @Override public void run() {
1783                        reportMemUsage(memInfos);
1784                    }
1785                };
1786                thread.start();
1787                break;
1788            }
1789            case REPORT_USER_SWITCH_MSG: {
1790                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1791                break;
1792            }
1793            case CONTINUE_USER_SWITCH_MSG: {
1794                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1795                break;
1796            }
1797            case USER_SWITCH_TIMEOUT_MSG: {
1798                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1799                break;
1800            }
1801            case IMMERSIVE_MODE_LOCK_MSG: {
1802                final boolean nextState = (msg.arg1 != 0);
1803                if (mUpdateLock.isHeld() != nextState) {
1804                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1805                            "Applying new update lock state '" + nextState
1806                            + "' for " + (ActivityRecord)msg.obj);
1807                    if (nextState) {
1808                        mUpdateLock.acquire();
1809                    } else {
1810                        mUpdateLock.release();
1811                    }
1812                }
1813                break;
1814            }
1815            case PERSIST_URI_GRANTS_MSG: {
1816                writeGrantedUriPermissions();
1817                break;
1818            }
1819            case REQUEST_ALL_PSS_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1822                }
1823                break;
1824            }
1825            case START_PROFILES_MSG: {
1826                synchronized (ActivityManagerService.this) {
1827                    mUserController.startProfilesLocked();
1828                }
1829                break;
1830            }
1831            case UPDATE_TIME: {
1832                synchronized (ActivityManagerService.this) {
1833                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1834                        ProcessRecord r = mLruProcesses.get(i);
1835                        if (r.thread != null) {
1836                            try {
1837                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1838                            } catch (RemoteException ex) {
1839                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1840                            }
1841                        }
1842                    }
1843                }
1844                break;
1845            }
1846            case SYSTEM_USER_START_MSG: {
1847                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1848                        Integer.toString(msg.arg1), msg.arg1);
1849                mSystemServiceManager.startUser(msg.arg1);
1850                break;
1851            }
1852            case SYSTEM_USER_CURRENT_MSG: {
1853                mBatteryStatsService.noteEvent(
1854                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1855                        Integer.toString(msg.arg2), msg.arg2);
1856                mBatteryStatsService.noteEvent(
1857                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1858                        Integer.toString(msg.arg1), msg.arg1);
1859                mSystemServiceManager.switchUser(msg.arg1);
1860                break;
1861            }
1862            case ENTER_ANIMATION_COMPLETE_MSG: {
1863                synchronized (ActivityManagerService.this) {
1864                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1865                    if (r != null && r.app != null && r.app.thread != null) {
1866                        try {
1867                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1868                        } catch (RemoteException e) {
1869                        }
1870                    }
1871                }
1872                break;
1873            }
1874            case FINISH_BOOTING_MSG: {
1875                if (msg.arg1 != 0) {
1876                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1877                    finishBooting();
1878                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1879                }
1880                if (msg.arg2 != 0) {
1881                    enableScreenAfterBoot();
1882                }
1883                break;
1884            }
1885            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1886                try {
1887                    Locale l = (Locale) msg.obj;
1888                    IBinder service = ServiceManager.getService("mount");
1889                    IMountService mountService = IMountService.Stub.asInterface(service);
1890                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1891                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1892                } catch (RemoteException e) {
1893                    Log.e(TAG, "Error storing locale for decryption UI", e);
1894                }
1895                break;
1896            }
1897            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1898                synchronized (ActivityManagerService.this) {
1899                    int i = mTaskStackListeners.beginBroadcast();
1900                    while (i > 0) {
1901                        i--;
1902                        try {
1903                            // Make a one-way callback to the listener
1904                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1905                        } catch (RemoteException e){
1906                            // Handled by the RemoteCallbackList
1907                        }
1908                    }
1909                    mTaskStackListeners.finishBroadcast();
1910                }
1911                break;
1912            }
1913            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1914                final int uid = msg.arg1;
1915                final byte[] firstPacket = (byte[]) msg.obj;
1916
1917                synchronized (mPidsSelfLocked) {
1918                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1919                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1920                        if (p.uid == uid) {
1921                            try {
1922                                p.thread.notifyCleartextNetwork(firstPacket);
1923                            } catch (RemoteException ignored) {
1924                            }
1925                        }
1926                    }
1927                }
1928                break;
1929            }
1930            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1931                final String procName;
1932                final int uid;
1933                final long memLimit;
1934                final String reportPackage;
1935                synchronized (ActivityManagerService.this) {
1936                    procName = mMemWatchDumpProcName;
1937                    uid = mMemWatchDumpUid;
1938                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1939                    if (val == null) {
1940                        val = mMemWatchProcesses.get(procName, 0);
1941                    }
1942                    if (val != null) {
1943                        memLimit = val.first;
1944                        reportPackage = val.second;
1945                    } else {
1946                        memLimit = 0;
1947                        reportPackage = null;
1948                    }
1949                }
1950                if (procName == null) {
1951                    return;
1952                }
1953
1954                if (DEBUG_PSS) Slog.d(TAG_PSS,
1955                        "Showing dump heap notification from " + procName + "/" + uid);
1956
1957                INotificationManager inm = NotificationManager.getService();
1958                if (inm == null) {
1959                    return;
1960                }
1961
1962                String text = mContext.getString(R.string.dump_heap_notification, procName);
1963
1964
1965                Intent deleteIntent = new Intent();
1966                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1967                Intent intent = new Intent();
1968                intent.setClassName("android", DumpHeapActivity.class.getName());
1969                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1970                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1971                if (reportPackage != null) {
1972                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1973                }
1974                int userId = UserHandle.getUserId(uid);
1975                Notification notification = new Notification.Builder(mContext)
1976                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1977                        .setWhen(0)
1978                        .setOngoing(true)
1979                        .setAutoCancel(true)
1980                        .setTicker(text)
1981                        .setColor(mContext.getColor(
1982                                com.android.internal.R.color.system_notification_accent_color))
1983                        .setContentTitle(text)
1984                        .setContentText(
1985                                mContext.getText(R.string.dump_heap_notification_detail))
1986                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1987                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1988                                new UserHandle(userId)))
1989                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1990                                deleteIntent, 0, UserHandle.SYSTEM))
1991                        .build();
1992
1993                try {
1994                    int[] outId = new int[1];
1995                    inm.enqueueNotificationWithTag("android", "android", null,
1996                            R.string.dump_heap_notification,
1997                            notification, outId, userId);
1998                } catch (RuntimeException e) {
1999                    Slog.w(ActivityManagerService.TAG,
2000                            "Error showing notification for dump heap", e);
2001                } catch (RemoteException e) {
2002                }
2003            } break;
2004            case DELETE_DUMPHEAP_MSG: {
2005                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2006                        DumpHeapActivity.JAVA_URI,
2007                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2008                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2009                        UserHandle.myUserId());
2010                synchronized (ActivityManagerService.this) {
2011                    mMemWatchDumpFile = null;
2012                    mMemWatchDumpProcName = null;
2013                    mMemWatchDumpPid = -1;
2014                    mMemWatchDumpUid = -1;
2015                }
2016            } break;
2017            case FOREGROUND_PROFILE_CHANGED_MSG: {
2018                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2019            } break;
2020            case REPORT_TIME_TRACKER_MSG: {
2021                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2022                tracker.deliverResult(mContext);
2023            } break;
2024            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2025                mUserController.dispatchUserSwitchComplete(msg.arg1);
2026            } break;
2027            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2028                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2029                try {
2030                    connection.shutdown();
2031                } catch (RemoteException e) {
2032                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2033                }
2034                // Only a UiAutomation can set this flag and now that
2035                // it is finished we make sure it is reset to its default.
2036                mUserIsMonkey = false;
2037            } break;
2038            case APP_BOOST_DEACTIVATE_MSG : {
2039                synchronized(ActivityManagerService.this) {
2040                    if (mIsBoosted) {
2041                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2042                            nativeMigrateFromBoost();
2043                            mIsBoosted = false;
2044                            mBoostStartTime = 0;
2045                        } else {
2046                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2047                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2048                        }
2049                    }
2050                }
2051            } break;
2052            }
2053        }
2054    };
2055
2056    static final int COLLECT_PSS_BG_MSG = 1;
2057
2058    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2059        @Override
2060        public void handleMessage(Message msg) {
2061            switch (msg.what) {
2062            case COLLECT_PSS_BG_MSG: {
2063                long start = SystemClock.uptimeMillis();
2064                MemInfoReader memInfo = null;
2065                synchronized (ActivityManagerService.this) {
2066                    if (mFullPssPending) {
2067                        mFullPssPending = false;
2068                        memInfo = new MemInfoReader();
2069                    }
2070                }
2071                if (memInfo != null) {
2072                    updateCpuStatsNow();
2073                    long nativeTotalPss = 0;
2074                    synchronized (mProcessCpuTracker) {
2075                        final int N = mProcessCpuTracker.countStats();
2076                        for (int j=0; j<N; j++) {
2077                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2078                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2079                                // This is definitely an application process; skip it.
2080                                continue;
2081                            }
2082                            synchronized (mPidsSelfLocked) {
2083                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2084                                    // This is one of our own processes; skip it.
2085                                    continue;
2086                                }
2087                            }
2088                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2089                        }
2090                    }
2091                    memInfo.readMemInfo();
2092                    synchronized (ActivityManagerService.this) {
2093                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2094                                + (SystemClock.uptimeMillis()-start) + "ms");
2095                        final long cachedKb = memInfo.getCachedSizeKb();
2096                        final long freeKb = memInfo.getFreeSizeKb();
2097                        final long zramKb = memInfo.getZramTotalSizeKb();
2098                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2099                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2100                                kernelKb*1024, nativeTotalPss*1024);
2101                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2102                                nativeTotalPss);
2103                    }
2104                }
2105
2106                int num = 0;
2107                long[] tmp = new long[1];
2108                do {
2109                    ProcessRecord proc;
2110                    int procState;
2111                    int pid;
2112                    long lastPssTime;
2113                    synchronized (ActivityManagerService.this) {
2114                        if (mPendingPssProcesses.size() <= 0) {
2115                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2116                                    "Collected PSS of " + num + " processes in "
2117                                    + (SystemClock.uptimeMillis() - start) + "ms");
2118                            mPendingPssProcesses.clear();
2119                            return;
2120                        }
2121                        proc = mPendingPssProcesses.remove(0);
2122                        procState = proc.pssProcState;
2123                        lastPssTime = proc.lastPssTime;
2124                        if (proc.thread != null && procState == proc.setProcState
2125                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2126                                        < SystemClock.uptimeMillis()) {
2127                            pid = proc.pid;
2128                        } else {
2129                            proc = null;
2130                            pid = 0;
2131                        }
2132                    }
2133                    if (proc != null) {
2134                        long pss = Debug.getPss(pid, tmp, null);
2135                        synchronized (ActivityManagerService.this) {
2136                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2137                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2138                                num++;
2139                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2140                                        SystemClock.uptimeMillis());
2141                            }
2142                        }
2143                    }
2144                } while (true);
2145            }
2146            }
2147        }
2148    };
2149
2150    public void setSystemProcess() {
2151        try {
2152            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2153            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2154            ServiceManager.addService("meminfo", new MemBinder(this));
2155            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2156            ServiceManager.addService("dbinfo", new DbBinder(this));
2157            if (MONITOR_CPU_USAGE) {
2158                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2159            }
2160            ServiceManager.addService("permission", new PermissionController(this));
2161            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2162
2163            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2164                    "android", STOCK_PM_FLAGS);
2165            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2166
2167            synchronized (this) {
2168                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2169                app.persistent = true;
2170                app.pid = MY_PID;
2171                app.maxAdj = ProcessList.SYSTEM_ADJ;
2172                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2173                synchronized (mPidsSelfLocked) {
2174                    mPidsSelfLocked.put(app.pid, app);
2175                }
2176                updateLruProcessLocked(app, false, null);
2177                updateOomAdjLocked();
2178            }
2179        } catch (PackageManager.NameNotFoundException e) {
2180            throw new RuntimeException(
2181                    "Unable to find android system package", e);
2182        }
2183    }
2184
2185    public void setWindowManager(WindowManagerService wm) {
2186        mWindowManager = wm;
2187        mStackSupervisor.setWindowManager(wm);
2188    }
2189
2190    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2191        mUsageStatsService = usageStatsManager;
2192    }
2193
2194    public void startObservingNativeCrashes() {
2195        final NativeCrashListener ncl = new NativeCrashListener(this);
2196        ncl.start();
2197    }
2198
2199    public IAppOpsService getAppOpsService() {
2200        return mAppOpsService;
2201    }
2202
2203    static class MemBinder extends Binder {
2204        ActivityManagerService mActivityManagerService;
2205        MemBinder(ActivityManagerService activityManagerService) {
2206            mActivityManagerService = activityManagerService;
2207        }
2208
2209        @Override
2210        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2211            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2212                    != PackageManager.PERMISSION_GRANTED) {
2213                pw.println("Permission Denial: can't dump meminfo from from pid="
2214                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2215                        + " without permission " + android.Manifest.permission.DUMP);
2216                return;
2217            }
2218
2219            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2220        }
2221    }
2222
2223    static class GraphicsBinder extends Binder {
2224        ActivityManagerService mActivityManagerService;
2225        GraphicsBinder(ActivityManagerService activityManagerService) {
2226            mActivityManagerService = activityManagerService;
2227        }
2228
2229        @Override
2230        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2231            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2232                    != PackageManager.PERMISSION_GRANTED) {
2233                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2234                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2235                        + " without permission " + android.Manifest.permission.DUMP);
2236                return;
2237            }
2238
2239            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2240        }
2241    }
2242
2243    static class DbBinder extends Binder {
2244        ActivityManagerService mActivityManagerService;
2245        DbBinder(ActivityManagerService activityManagerService) {
2246            mActivityManagerService = activityManagerService;
2247        }
2248
2249        @Override
2250        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2251            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2252                    != PackageManager.PERMISSION_GRANTED) {
2253                pw.println("Permission Denial: can't dump dbinfo from from pid="
2254                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2255                        + " without permission " + android.Manifest.permission.DUMP);
2256                return;
2257            }
2258
2259            mActivityManagerService.dumpDbInfo(fd, pw, args);
2260        }
2261    }
2262
2263    static class CpuBinder extends Binder {
2264        ActivityManagerService mActivityManagerService;
2265        CpuBinder(ActivityManagerService activityManagerService) {
2266            mActivityManagerService = activityManagerService;
2267        }
2268
2269        @Override
2270        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2271            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2272                    != PackageManager.PERMISSION_GRANTED) {
2273                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2274                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2275                        + " without permission " + android.Manifest.permission.DUMP);
2276                return;
2277            }
2278
2279            synchronized (mActivityManagerService.mProcessCpuTracker) {
2280                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2281                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2282                        SystemClock.uptimeMillis()));
2283            }
2284        }
2285    }
2286
2287    public static final class Lifecycle extends SystemService {
2288        private final ActivityManagerService mService;
2289
2290        public Lifecycle(Context context) {
2291            super(context);
2292            mService = new ActivityManagerService(context);
2293        }
2294
2295        @Override
2296        public void onStart() {
2297            mService.start();
2298        }
2299
2300        public ActivityManagerService getService() {
2301            return mService;
2302        }
2303    }
2304
2305    // Note: This method is invoked on the main thread but may need to attach various
2306    // handlers to other threads.  So take care to be explicit about the looper.
2307    public ActivityManagerService(Context systemContext) {
2308        mContext = systemContext;
2309        mFactoryTest = FactoryTest.getMode();
2310        mSystemThread = ActivityThread.currentActivityThread();
2311
2312        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2313
2314        mHandlerThread = new ServiceThread(TAG,
2315                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2316        mHandlerThread.start();
2317        mHandler = new MainHandler(mHandlerThread.getLooper());
2318        mUiHandler = new UiHandler();
2319
2320        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2321                "foreground", BROADCAST_FG_TIMEOUT, false);
2322        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2323                "background", BROADCAST_BG_TIMEOUT, true);
2324        mBroadcastQueues[0] = mFgBroadcastQueue;
2325        mBroadcastQueues[1] = mBgBroadcastQueue;
2326
2327        mServices = new ActiveServices(this);
2328        mProviderMap = new ProviderMap(this);
2329
2330        // TODO: Move creation of battery stats service outside of activity manager service.
2331        File dataDir = Environment.getDataDirectory();
2332        File systemDir = new File(dataDir, "system");
2333        systemDir.mkdirs();
2334        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2335        mBatteryStatsService.getActiveStatistics().readLocked();
2336        mBatteryStatsService.scheduleWriteToDisk();
2337        mOnBattery = DEBUG_POWER ? true
2338                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2339        mBatteryStatsService.getActiveStatistics().setCallback(this);
2340
2341        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2342
2343        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2344
2345        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2346
2347        mUserController = new UserController(this);
2348
2349        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2350            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2351
2352        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2353
2354        mConfiguration.setToDefaults();
2355        mConfiguration.setLocale(Locale.getDefault());
2356
2357        mConfigurationSeq = mConfiguration.seq = 1;
2358        mProcessCpuTracker.init();
2359
2360        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2361        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2362        mRecentTasks = new RecentTasks(this);
2363        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2364        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2365
2366        mProcessCpuThread = new Thread("CpuTracker") {
2367            @Override
2368            public void run() {
2369                while (true) {
2370                    try {
2371                        try {
2372                            synchronized(this) {
2373                                final long now = SystemClock.uptimeMillis();
2374                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2375                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2376                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2377                                //        + ", write delay=" + nextWriteDelay);
2378                                if (nextWriteDelay < nextCpuDelay) {
2379                                    nextCpuDelay = nextWriteDelay;
2380                                }
2381                                if (nextCpuDelay > 0) {
2382                                    mProcessCpuMutexFree.set(true);
2383                                    this.wait(nextCpuDelay);
2384                                }
2385                            }
2386                        } catch (InterruptedException e) {
2387                        }
2388                        updateCpuStatsNow();
2389                    } catch (Exception e) {
2390                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2391                    }
2392                }
2393            }
2394        };
2395
2396        Watchdog.getInstance().addMonitor(this);
2397        Watchdog.getInstance().addThread(mHandler);
2398    }
2399
2400    public void setSystemServiceManager(SystemServiceManager mgr) {
2401        mSystemServiceManager = mgr;
2402    }
2403
2404    public void setInstaller(Installer installer) {
2405        mInstaller = installer;
2406    }
2407
2408    private void start() {
2409        Process.removeAllProcessGroups();
2410        mProcessCpuThread.start();
2411
2412        mBatteryStatsService.publish(mContext);
2413        mAppOpsService.publish(mContext);
2414        Slog.d("AppOps", "AppOpsService published");
2415        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2416    }
2417
2418    public void initPowerManagement() {
2419        mStackSupervisor.initPowerManagement();
2420        mBatteryStatsService.initPowerManagement();
2421        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2422        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2423        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2424        mVoiceWakeLock.setReferenceCounted(false);
2425    }
2426
2427    @Override
2428    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2429            throws RemoteException {
2430        if (code == SYSPROPS_TRANSACTION) {
2431            // We need to tell all apps about the system property change.
2432            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2433            synchronized(this) {
2434                final int NP = mProcessNames.getMap().size();
2435                for (int ip=0; ip<NP; ip++) {
2436                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2437                    final int NA = apps.size();
2438                    for (int ia=0; ia<NA; ia++) {
2439                        ProcessRecord app = apps.valueAt(ia);
2440                        if (app.thread != null) {
2441                            procs.add(app.thread.asBinder());
2442                        }
2443                    }
2444                }
2445            }
2446
2447            int N = procs.size();
2448            for (int i=0; i<N; i++) {
2449                Parcel data2 = Parcel.obtain();
2450                try {
2451                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2452                } catch (RemoteException e) {
2453                }
2454                data2.recycle();
2455            }
2456        }
2457        try {
2458            return super.onTransact(code, data, reply, flags);
2459        } catch (RuntimeException e) {
2460            // The activity manager only throws security exceptions, so let's
2461            // log all others.
2462            if (!(e instanceof SecurityException)) {
2463                Slog.wtf(TAG, "Activity Manager Crash", e);
2464            }
2465            throw e;
2466        }
2467    }
2468
2469    void updateCpuStats() {
2470        final long now = SystemClock.uptimeMillis();
2471        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2472            return;
2473        }
2474        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2475            synchronized (mProcessCpuThread) {
2476                mProcessCpuThread.notify();
2477            }
2478        }
2479    }
2480
2481    void updateCpuStatsNow() {
2482        synchronized (mProcessCpuTracker) {
2483            mProcessCpuMutexFree.set(false);
2484            final long now = SystemClock.uptimeMillis();
2485            boolean haveNewCpuStats = false;
2486
2487            if (MONITOR_CPU_USAGE &&
2488                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2489                mLastCpuTime.set(now);
2490                mProcessCpuTracker.update();
2491                if (mProcessCpuTracker.hasGoodLastStats()) {
2492                    haveNewCpuStats = true;
2493                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2494                    //Slog.i(TAG, "Total CPU usage: "
2495                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2496
2497                    // Slog the cpu usage if the property is set.
2498                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2499                        int user = mProcessCpuTracker.getLastUserTime();
2500                        int system = mProcessCpuTracker.getLastSystemTime();
2501                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2502                        int irq = mProcessCpuTracker.getLastIrqTime();
2503                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2504                        int idle = mProcessCpuTracker.getLastIdleTime();
2505
2506                        int total = user + system + iowait + irq + softIrq + idle;
2507                        if (total == 0) total = 1;
2508
2509                        EventLog.writeEvent(EventLogTags.CPU,
2510                                ((user+system+iowait+irq+softIrq) * 100) / total,
2511                                (user * 100) / total,
2512                                (system * 100) / total,
2513                                (iowait * 100) / total,
2514                                (irq * 100) / total,
2515                                (softIrq * 100) / total);
2516                    }
2517                }
2518            }
2519
2520            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2521            synchronized(bstats) {
2522                synchronized(mPidsSelfLocked) {
2523                    if (haveNewCpuStats) {
2524                        if (bstats.startAddingCpuLocked()) {
2525                            int totalUTime = 0;
2526                            int totalSTime = 0;
2527                            final int N = mProcessCpuTracker.countStats();
2528                            for (int i=0; i<N; i++) {
2529                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2530                                if (!st.working) {
2531                                    continue;
2532                                }
2533                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2534                                totalUTime += st.rel_utime;
2535                                totalSTime += st.rel_stime;
2536                                if (pr != null) {
2537                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2538                                    if (ps == null || !ps.isActive()) {
2539                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2540                                                pr.info.uid, pr.processName);
2541                                    }
2542                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2543                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2544                                } else {
2545                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2546                                    if (ps == null || !ps.isActive()) {
2547                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2548                                                bstats.mapUid(st.uid), st.name);
2549                                    }
2550                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2551                                }
2552                            }
2553                            final int userTime = mProcessCpuTracker.getLastUserTime();
2554                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2555                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2556                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2557                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2558                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2559                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2560                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2561                        }
2562                    }
2563                }
2564
2565                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2566                    mLastWriteTime = now;
2567                    mBatteryStatsService.scheduleWriteToDisk();
2568                }
2569            }
2570        }
2571    }
2572
2573    @Override
2574    public void batteryNeedsCpuUpdate() {
2575        updateCpuStatsNow();
2576    }
2577
2578    @Override
2579    public void batteryPowerChanged(boolean onBattery) {
2580        // When plugging in, update the CPU stats first before changing
2581        // the plug state.
2582        updateCpuStatsNow();
2583        synchronized (this) {
2584            synchronized(mPidsSelfLocked) {
2585                mOnBattery = DEBUG_POWER ? true : onBattery;
2586            }
2587        }
2588    }
2589
2590    @Override
2591    public void batterySendBroadcast(Intent intent) {
2592        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2593                AppOpsManager.OP_NONE, null, false, false,
2594                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2595    }
2596
2597    /**
2598     * Initialize the application bind args. These are passed to each
2599     * process when the bindApplication() IPC is sent to the process. They're
2600     * lazily setup to make sure the services are running when they're asked for.
2601     */
2602    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2603        if (mAppBindArgs == null) {
2604            mAppBindArgs = new HashMap<>();
2605
2606            // Isolated processes won't get this optimization, so that we don't
2607            // violate the rules about which services they have access to.
2608            if (!isolated) {
2609                // Setup the application init args
2610                mAppBindArgs.put("package", ServiceManager.getService("package"));
2611                mAppBindArgs.put("window", ServiceManager.getService("window"));
2612                mAppBindArgs.put(Context.ALARM_SERVICE,
2613                        ServiceManager.getService(Context.ALARM_SERVICE));
2614            }
2615        }
2616        return mAppBindArgs;
2617    }
2618
2619    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2620        if (r != null && mFocusedActivity != r) {
2621            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2622            ActivityRecord last = mFocusedActivity;
2623            mFocusedActivity = r;
2624            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2625                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2626                if (mCurAppTimeTracker != r.appTimeTracker) {
2627                    // We are switching app tracking.  Complete the current one.
2628                    if (mCurAppTimeTracker != null) {
2629                        mCurAppTimeTracker.stop();
2630                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2631                                mCurAppTimeTracker).sendToTarget();
2632                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2633                        mCurAppTimeTracker = null;
2634                    }
2635                    if (r.appTimeTracker != null) {
2636                        mCurAppTimeTracker = r.appTimeTracker;
2637                        startTimeTrackingFocusedActivityLocked();
2638                    }
2639                } else {
2640                    startTimeTrackingFocusedActivityLocked();
2641                }
2642            } else {
2643                r.appTimeTracker = null;
2644            }
2645            if (r.task != null && r.task.voiceInteractor != null) {
2646                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2647            } else {
2648                finishRunningVoiceLocked();
2649                if (last != null && last.task.voiceSession != null) {
2650                    // We had been in a voice interaction session, but now focused has
2651                    // move to something different.  Just finish the session, we can't
2652                    // return to it and retain the proper state and synchronization with
2653                    // the voice interaction service.
2654                    finishVoiceTask(last.task.voiceSession);
2655                }
2656            }
2657            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2658                mWindowManager.setFocusedApp(r.appToken, true);
2659            }
2660            applyUpdateLockStateLocked(r);
2661            if (mFocusedActivity.userId != mLastFocusedUserId) {
2662                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2663                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2664                        mFocusedActivity.userId, 0));
2665                mLastFocusedUserId = mFocusedActivity.userId;
2666            }
2667        }
2668        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2669                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2670                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2671    }
2672
2673    final void clearFocusedActivity(ActivityRecord r) {
2674        if (mFocusedActivity == r) {
2675            ActivityStack stack = mStackSupervisor.getFocusedStack();
2676            if (stack != null) {
2677                ActivityRecord top = stack.topActivity();
2678                if (top != null && top.userId != mLastFocusedUserId) {
2679                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2680                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2681                                    top.userId, 0));
2682                    mLastFocusedUserId = top.userId;
2683                }
2684            }
2685            mFocusedActivity = null;
2686            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2687        }
2688    }
2689
2690    @Override
2691    public void setFocusedStack(int stackId) {
2692        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2693        synchronized (ActivityManagerService.this) {
2694            ActivityStack stack = mStackSupervisor.getStack(stackId);
2695            if (stack != null) {
2696                ActivityRecord r = stack.topRunningActivityLocked();
2697                if (r != null) {
2698                    setFocusedActivityLocked(r, "setFocusedStack");
2699                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2700                }
2701            }
2702        }
2703    }
2704
2705    @Override
2706    public void setFocusedTask(int taskId) {
2707        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2708        long callingId = Binder.clearCallingIdentity();
2709        try {
2710            synchronized (ActivityManagerService.this) {
2711                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2712                if (task != null) {
2713                    ActivityRecord r = task.topRunningActivityLocked();
2714                    if (r != null) {
2715                        setFocusedActivityLocked(r, "setFocusedTask");
2716                        mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2717                    }
2718                }
2719            }
2720        } finally {
2721            Binder.restoreCallingIdentity(callingId);
2722        }
2723    }
2724
2725    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2726    @Override
2727    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2728        synchronized (ActivityManagerService.this) {
2729            if (listener != null) {
2730                mTaskStackListeners.register(listener);
2731            }
2732        }
2733    }
2734
2735    @Override
2736    public void notifyActivityDrawn(IBinder token) {
2737        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2738        synchronized (this) {
2739            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2740            if (r != null) {
2741                r.task.stack.notifyActivityDrawnLocked(r);
2742            }
2743        }
2744    }
2745
2746    final void applyUpdateLockStateLocked(ActivityRecord r) {
2747        // Modifications to the UpdateLock state are done on our handler, outside
2748        // the activity manager's locks.  The new state is determined based on the
2749        // state *now* of the relevant activity record.  The object is passed to
2750        // the handler solely for logging detail, not to be consulted/modified.
2751        final boolean nextState = r != null && r.immersive;
2752        mHandler.sendMessage(
2753                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2754    }
2755
2756    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2757        Message msg = Message.obtain();
2758        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2759        msg.obj = r.task.askedCompatMode ? null : r;
2760        mUiHandler.sendMessage(msg);
2761    }
2762
2763    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2764            String what, Object obj, ProcessRecord srcApp) {
2765        app.lastActivityTime = now;
2766
2767        if (app.activities.size() > 0) {
2768            // Don't want to touch dependent processes that are hosting activities.
2769            return index;
2770        }
2771
2772        int lrui = mLruProcesses.lastIndexOf(app);
2773        if (lrui < 0) {
2774            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2775                    + what + " " + obj + " from " + srcApp);
2776            return index;
2777        }
2778
2779        if (lrui >= index) {
2780            // Don't want to cause this to move dependent processes *back* in the
2781            // list as if they were less frequently used.
2782            return index;
2783        }
2784
2785        if (lrui >= mLruProcessActivityStart) {
2786            // Don't want to touch dependent processes that are hosting activities.
2787            return index;
2788        }
2789
2790        mLruProcesses.remove(lrui);
2791        if (index > 0) {
2792            index--;
2793        }
2794        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2795                + " in LRU list: " + app);
2796        mLruProcesses.add(index, app);
2797        return index;
2798    }
2799
2800    private static void killProcessGroup(int uid, int pid) {
2801        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2802        Process.killProcessGroup(uid, pid);
2803        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2804    }
2805
2806    final void removeLruProcessLocked(ProcessRecord app) {
2807        int lrui = mLruProcesses.lastIndexOf(app);
2808        if (lrui >= 0) {
2809            if (!app.killed) {
2810                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2811                Process.killProcessQuiet(app.pid);
2812                killProcessGroup(app.info.uid, app.pid);
2813            }
2814            if (lrui <= mLruProcessActivityStart) {
2815                mLruProcessActivityStart--;
2816            }
2817            if (lrui <= mLruProcessServiceStart) {
2818                mLruProcessServiceStart--;
2819            }
2820            mLruProcesses.remove(lrui);
2821        }
2822    }
2823
2824    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2825            ProcessRecord client) {
2826        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2827                || app.treatLikeActivity;
2828        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2829        if (!activityChange && hasActivity) {
2830            // The process has activities, so we are only allowing activity-based adjustments
2831            // to move it.  It should be kept in the front of the list with other
2832            // processes that have activities, and we don't want those to change their
2833            // order except due to activity operations.
2834            return;
2835        }
2836
2837        mLruSeq++;
2838        final long now = SystemClock.uptimeMillis();
2839        app.lastActivityTime = now;
2840
2841        // First a quick reject: if the app is already at the position we will
2842        // put it, then there is nothing to do.
2843        if (hasActivity) {
2844            final int N = mLruProcesses.size();
2845            if (N > 0 && mLruProcesses.get(N-1) == app) {
2846                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2847                return;
2848            }
2849        } else {
2850            if (mLruProcessServiceStart > 0
2851                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2852                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2853                return;
2854            }
2855        }
2856
2857        int lrui = mLruProcesses.lastIndexOf(app);
2858
2859        if (app.persistent && lrui >= 0) {
2860            // We don't care about the position of persistent processes, as long as
2861            // they are in the list.
2862            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2863            return;
2864        }
2865
2866        /* In progress: compute new position first, so we can avoid doing work
2867           if the process is not actually going to move.  Not yet working.
2868        int addIndex;
2869        int nextIndex;
2870        boolean inActivity = false, inService = false;
2871        if (hasActivity) {
2872            // Process has activities, put it at the very tipsy-top.
2873            addIndex = mLruProcesses.size();
2874            nextIndex = mLruProcessServiceStart;
2875            inActivity = true;
2876        } else if (hasService) {
2877            // Process has services, put it at the top of the service list.
2878            addIndex = mLruProcessActivityStart;
2879            nextIndex = mLruProcessServiceStart;
2880            inActivity = true;
2881            inService = true;
2882        } else  {
2883            // Process not otherwise of interest, it goes to the top of the non-service area.
2884            addIndex = mLruProcessServiceStart;
2885            if (client != null) {
2886                int clientIndex = mLruProcesses.lastIndexOf(client);
2887                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2888                        + app);
2889                if (clientIndex >= 0 && addIndex > clientIndex) {
2890                    addIndex = clientIndex;
2891                }
2892            }
2893            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2894        }
2895
2896        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2897                + mLruProcessActivityStart + "): " + app);
2898        */
2899
2900        if (lrui >= 0) {
2901            if (lrui < mLruProcessActivityStart) {
2902                mLruProcessActivityStart--;
2903            }
2904            if (lrui < mLruProcessServiceStart) {
2905                mLruProcessServiceStart--;
2906            }
2907            /*
2908            if (addIndex > lrui) {
2909                addIndex--;
2910            }
2911            if (nextIndex > lrui) {
2912                nextIndex--;
2913            }
2914            */
2915            mLruProcesses.remove(lrui);
2916        }
2917
2918        /*
2919        mLruProcesses.add(addIndex, app);
2920        if (inActivity) {
2921            mLruProcessActivityStart++;
2922        }
2923        if (inService) {
2924            mLruProcessActivityStart++;
2925        }
2926        */
2927
2928        int nextIndex;
2929        if (hasActivity) {
2930            final int N = mLruProcesses.size();
2931            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2932                // Process doesn't have activities, but has clients with
2933                // activities...  move it up, but one below the top (the top
2934                // should always have a real activity).
2935                if (DEBUG_LRU) Slog.d(TAG_LRU,
2936                        "Adding to second-top of LRU activity list: " + app);
2937                mLruProcesses.add(N - 1, app);
2938                // To keep it from spamming the LRU list (by making a bunch of clients),
2939                // we will push down any other entries owned by the app.
2940                final int uid = app.info.uid;
2941                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2942                    ProcessRecord subProc = mLruProcesses.get(i);
2943                    if (subProc.info.uid == uid) {
2944                        // We want to push this one down the list.  If the process after
2945                        // it is for the same uid, however, don't do so, because we don't
2946                        // want them internally to be re-ordered.
2947                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2948                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2949                                    "Pushing uid " + uid + " swapping at " + i + ": "
2950                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2951                            ProcessRecord tmp = mLruProcesses.get(i);
2952                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2953                            mLruProcesses.set(i - 1, tmp);
2954                            i--;
2955                        }
2956                    } else {
2957                        // A gap, we can stop here.
2958                        break;
2959                    }
2960                }
2961            } else {
2962                // Process has activities, put it at the very tipsy-top.
2963                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2964                mLruProcesses.add(app);
2965            }
2966            nextIndex = mLruProcessServiceStart;
2967        } else if (hasService) {
2968            // Process has services, put it at the top of the service list.
2969            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2970            mLruProcesses.add(mLruProcessActivityStart, app);
2971            nextIndex = mLruProcessServiceStart;
2972            mLruProcessActivityStart++;
2973        } else  {
2974            // Process not otherwise of interest, it goes to the top of the non-service area.
2975            int index = mLruProcessServiceStart;
2976            if (client != null) {
2977                // If there is a client, don't allow the process to be moved up higher
2978                // in the list than that client.
2979                int clientIndex = mLruProcesses.lastIndexOf(client);
2980                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2981                        + " when updating " + app);
2982                if (clientIndex <= lrui) {
2983                    // Don't allow the client index restriction to push it down farther in the
2984                    // list than it already is.
2985                    clientIndex = lrui;
2986                }
2987                if (clientIndex >= 0 && index > clientIndex) {
2988                    index = clientIndex;
2989                }
2990            }
2991            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2992            mLruProcesses.add(index, app);
2993            nextIndex = index-1;
2994            mLruProcessActivityStart++;
2995            mLruProcessServiceStart++;
2996        }
2997
2998        // If the app is currently using a content provider or service,
2999        // bump those processes as well.
3000        for (int j=app.connections.size()-1; j>=0; j--) {
3001            ConnectionRecord cr = app.connections.valueAt(j);
3002            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3003                    && cr.binding.service.app != null
3004                    && cr.binding.service.app.lruSeq != mLruSeq
3005                    && !cr.binding.service.app.persistent) {
3006                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3007                        "service connection", cr, app);
3008            }
3009        }
3010        for (int j=app.conProviders.size()-1; j>=0; j--) {
3011            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3012            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3013                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3014                        "provider reference", cpr, app);
3015            }
3016        }
3017    }
3018
3019    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3020        if (uid == Process.SYSTEM_UID) {
3021            // The system gets to run in any process.  If there are multiple
3022            // processes with the same uid, just pick the first (this
3023            // should never happen).
3024            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3025            if (procs == null) return null;
3026            final int procCount = procs.size();
3027            for (int i = 0; i < procCount; i++) {
3028                final int procUid = procs.keyAt(i);
3029                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3030                    // Don't use an app process or different user process for system component.
3031                    continue;
3032                }
3033                return procs.valueAt(i);
3034            }
3035        }
3036        ProcessRecord proc = mProcessNames.get(processName, uid);
3037        if (false && proc != null && !keepIfLarge
3038                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3039                && proc.lastCachedPss >= 4000) {
3040            // Turn this condition on to cause killing to happen regularly, for testing.
3041            if (proc.baseProcessTracker != null) {
3042                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3043            }
3044            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3045        } else if (proc != null && !keepIfLarge
3046                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3047                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3048            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3049            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3050                if (proc.baseProcessTracker != null) {
3051                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3052                }
3053                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3054            }
3055        }
3056        return proc;
3057    }
3058
3059    void ensurePackageDexOpt(String packageName) {
3060        IPackageManager pm = AppGlobals.getPackageManager();
3061        try {
3062            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3063                mDidDexOpt = true;
3064            }
3065        } catch (RemoteException e) {
3066        }
3067    }
3068
3069    boolean isNextTransitionForward() {
3070        int transit = mWindowManager.getPendingAppTransition();
3071        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3072                || transit == AppTransition.TRANSIT_TASK_OPEN
3073                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3074    }
3075
3076    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3077            String processName, String abiOverride, int uid, Runnable crashHandler) {
3078        synchronized(this) {
3079            ApplicationInfo info = new ApplicationInfo();
3080            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3081            // For isolated processes, the former contains the parent's uid and the latter the
3082            // actual uid of the isolated process.
3083            // In the special case introduced by this method (which is, starting an isolated
3084            // process directly from the SystemServer without an actual parent app process) the
3085            // closest thing to a parent's uid is SYSTEM_UID.
3086            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3087            // the |isolated| logic in the ProcessRecord constructor.
3088            info.uid = Process.SYSTEM_UID;
3089            info.processName = processName;
3090            info.className = entryPoint;
3091            info.packageName = "android";
3092            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3093                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3094                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3095                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3096                    crashHandler);
3097            return proc != null ? proc.pid : 0;
3098        }
3099    }
3100
3101    final ProcessRecord startProcessLocked(String processName,
3102            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3103            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3104            boolean isolated, boolean keepIfLarge) {
3105        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3106                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3107                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3108                null /* crashHandler */);
3109    }
3110
3111    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3112            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3113            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3114            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3115        long startTime = SystemClock.elapsedRealtime();
3116        ProcessRecord app;
3117        if (!isolated) {
3118            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3119            checkTime(startTime, "startProcess: after getProcessRecord");
3120
3121            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3122                // If we are in the background, then check to see if this process
3123                // is bad.  If so, we will just silently fail.
3124                if (mBadProcesses.get(info.processName, info.uid) != null) {
3125                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3126                            + "/" + info.processName);
3127                    return null;
3128                }
3129            } else {
3130                // When the user is explicitly starting a process, then clear its
3131                // crash count so that we won't make it bad until they see at
3132                // least one crash dialog again, and make the process good again
3133                // if it had been bad.
3134                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3135                        + "/" + info.processName);
3136                mProcessCrashTimes.remove(info.processName, info.uid);
3137                if (mBadProcesses.get(info.processName, info.uid) != null) {
3138                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3139                            UserHandle.getUserId(info.uid), info.uid,
3140                            info.processName);
3141                    mBadProcesses.remove(info.processName, info.uid);
3142                    if (app != null) {
3143                        app.bad = false;
3144                    }
3145                }
3146            }
3147        } else {
3148            // If this is an isolated process, it can't re-use an existing process.
3149            app = null;
3150        }
3151
3152        // app launch boost for big.little configurations
3153        // use cpusets to migrate freshly launched tasks to big cores
3154        synchronized(ActivityManagerService.this) {
3155            nativeMigrateToBoost();
3156            mIsBoosted = true;
3157            mBoostStartTime = SystemClock.uptimeMillis();
3158            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3159            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3160        }
3161
3162        // We don't have to do anything more if:
3163        // (1) There is an existing application record; and
3164        // (2) The caller doesn't think it is dead, OR there is no thread
3165        //     object attached to it so we know it couldn't have crashed; and
3166        // (3) There is a pid assigned to it, so it is either starting or
3167        //     already running.
3168        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3169                + " app=" + app + " knownToBeDead=" + knownToBeDead
3170                + " thread=" + (app != null ? app.thread : null)
3171                + " pid=" + (app != null ? app.pid : -1));
3172        if (app != null && app.pid > 0) {
3173            if (!knownToBeDead || app.thread == null) {
3174                // We already have the app running, or are waiting for it to
3175                // come up (we have a pid but not yet its thread), so keep it.
3176                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3177                // If this is a new package in the process, add the package to the list
3178                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3179                checkTime(startTime, "startProcess: done, added package to proc");
3180                return app;
3181            }
3182
3183            // An application record is attached to a previous process,
3184            // clean it up now.
3185            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3186            checkTime(startTime, "startProcess: bad proc running, killing");
3187            killProcessGroup(app.info.uid, app.pid);
3188            handleAppDiedLocked(app, true, true);
3189            checkTime(startTime, "startProcess: done killing old proc");
3190        }
3191
3192        String hostingNameStr = hostingName != null
3193                ? hostingName.flattenToShortString() : null;
3194
3195        if (app == null) {
3196            checkTime(startTime, "startProcess: creating new process record");
3197            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3198            if (app == null) {
3199                Slog.w(TAG, "Failed making new process record for "
3200                        + processName + "/" + info.uid + " isolated=" + isolated);
3201                return null;
3202            }
3203            app.crashHandler = crashHandler;
3204            checkTime(startTime, "startProcess: done creating new process record");
3205        } else {
3206            // If this is a new package in the process, add the package to the list
3207            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3208            checkTime(startTime, "startProcess: added package to existing proc");
3209        }
3210
3211        // If the system is not ready yet, then hold off on starting this
3212        // process until it is.
3213        if (!mProcessesReady
3214                && !isAllowedWhileBooting(info)
3215                && !allowWhileBooting) {
3216            if (!mProcessesOnHold.contains(app)) {
3217                mProcessesOnHold.add(app);
3218            }
3219            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3220                    "System not ready, putting on hold: " + app);
3221            checkTime(startTime, "startProcess: returning with proc on hold");
3222            return app;
3223        }
3224
3225        checkTime(startTime, "startProcess: stepping in to startProcess");
3226        startProcessLocked(
3227                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3228        checkTime(startTime, "startProcess: done starting proc!");
3229        return (app.pid != 0) ? app : null;
3230    }
3231
3232    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3233        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3234    }
3235
3236    private final void startProcessLocked(ProcessRecord app,
3237            String hostingType, String hostingNameStr) {
3238        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3239                null /* entryPoint */, null /* entryPointArgs */);
3240    }
3241
3242    private final void startProcessLocked(ProcessRecord app, String hostingType,
3243            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3244        long startTime = SystemClock.elapsedRealtime();
3245        if (app.pid > 0 && app.pid != MY_PID) {
3246            checkTime(startTime, "startProcess: removing from pids map");
3247            synchronized (mPidsSelfLocked) {
3248                mPidsSelfLocked.remove(app.pid);
3249                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3250            }
3251            checkTime(startTime, "startProcess: done removing from pids map");
3252            app.setPid(0);
3253        }
3254
3255        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3256                "startProcessLocked removing on hold: " + app);
3257        mProcessesOnHold.remove(app);
3258
3259        checkTime(startTime, "startProcess: starting to update cpu stats");
3260        updateCpuStats();
3261        checkTime(startTime, "startProcess: done updating cpu stats");
3262
3263        try {
3264            try {
3265                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3266                    // This is caught below as if we had failed to fork zygote
3267                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3268                }
3269            } catch (RemoteException e) {
3270                throw e.rethrowAsRuntimeException();
3271            }
3272
3273            int uid = app.uid;
3274            int[] gids = null;
3275            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3276            if (!app.isolated) {
3277                int[] permGids = null;
3278                try {
3279                    checkTime(startTime, "startProcess: getting gids from package manager");
3280                    final IPackageManager pm = AppGlobals.getPackageManager();
3281                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3282                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3283                            MountServiceInternal.class);
3284                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3285                            app.info.packageName);
3286                } catch (RemoteException e) {
3287                    throw e.rethrowAsRuntimeException();
3288                }
3289
3290                /*
3291                 * Add shared application and profile GIDs so applications can share some
3292                 * resources like shared libraries and access user-wide resources
3293                 */
3294                if (ArrayUtils.isEmpty(permGids)) {
3295                    gids = new int[2];
3296                } else {
3297                    gids = new int[permGids.length + 2];
3298                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3299                }
3300                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3301                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3302            }
3303            checkTime(startTime, "startProcess: building args");
3304            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3305                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3306                        && mTopComponent != null
3307                        && app.processName.equals(mTopComponent.getPackageName())) {
3308                    uid = 0;
3309                }
3310                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3311                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3312                    uid = 0;
3313                }
3314            }
3315            int debugFlags = 0;
3316            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3317                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3318                // Also turn on CheckJNI for debuggable apps. It's quite
3319                // awkward to turn on otherwise.
3320                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3321            }
3322            // Run the app in safe mode if its manifest requests so or the
3323            // system is booted in safe mode.
3324            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3325                mSafeMode == true) {
3326                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3327            }
3328            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3329                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3330            }
3331            String jitDebugProperty = SystemProperties.get("debug.usejit");
3332            if ("true".equals(jitDebugProperty)) {
3333                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3334            } else if (!"false".equals(jitDebugProperty)) {
3335                // If we didn't force disable by setting false, defer to the dalvik vm options.
3336                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3337                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3338                }
3339            }
3340            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3341            if ("true".equals(genDebugInfoProperty)) {
3342                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3343            }
3344            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3345                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3346            }
3347            if ("1".equals(SystemProperties.get("debug.assert"))) {
3348                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3349            }
3350
3351            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3352            if (requiredAbi == null) {
3353                requiredAbi = Build.SUPPORTED_ABIS[0];
3354            }
3355
3356            String instructionSet = null;
3357            if (app.info.primaryCpuAbi != null) {
3358                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3359            }
3360
3361            app.gids = gids;
3362            app.requiredAbi = requiredAbi;
3363            app.instructionSet = instructionSet;
3364
3365            // Start the process.  It will either succeed and return a result containing
3366            // the PID of the new process, or else throw a RuntimeException.
3367            boolean isActivityProcess = (entryPoint == null);
3368            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3369            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3370                    app.processName);
3371            checkTime(startTime, "startProcess: asking zygote to start proc");
3372            Process.ProcessStartResult startResult = Process.start(entryPoint,
3373                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3374                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3375                    app.info.dataDir, entryPointArgs);
3376            checkTime(startTime, "startProcess: returned from zygote!");
3377            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3378
3379            if (app.isolated) {
3380                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3381            }
3382            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3383            checkTime(startTime, "startProcess: done updating battery stats");
3384
3385            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3386                    UserHandle.getUserId(uid), startResult.pid, uid,
3387                    app.processName, hostingType,
3388                    hostingNameStr != null ? hostingNameStr : "");
3389
3390            if (app.persistent) {
3391                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3392            }
3393
3394            checkTime(startTime, "startProcess: building log message");
3395            StringBuilder buf = mStringBuilder;
3396            buf.setLength(0);
3397            buf.append("Start proc ");
3398            buf.append(startResult.pid);
3399            buf.append(':');
3400            buf.append(app.processName);
3401            buf.append('/');
3402            UserHandle.formatUid(buf, uid);
3403            if (!isActivityProcess) {
3404                buf.append(" [");
3405                buf.append(entryPoint);
3406                buf.append("]");
3407            }
3408            buf.append(" for ");
3409            buf.append(hostingType);
3410            if (hostingNameStr != null) {
3411                buf.append(" ");
3412                buf.append(hostingNameStr);
3413            }
3414            Slog.i(TAG, buf.toString());
3415            app.setPid(startResult.pid);
3416            app.usingWrapper = startResult.usingWrapper;
3417            app.removed = false;
3418            app.killed = false;
3419            app.killedByAm = false;
3420            checkTime(startTime, "startProcess: starting to update pids map");
3421            synchronized (mPidsSelfLocked) {
3422                this.mPidsSelfLocked.put(startResult.pid, app);
3423                if (isActivityProcess) {
3424                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3425                    msg.obj = app;
3426                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3427                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3428                }
3429            }
3430            checkTime(startTime, "startProcess: done updating pids map");
3431        } catch (RuntimeException e) {
3432            // XXX do better error recovery.
3433            app.setPid(0);
3434            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3435            if (app.isolated) {
3436                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3437            }
3438            Slog.e(TAG, "Failure starting process " + app.processName, e);
3439        }
3440    }
3441
3442    void updateUsageStats(ActivityRecord component, boolean resumed) {
3443        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3444                "updateUsageStats: comp=" + component + "res=" + resumed);
3445        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3446        if (resumed) {
3447            if (mUsageStatsService != null) {
3448                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3449                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3450            }
3451            synchronized (stats) {
3452                stats.noteActivityResumedLocked(component.app.uid);
3453            }
3454        } else {
3455            if (mUsageStatsService != null) {
3456                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3457                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3458            }
3459            synchronized (stats) {
3460                stats.noteActivityPausedLocked(component.app.uid);
3461            }
3462        }
3463    }
3464
3465    Intent getHomeIntent() {
3466        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3467        intent.setComponent(mTopComponent);
3468        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3469            intent.addCategory(Intent.CATEGORY_HOME);
3470        }
3471        return intent;
3472    }
3473
3474    boolean startHomeActivityLocked(int userId, String reason) {
3475        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3476                && mTopAction == null) {
3477            // We are running in factory test mode, but unable to find
3478            // the factory test app, so just sit around displaying the
3479            // error message and don't try to start anything.
3480            return false;
3481        }
3482        Intent intent = getHomeIntent();
3483        ActivityInfo aInfo =
3484            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3485        if (aInfo != null) {
3486            intent.setComponent(new ComponentName(
3487                    aInfo.applicationInfo.packageName, aInfo.name));
3488            // Don't do this if the home app is currently being
3489            // instrumented.
3490            aInfo = new ActivityInfo(aInfo);
3491            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3492            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3493                    aInfo.applicationInfo.uid, true);
3494            if (app == null || app.instrumentationClass == null) {
3495                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3496                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3497            }
3498        }
3499
3500        return true;
3501    }
3502
3503    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3504        ActivityInfo ai = null;
3505        ComponentName comp = intent.getComponent();
3506        try {
3507            if (comp != null) {
3508                // Factory test.
3509                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3510            } else {
3511                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3512                        intent,
3513                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3514                        flags, userId);
3515
3516                if (info != null) {
3517                    ai = info.activityInfo;
3518                }
3519            }
3520        } catch (RemoteException e) {
3521            // ignore
3522        }
3523
3524        return ai;
3525    }
3526
3527    /**
3528     * Starts the "new version setup screen" if appropriate.
3529     */
3530    void startSetupActivityLocked() {
3531        // Only do this once per boot.
3532        if (mCheckedForSetup) {
3533            return;
3534        }
3535
3536        // We will show this screen if the current one is a different
3537        // version than the last one shown, and we are not running in
3538        // low-level factory test mode.
3539        final ContentResolver resolver = mContext.getContentResolver();
3540        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3541                Settings.Global.getInt(resolver,
3542                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3543            mCheckedForSetup = true;
3544
3545            // See if we should be showing the platform update setup UI.
3546            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3547            List<ResolveInfo> ris = mContext.getPackageManager()
3548                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3549
3550            // We don't allow third party apps to replace this.
3551            ResolveInfo ri = null;
3552            for (int i=0; ris != null && i<ris.size(); i++) {
3553                if ((ris.get(i).activityInfo.applicationInfo.flags
3554                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3555                    ri = ris.get(i);
3556                    break;
3557                }
3558            }
3559
3560            if (ri != null) {
3561                String vers = ri.activityInfo.metaData != null
3562                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3563                        : null;
3564                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3565                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3566                            Intent.METADATA_SETUP_VERSION);
3567                }
3568                String lastVers = Settings.Secure.getString(
3569                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3570                if (vers != null && !vers.equals(lastVers)) {
3571                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3572                    intent.setComponent(new ComponentName(
3573                            ri.activityInfo.packageName, ri.activityInfo.name));
3574                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3575                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3576                            null, null, null);
3577                }
3578            }
3579        }
3580    }
3581
3582    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3583        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3584    }
3585
3586    void enforceNotIsolatedCaller(String caller) {
3587        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3588            throw new SecurityException("Isolated process not allowed to call " + caller);
3589        }
3590    }
3591
3592    void enforceShellRestriction(String restriction, int userHandle) {
3593        if (Binder.getCallingUid() == Process.SHELL_UID) {
3594            if (userHandle < 0
3595                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3596                throw new SecurityException("Shell does not have permission to access user "
3597                        + userHandle);
3598            }
3599        }
3600    }
3601
3602    @Override
3603    public int getFrontActivityScreenCompatMode() {
3604        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3605        synchronized (this) {
3606            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3607        }
3608    }
3609
3610    @Override
3611    public void setFrontActivityScreenCompatMode(int mode) {
3612        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3613                "setFrontActivityScreenCompatMode");
3614        synchronized (this) {
3615            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3616        }
3617    }
3618
3619    @Override
3620    public int getPackageScreenCompatMode(String packageName) {
3621        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3622        synchronized (this) {
3623            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3624        }
3625    }
3626
3627    @Override
3628    public void setPackageScreenCompatMode(String packageName, int mode) {
3629        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3630                "setPackageScreenCompatMode");
3631        synchronized (this) {
3632            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3633        }
3634    }
3635
3636    @Override
3637    public boolean getPackageAskScreenCompat(String packageName) {
3638        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3639        synchronized (this) {
3640            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3641        }
3642    }
3643
3644    @Override
3645    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3646        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3647                "setPackageAskScreenCompat");
3648        synchronized (this) {
3649            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3650        }
3651    }
3652
3653    private boolean hasUsageStatsPermission(String callingPackage) {
3654        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3655                Binder.getCallingUid(), callingPackage);
3656        if (mode == AppOpsManager.MODE_DEFAULT) {
3657            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3658                    == PackageManager.PERMISSION_GRANTED;
3659        }
3660        return mode == AppOpsManager.MODE_ALLOWED;
3661    }
3662
3663    @Override
3664    public int getPackageProcessState(String packageName, String callingPackage) {
3665        if (!hasUsageStatsPermission(callingPackage)) {
3666            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3667                    "getPackageProcessState");
3668        }
3669
3670        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3671        synchronized (this) {
3672            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3673                final ProcessRecord proc = mLruProcesses.get(i);
3674                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3675                        || procState > proc.setProcState) {
3676                    boolean found = false;
3677                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3678                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3679                            procState = proc.setProcState;
3680                            found = true;
3681                        }
3682                    }
3683                    if (proc.pkgDeps != null && !found) {
3684                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3685                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3686                                procState = proc.setProcState;
3687                                break;
3688                            }
3689                        }
3690                    }
3691                }
3692            }
3693        }
3694        return procState;
3695    }
3696
3697    @Override
3698    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3699        synchronized (this) {
3700            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3701            if (app == null) {
3702                return false;
3703            }
3704            if (app.trimMemoryLevel < level && app.thread != null &&
3705                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3706                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3707                try {
3708                    app.thread.scheduleTrimMemory(level);
3709                    app.trimMemoryLevel = level;
3710                    return true;
3711                } catch (RemoteException e) {
3712                    // Fallthrough to failure case.
3713                }
3714            }
3715        }
3716        return false;
3717    }
3718
3719    private void dispatchProcessesChanged() {
3720        int N;
3721        synchronized (this) {
3722            N = mPendingProcessChanges.size();
3723            if (mActiveProcessChanges.length < N) {
3724                mActiveProcessChanges = new ProcessChangeItem[N];
3725            }
3726            mPendingProcessChanges.toArray(mActiveProcessChanges);
3727            mPendingProcessChanges.clear();
3728            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3729                    "*** Delivering " + N + " process changes");
3730        }
3731
3732        int i = mProcessObservers.beginBroadcast();
3733        while (i > 0) {
3734            i--;
3735            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3736            if (observer != null) {
3737                try {
3738                    for (int j=0; j<N; j++) {
3739                        ProcessChangeItem item = mActiveProcessChanges[j];
3740                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3741                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3742                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3743                                    + item.uid + ": " + item.foregroundActivities);
3744                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3745                                    item.foregroundActivities);
3746                        }
3747                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3748                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3749                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3750                                    + ": " + item.processState);
3751                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3752                        }
3753                    }
3754                } catch (RemoteException e) {
3755                }
3756            }
3757        }
3758        mProcessObservers.finishBroadcast();
3759
3760        synchronized (this) {
3761            for (int j=0; j<N; j++) {
3762                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3763            }
3764        }
3765    }
3766
3767    private void dispatchProcessDied(int pid, int uid) {
3768        int i = mProcessObservers.beginBroadcast();
3769        while (i > 0) {
3770            i--;
3771            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3772            if (observer != null) {
3773                try {
3774                    observer.onProcessDied(pid, uid);
3775                } catch (RemoteException e) {
3776                }
3777            }
3778        }
3779        mProcessObservers.finishBroadcast();
3780    }
3781
3782    private void dispatchUidsChanged() {
3783        int N;
3784        synchronized (this) {
3785            N = mPendingUidChanges.size();
3786            if (mActiveUidChanges.length < N) {
3787                mActiveUidChanges = new UidRecord.ChangeItem[N];
3788            }
3789            for (int i=0; i<N; i++) {
3790                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3791                mActiveUidChanges[i] = change;
3792                change.uidRecord.pendingChange = null;
3793                change.uidRecord = null;
3794            }
3795            mPendingUidChanges.clear();
3796            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3797                    "*** Delivering " + N + " uid changes");
3798        }
3799
3800        if (mLocalPowerManager != null) {
3801            for (int j=0; j<N; j++) {
3802                UidRecord.ChangeItem item = mActiveUidChanges[j];
3803                if (item.gone) {
3804                    mLocalPowerManager.uidGone(item.uid);
3805                } else {
3806                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3807                }
3808            }
3809        }
3810
3811        int i = mUidObservers.beginBroadcast();
3812        while (i > 0) {
3813            i--;
3814            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3815            if (observer != null) {
3816                try {
3817                    for (int j=0; j<N; j++) {
3818                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3819                        if (item.gone) {
3820                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3821                                    "UID gone uid=" + item.uid);
3822                            observer.onUidGone(item.uid);
3823                        } else {
3824                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3825                                    "UID CHANGED uid=" + item.uid
3826                                    + ": " + item.processState);
3827                            observer.onUidStateChanged(item.uid, item.processState);
3828                        }
3829                    }
3830                } catch (RemoteException e) {
3831                }
3832            }
3833        }
3834        mUidObservers.finishBroadcast();
3835
3836        synchronized (this) {
3837            for (int j=0; j<N; j++) {
3838                mAvailUidChanges.add(mActiveUidChanges[j]);
3839            }
3840        }
3841    }
3842
3843    @Override
3844    public final int startActivity(IApplicationThread caller, String callingPackage,
3845            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3846            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3847        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3848                resultWho, requestCode, startFlags, profilerInfo, options,
3849                UserHandle.getCallingUserId());
3850    }
3851
3852    @Override
3853    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3854            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3855            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3856        enforceNotIsolatedCaller("startActivity");
3857        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3858                false, ALLOW_FULL_ONLY, "startActivity", null);
3859        // TODO: Switch to user app stacks here.
3860        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3861                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3862                profilerInfo, null, null, options, false, userId, null, null);
3863    }
3864
3865    @Override
3866    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3867            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3868            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3869            int userId) {
3870
3871        // This is very dangerous -- it allows you to perform a start activity (including
3872        // permission grants) as any app that may launch one of your own activities.  So
3873        // we will only allow this to be done from activities that are part of the core framework,
3874        // and then only when they are running as the system.
3875        final ActivityRecord sourceRecord;
3876        final int targetUid;
3877        final String targetPackage;
3878        synchronized (this) {
3879            if (resultTo == null) {
3880                throw new SecurityException("Must be called from an activity");
3881            }
3882            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3883            if (sourceRecord == null) {
3884                throw new SecurityException("Called with bad activity token: " + resultTo);
3885            }
3886            if (!sourceRecord.info.packageName.equals("android")) {
3887                throw new SecurityException(
3888                        "Must be called from an activity that is declared in the android package");
3889            }
3890            if (sourceRecord.app == null) {
3891                throw new SecurityException("Called without a process attached to activity");
3892            }
3893            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3894                // This is still okay, as long as this activity is running under the
3895                // uid of the original calling activity.
3896                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3897                    throw new SecurityException(
3898                            "Calling activity in uid " + sourceRecord.app.uid
3899                                    + " must be system uid or original calling uid "
3900                                    + sourceRecord.launchedFromUid);
3901                }
3902            }
3903            if (ignoreTargetSecurity) {
3904                if (intent.getComponent() == null) {
3905                    throw new SecurityException(
3906                            "Component must be specified with ignoreTargetSecurity");
3907                }
3908                if (intent.getSelector() != null) {
3909                    throw new SecurityException(
3910                            "Selector not allowed with ignoreTargetSecurity");
3911                }
3912            }
3913            targetUid = sourceRecord.launchedFromUid;
3914            targetPackage = sourceRecord.launchedFromPackage;
3915        }
3916
3917        if (userId == UserHandle.USER_NULL) {
3918            userId = UserHandle.getUserId(sourceRecord.app.uid);
3919        }
3920
3921        // TODO: Switch to user app stacks here.
3922        try {
3923            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3924                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3925                    null, null, options, ignoreTargetSecurity, userId, null, null);
3926            return ret;
3927        } catch (SecurityException e) {
3928            // XXX need to figure out how to propagate to original app.
3929            // A SecurityException here is generally actually a fault of the original
3930            // calling activity (such as a fairly granting permissions), so propagate it
3931            // back to them.
3932            /*
3933            StringBuilder msg = new StringBuilder();
3934            msg.append("While launching");
3935            msg.append(intent.toString());
3936            msg.append(": ");
3937            msg.append(e.getMessage());
3938            */
3939            throw e;
3940        }
3941    }
3942
3943    @Override
3944    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3945            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3946            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3947        enforceNotIsolatedCaller("startActivityAndWait");
3948        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3949                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3950        WaitResult res = new WaitResult();
3951        // TODO: Switch to user app stacks here.
3952        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3953                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3954                options, false, userId, null, null);
3955        return res;
3956    }
3957
3958    @Override
3959    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3960            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3961            int startFlags, Configuration config, Bundle options, int userId) {
3962        enforceNotIsolatedCaller("startActivityWithConfig");
3963        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3964                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3965        // TODO: Switch to user app stacks here.
3966        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3967                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3968                null, null, config, options, false, userId, null, null);
3969        return ret;
3970    }
3971
3972    @Override
3973    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3974            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3975            int requestCode, int flagsMask, int flagsValues, Bundle options)
3976            throws TransactionTooLargeException {
3977        enforceNotIsolatedCaller("startActivityIntentSender");
3978        // Refuse possible leaked file descriptors
3979        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3980            throw new IllegalArgumentException("File descriptors passed in Intent");
3981        }
3982
3983        IIntentSender sender = intent.getTarget();
3984        if (!(sender instanceof PendingIntentRecord)) {
3985            throw new IllegalArgumentException("Bad PendingIntent object");
3986        }
3987
3988        PendingIntentRecord pir = (PendingIntentRecord)sender;
3989
3990        synchronized (this) {
3991            // If this is coming from the currently resumed activity, it is
3992            // effectively saying that app switches are allowed at this point.
3993            final ActivityStack stack = getFocusedStack();
3994            if (stack.mResumedActivity != null &&
3995                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3996                mAppSwitchesAllowedTime = 0;
3997            }
3998        }
3999        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4000                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
4001        return ret;
4002    }
4003
4004    @Override
4005    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4006            Intent intent, String resolvedType, IVoiceInteractionSession session,
4007            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4008            Bundle options, int userId) {
4009        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4010                != PackageManager.PERMISSION_GRANTED) {
4011            String msg = "Permission Denial: startVoiceActivity() from pid="
4012                    + Binder.getCallingPid()
4013                    + ", uid=" + Binder.getCallingUid()
4014                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4015            Slog.w(TAG, msg);
4016            throw new SecurityException(msg);
4017        }
4018        if (session == null || interactor == null) {
4019            throw new NullPointerException("null session or interactor");
4020        }
4021        userId = handleIncomingUser(callingPid, callingUid, userId,
4022                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4023        // TODO: Switch to user app stacks here.
4024        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4025                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4026                null, options, false, userId, null, null);
4027    }
4028
4029    @Override
4030    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4031        synchronized (this) {
4032            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4033                if (keepAwake) {
4034                    mVoiceWakeLock.acquire();
4035                } else {
4036                    mVoiceWakeLock.release();
4037                }
4038            }
4039        }
4040    }
4041
4042    @Override
4043    public boolean startNextMatchingActivity(IBinder callingActivity,
4044            Intent intent, Bundle options) {
4045        // Refuse possible leaked file descriptors
4046        if (intent != null && intent.hasFileDescriptors() == true) {
4047            throw new IllegalArgumentException("File descriptors passed in Intent");
4048        }
4049
4050        synchronized (this) {
4051            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4052            if (r == null) {
4053                ActivityOptions.abort(options);
4054                return false;
4055            }
4056            if (r.app == null || r.app.thread == null) {
4057                // The caller is not running...  d'oh!
4058                ActivityOptions.abort(options);
4059                return false;
4060            }
4061            intent = new Intent(intent);
4062            // The caller is not allowed to change the data.
4063            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4064            // And we are resetting to find the next component...
4065            intent.setComponent(null);
4066
4067            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4068
4069            ActivityInfo aInfo = null;
4070            try {
4071                List<ResolveInfo> resolves =
4072                    AppGlobals.getPackageManager().queryIntentActivities(
4073                            intent, r.resolvedType,
4074                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4075                            UserHandle.getCallingUserId());
4076
4077                // Look for the original activity in the list...
4078                final int N = resolves != null ? resolves.size() : 0;
4079                for (int i=0; i<N; i++) {
4080                    ResolveInfo rInfo = resolves.get(i);
4081                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4082                            && rInfo.activityInfo.name.equals(r.info.name)) {
4083                        // We found the current one...  the next matching is
4084                        // after it.
4085                        i++;
4086                        if (i<N) {
4087                            aInfo = resolves.get(i).activityInfo;
4088                        }
4089                        if (debug) {
4090                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4091                                    + "/" + r.info.name);
4092                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4093                                    + "/" + aInfo.name);
4094                        }
4095                        break;
4096                    }
4097                }
4098            } catch (RemoteException e) {
4099            }
4100
4101            if (aInfo == null) {
4102                // Nobody who is next!
4103                ActivityOptions.abort(options);
4104                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4105                return false;
4106            }
4107
4108            intent.setComponent(new ComponentName(
4109                    aInfo.applicationInfo.packageName, aInfo.name));
4110            intent.setFlags(intent.getFlags()&~(
4111                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4112                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4113                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4114                    Intent.FLAG_ACTIVITY_NEW_TASK));
4115
4116            // Okay now we need to start the new activity, replacing the
4117            // currently running activity.  This is a little tricky because
4118            // we want to start the new one as if the current one is finished,
4119            // but not finish the current one first so that there is no flicker.
4120            // And thus...
4121            final boolean wasFinishing = r.finishing;
4122            r.finishing = true;
4123
4124            // Propagate reply information over to the new activity.
4125            final ActivityRecord resultTo = r.resultTo;
4126            final String resultWho = r.resultWho;
4127            final int requestCode = r.requestCode;
4128            r.resultTo = null;
4129            if (resultTo != null) {
4130                resultTo.removeResultsLocked(r, resultWho, requestCode);
4131            }
4132
4133            final long origId = Binder.clearCallingIdentity();
4134            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4135                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4136                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4137                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4138            Binder.restoreCallingIdentity(origId);
4139
4140            r.finishing = wasFinishing;
4141            if (res != ActivityManager.START_SUCCESS) {
4142                return false;
4143            }
4144            return true;
4145        }
4146    }
4147
4148    @Override
4149    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle options) {
4150        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4151            String msg = "Permission Denial: startActivityFromRecents called without " +
4152                    START_TASKS_FROM_RECENTS;
4153            Slog.w(TAG, msg);
4154            throw new SecurityException(msg);
4155        }
4156        final long origId = Binder.clearCallingIdentity();
4157        try {
4158            return startActivityFromRecentsInner(taskId, launchStackId, options);
4159        } finally {
4160            Binder.restoreCallingIdentity(origId);
4161        }
4162    }
4163
4164    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle options) {
4165        final TaskRecord task;
4166        final int callingUid;
4167        final String callingPackage;
4168        final Intent intent;
4169        final int userId;
4170        synchronized (this) {
4171            if (launchStackId == HOME_STACK_ID) {
4172                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4173                        + taskId + " can't be launch in the home stack.");
4174            }
4175
4176            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4177            if (task == null) {
4178                throw new IllegalArgumentException(
4179                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4180            }
4181
4182            if (launchStackId != INVALID_STACK_ID && task.stack.mStackId != launchStackId) {
4183                if (launchStackId == DOCKED_STACK_ID && options != null) {
4184                    ActivityOptions activityOptions = new ActivityOptions(options);
4185                    mWindowManager.setDockedStackCreateMode(activityOptions.getDockCreateMode());
4186                }
4187                mStackSupervisor.moveTaskToStackLocked(
4188                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents");
4189            }
4190
4191            if (task.getRootActivity() != null) {
4192                moveTaskToFrontLocked(task.taskId, 0, options);
4193                return ActivityManager.START_TASK_TO_FRONT;
4194            }
4195            callingUid = task.mCallingUid;
4196            callingPackage = task.mCallingPackage;
4197            intent = task.intent;
4198            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4199            userId = task.userId;
4200        }
4201        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4202                options, userId, null, task);
4203    }
4204
4205    final int startActivityInPackage(int uid, String callingPackage,
4206            Intent intent, String resolvedType, IBinder resultTo,
4207            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4208            IActivityContainer container, TaskRecord inTask) {
4209
4210        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4211                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4212
4213        // TODO: Switch to user app stacks here.
4214        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4215                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4216                null, null, null, options, false, userId, container, inTask);
4217        return ret;
4218    }
4219
4220    @Override
4221    public final int startActivities(IApplicationThread caller, String callingPackage,
4222            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4223            int userId) {
4224        enforceNotIsolatedCaller("startActivities");
4225        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4226                false, ALLOW_FULL_ONLY, "startActivity", null);
4227        // TODO: Switch to user app stacks here.
4228        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4229                resolvedTypes, resultTo, options, userId);
4230        return ret;
4231    }
4232
4233    final int startActivitiesInPackage(int uid, String callingPackage,
4234            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4235            Bundle options, int userId) {
4236
4237        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4238                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4239        // TODO: Switch to user app stacks here.
4240        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4241                resultTo, options, userId);
4242        return ret;
4243    }
4244
4245    @Override
4246    public void reportActivityFullyDrawn(IBinder token) {
4247        synchronized (this) {
4248            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4249            if (r == null) {
4250                return;
4251            }
4252            r.reportFullyDrawnLocked();
4253        }
4254    }
4255
4256    @Override
4257    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4258        synchronized (this) {
4259            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4260            if (r == null) {
4261                return;
4262            }
4263            if (r.task != null && r.task.mResizeable) {
4264                // Fixed screen orientation isn't supported with resizeable activities.
4265                return;
4266            }
4267            final long origId = Binder.clearCallingIdentity();
4268            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4269            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4270                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4271            if (config != null) {
4272                r.frozenBeforeDestroy = true;
4273                if (!updateConfigurationLocked(config, r, false)) {
4274                    mStackSupervisor.resumeTopActivitiesLocked();
4275                }
4276            }
4277            Binder.restoreCallingIdentity(origId);
4278        }
4279    }
4280
4281    @Override
4282    public int getRequestedOrientation(IBinder token) {
4283        synchronized (this) {
4284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4285            if (r == null) {
4286                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4287            }
4288            return mWindowManager.getAppOrientation(r.appToken);
4289        }
4290    }
4291
4292    /**
4293     * This is the internal entry point for handling Activity.finish().
4294     *
4295     * @param token The Binder token referencing the Activity we want to finish.
4296     * @param resultCode Result code, if any, from this Activity.
4297     * @param resultData Result data (Intent), if any, from this Activity.
4298     * @param finishTask Whether to finish the task associated with this Activity.
4299     *
4300     * @return Returns true if the activity successfully finished, or false if it is still running.
4301     */
4302    @Override
4303    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4304            int finishTask) {
4305        // Refuse possible leaked file descriptors
4306        if (resultData != null && resultData.hasFileDescriptors() == true) {
4307            throw new IllegalArgumentException("File descriptors passed in Intent");
4308        }
4309
4310        synchronized(this) {
4311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4312            if (r == null) {
4313                return true;
4314            }
4315            // Keep track of the root activity of the task before we finish it
4316            TaskRecord tr = r.task;
4317            ActivityRecord rootR = tr.getRootActivity();
4318            if (rootR == null) {
4319                Slog.w(TAG, "Finishing task with all activities already finished");
4320            }
4321            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4322            // finish.
4323            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4324                    mStackSupervisor.isLastLockedTask(tr)) {
4325                Slog.i(TAG, "Not finishing task in lock task mode");
4326                mStackSupervisor.showLockTaskToast();
4327                return false;
4328            }
4329            if (mController != null) {
4330                // Find the first activity that is not finishing.
4331                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4332                if (next != null) {
4333                    // ask watcher if this is allowed
4334                    boolean resumeOK = true;
4335                    try {
4336                        resumeOK = mController.activityResuming(next.packageName);
4337                    } catch (RemoteException e) {
4338                        mController = null;
4339                        Watchdog.getInstance().setActivityController(null);
4340                    }
4341
4342                    if (!resumeOK) {
4343                        Slog.i(TAG, "Not finishing activity because controller resumed");
4344                        return false;
4345                    }
4346                }
4347            }
4348            final long origId = Binder.clearCallingIdentity();
4349            try {
4350                boolean res;
4351                final boolean finishWithRootActivity =
4352                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4353                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4354                        || (finishWithRootActivity && r == rootR)) {
4355                    // If requested, remove the task that is associated to this activity only if it
4356                    // was the root activity in the task. The result code and data is ignored
4357                    // because we don't support returning them across task boundaries. Also, to
4358                    // keep backwards compatibility we remove the task from recents when finishing
4359                    // task with root activity.
4360                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4361                    if (!res) {
4362                        Slog.i(TAG, "Removing task failed to finish activity");
4363                    }
4364                } else {
4365                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4366                            resultData, "app-request", true);
4367                    if (!res) {
4368                        Slog.i(TAG, "Failed to finish by app-request");
4369                    }
4370                }
4371                return res;
4372            } finally {
4373                Binder.restoreCallingIdentity(origId);
4374            }
4375        }
4376    }
4377
4378    @Override
4379    public final void finishHeavyWeightApp() {
4380        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4381                != PackageManager.PERMISSION_GRANTED) {
4382            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4383                    + Binder.getCallingPid()
4384                    + ", uid=" + Binder.getCallingUid()
4385                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4386            Slog.w(TAG, msg);
4387            throw new SecurityException(msg);
4388        }
4389
4390        synchronized(this) {
4391            if (mHeavyWeightProcess == null) {
4392                return;
4393            }
4394
4395            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4396            for (int i = 0; i < activities.size(); i++) {
4397                ActivityRecord r = activities.get(i);
4398                if (!r.finishing && r.isInStackLocked()) {
4399                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4400                            null, "finish-heavy", true);
4401                }
4402            }
4403
4404            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4405                    mHeavyWeightProcess.userId, 0));
4406            mHeavyWeightProcess = null;
4407        }
4408    }
4409
4410    @Override
4411    public void crashApplication(int uid, int initialPid, String packageName,
4412            String message) {
4413        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4414                != PackageManager.PERMISSION_GRANTED) {
4415            String msg = "Permission Denial: crashApplication() from pid="
4416                    + Binder.getCallingPid()
4417                    + ", uid=" + Binder.getCallingUid()
4418                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4419            Slog.w(TAG, msg);
4420            throw new SecurityException(msg);
4421        }
4422
4423        synchronized(this) {
4424            ProcessRecord proc = null;
4425
4426            // Figure out which process to kill.  We don't trust that initialPid
4427            // still has any relation to current pids, so must scan through the
4428            // list.
4429            synchronized (mPidsSelfLocked) {
4430                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4431                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4432                    if (p.uid != uid) {
4433                        continue;
4434                    }
4435                    if (p.pid == initialPid) {
4436                        proc = p;
4437                        break;
4438                    }
4439                    if (p.pkgList.containsKey(packageName)) {
4440                        proc = p;
4441                    }
4442                }
4443            }
4444
4445            if (proc == null) {
4446                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4447                        + " initialPid=" + initialPid
4448                        + " packageName=" + packageName);
4449                return;
4450            }
4451
4452            if (proc.thread != null) {
4453                if (proc.pid == Process.myPid()) {
4454                    Log.w(TAG, "crashApplication: trying to crash self!");
4455                    return;
4456                }
4457                long ident = Binder.clearCallingIdentity();
4458                try {
4459                    proc.thread.scheduleCrash(message);
4460                } catch (RemoteException e) {
4461                }
4462                Binder.restoreCallingIdentity(ident);
4463            }
4464        }
4465    }
4466
4467    @Override
4468    public final void finishSubActivity(IBinder token, String resultWho,
4469            int requestCode) {
4470        synchronized(this) {
4471            final long origId = Binder.clearCallingIdentity();
4472            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4473            if (r != null) {
4474                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4475            }
4476            Binder.restoreCallingIdentity(origId);
4477        }
4478    }
4479
4480    @Override
4481    public boolean finishActivityAffinity(IBinder token) {
4482        synchronized(this) {
4483            final long origId = Binder.clearCallingIdentity();
4484            try {
4485                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4486                if (r == null) {
4487                    return false;
4488                }
4489
4490                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4491                // can finish.
4492                final TaskRecord task = r.task;
4493                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4494                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4495                    mStackSupervisor.showLockTaskToast();
4496                    return false;
4497                }
4498                return task.stack.finishActivityAffinityLocked(r);
4499            } finally {
4500                Binder.restoreCallingIdentity(origId);
4501            }
4502        }
4503    }
4504
4505    @Override
4506    public void finishVoiceTask(IVoiceInteractionSession session) {
4507        synchronized(this) {
4508            final long origId = Binder.clearCallingIdentity();
4509            try {
4510                mStackSupervisor.finishVoiceTask(session);
4511            } finally {
4512                Binder.restoreCallingIdentity(origId);
4513            }
4514        }
4515
4516    }
4517
4518    @Override
4519    public boolean releaseActivityInstance(IBinder token) {
4520        synchronized(this) {
4521            final long origId = Binder.clearCallingIdentity();
4522            try {
4523                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4524                if (r == null) {
4525                    return false;
4526                }
4527                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4528            } finally {
4529                Binder.restoreCallingIdentity(origId);
4530            }
4531        }
4532    }
4533
4534    @Override
4535    public void releaseSomeActivities(IApplicationThread appInt) {
4536        synchronized(this) {
4537            final long origId = Binder.clearCallingIdentity();
4538            try {
4539                ProcessRecord app = getRecordForAppLocked(appInt);
4540                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4541            } finally {
4542                Binder.restoreCallingIdentity(origId);
4543            }
4544        }
4545    }
4546
4547    @Override
4548    public boolean willActivityBeVisible(IBinder token) {
4549        synchronized(this) {
4550            ActivityStack stack = ActivityRecord.getStackLocked(token);
4551            if (stack != null) {
4552                return stack.willActivityBeVisibleLocked(token);
4553            }
4554            return false;
4555        }
4556    }
4557
4558    @Override
4559    public void overridePendingTransition(IBinder token, String packageName,
4560            int enterAnim, int exitAnim) {
4561        synchronized(this) {
4562            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4563            if (self == null) {
4564                return;
4565            }
4566
4567            final long origId = Binder.clearCallingIdentity();
4568
4569            if (self.state == ActivityState.RESUMED
4570                    || self.state == ActivityState.PAUSING) {
4571                mWindowManager.overridePendingAppTransition(packageName,
4572                        enterAnim, exitAnim, null);
4573            }
4574
4575            Binder.restoreCallingIdentity(origId);
4576        }
4577    }
4578
4579    /**
4580     * Main function for removing an existing process from the activity manager
4581     * as a result of that process going away.  Clears out all connections
4582     * to the process.
4583     */
4584    private final void handleAppDiedLocked(ProcessRecord app,
4585            boolean restarting, boolean allowRestart) {
4586        int pid = app.pid;
4587        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4588        if (!kept && !restarting) {
4589            removeLruProcessLocked(app);
4590            if (pid > 0) {
4591                ProcessList.remove(pid);
4592            }
4593        }
4594
4595        if (mProfileProc == app) {
4596            clearProfilerLocked();
4597        }
4598
4599        // Remove this application's activities from active lists.
4600        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4601
4602        app.activities.clear();
4603
4604        if (app.instrumentationClass != null) {
4605            Slog.w(TAG, "Crash of app " + app.processName
4606                  + " running instrumentation " + app.instrumentationClass);
4607            Bundle info = new Bundle();
4608            info.putString("shortMsg", "Process crashed.");
4609            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4610        }
4611
4612        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4613            // If there was nothing to resume, and we are not already
4614            // restarting this process, but there is a visible activity that
4615            // is hosted by the process...  then make sure all visible
4616            // activities are running, taking care of restarting this
4617            // process.
4618            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4619        }
4620    }
4621
4622    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4623        IBinder threadBinder = thread.asBinder();
4624        // Find the application record.
4625        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4626            ProcessRecord rec = mLruProcesses.get(i);
4627            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4628                return i;
4629            }
4630        }
4631        return -1;
4632    }
4633
4634    final ProcessRecord getRecordForAppLocked(
4635            IApplicationThread thread) {
4636        if (thread == null) {
4637            return null;
4638        }
4639
4640        int appIndex = getLRURecordIndexForAppLocked(thread);
4641        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4642    }
4643
4644    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4645        // If there are no longer any background processes running,
4646        // and the app that died was not running instrumentation,
4647        // then tell everyone we are now low on memory.
4648        boolean haveBg = false;
4649        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4650            ProcessRecord rec = mLruProcesses.get(i);
4651            if (rec.thread != null
4652                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4653                haveBg = true;
4654                break;
4655            }
4656        }
4657
4658        if (!haveBg) {
4659            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4660            if (doReport) {
4661                long now = SystemClock.uptimeMillis();
4662                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4663                    doReport = false;
4664                } else {
4665                    mLastMemUsageReportTime = now;
4666                }
4667            }
4668            final ArrayList<ProcessMemInfo> memInfos
4669                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4670            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4671            long now = SystemClock.uptimeMillis();
4672            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4673                ProcessRecord rec = mLruProcesses.get(i);
4674                if (rec == dyingProc || rec.thread == null) {
4675                    continue;
4676                }
4677                if (doReport) {
4678                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4679                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4680                }
4681                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4682                    // The low memory report is overriding any current
4683                    // state for a GC request.  Make sure to do
4684                    // heavy/important/visible/foreground processes first.
4685                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4686                        rec.lastRequestedGc = 0;
4687                    } else {
4688                        rec.lastRequestedGc = rec.lastLowMemory;
4689                    }
4690                    rec.reportLowMemory = true;
4691                    rec.lastLowMemory = now;
4692                    mProcessesToGc.remove(rec);
4693                    addProcessToGcListLocked(rec);
4694                }
4695            }
4696            if (doReport) {
4697                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4698                mHandler.sendMessage(msg);
4699            }
4700            scheduleAppGcsLocked();
4701        }
4702    }
4703
4704    final void appDiedLocked(ProcessRecord app) {
4705       appDiedLocked(app, app.pid, app.thread, false);
4706    }
4707
4708    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4709            boolean fromBinderDied) {
4710        // First check if this ProcessRecord is actually active for the pid.
4711        synchronized (mPidsSelfLocked) {
4712            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4713            if (curProc != app) {
4714                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4715                return;
4716            }
4717        }
4718
4719        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4720        synchronized (stats) {
4721            stats.noteProcessDiedLocked(app.info.uid, pid);
4722        }
4723
4724        if (!app.killed) {
4725            if (!fromBinderDied) {
4726                Process.killProcessQuiet(pid);
4727            }
4728            killProcessGroup(app.info.uid, pid);
4729            app.killed = true;
4730        }
4731
4732        // Clean up already done if the process has been re-started.
4733        if (app.pid == pid && app.thread != null &&
4734                app.thread.asBinder() == thread.asBinder()) {
4735            boolean doLowMem = app.instrumentationClass == null;
4736            boolean doOomAdj = doLowMem;
4737            if (!app.killedByAm) {
4738                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4739                        + ") has died");
4740                mAllowLowerMemLevel = true;
4741            } else {
4742                // Note that we always want to do oom adj to update our state with the
4743                // new number of procs.
4744                mAllowLowerMemLevel = false;
4745                doLowMem = false;
4746            }
4747            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4748            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4749                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4750            handleAppDiedLocked(app, false, true);
4751
4752            if (doOomAdj) {
4753                updateOomAdjLocked();
4754            }
4755            if (doLowMem) {
4756                doLowMemReportIfNeededLocked(app);
4757            }
4758        } else if (app.pid != pid) {
4759            // A new process has already been started.
4760            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4761                    + ") has died and restarted (pid " + app.pid + ").");
4762            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4763        } else if (DEBUG_PROCESSES) {
4764            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4765                    + thread.asBinder());
4766        }
4767    }
4768
4769    /**
4770     * If a stack trace dump file is configured, dump process stack traces.
4771     * @param clearTraces causes the dump file to be erased prior to the new
4772     *    traces being written, if true; when false, the new traces will be
4773     *    appended to any existing file content.
4774     * @param firstPids of dalvik VM processes to dump stack traces for first
4775     * @param lastPids of dalvik VM processes to dump stack traces for last
4776     * @param nativeProcs optional list of native process names to dump stack crawls
4777     * @return file containing stack traces, or null if no dump file is configured
4778     */
4779    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4780            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4781        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4782        if (tracesPath == null || tracesPath.length() == 0) {
4783            return null;
4784        }
4785
4786        File tracesFile = new File(tracesPath);
4787        try {
4788            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4789            tracesFile.createNewFile();
4790            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4791        } catch (IOException e) {
4792            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4793            return null;
4794        }
4795
4796        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4797        return tracesFile;
4798    }
4799
4800    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4801            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4802        // Use a FileObserver to detect when traces finish writing.
4803        // The order of traces is considered important to maintain for legibility.
4804        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4805            @Override
4806            public synchronized void onEvent(int event, String path) { notify(); }
4807        };
4808
4809        try {
4810            observer.startWatching();
4811
4812            // First collect all of the stacks of the most important pids.
4813            if (firstPids != null) {
4814                try {
4815                    int num = firstPids.size();
4816                    for (int i = 0; i < num; i++) {
4817                        synchronized (observer) {
4818                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4819                            observer.wait(200);  // Wait for write-close, give up after 200msec
4820                        }
4821                    }
4822                } catch (InterruptedException e) {
4823                    Slog.wtf(TAG, e);
4824                }
4825            }
4826
4827            // Next collect the stacks of the native pids
4828            if (nativeProcs != null) {
4829                int[] pids = Process.getPidsForCommands(nativeProcs);
4830                if (pids != null) {
4831                    for (int pid : pids) {
4832                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4833                    }
4834                }
4835            }
4836
4837            // Lastly, measure CPU usage.
4838            if (processCpuTracker != null) {
4839                processCpuTracker.init();
4840                System.gc();
4841                processCpuTracker.update();
4842                try {
4843                    synchronized (processCpuTracker) {
4844                        processCpuTracker.wait(500); // measure over 1/2 second.
4845                    }
4846                } catch (InterruptedException e) {
4847                }
4848                processCpuTracker.update();
4849
4850                // We'll take the stack crawls of just the top apps using CPU.
4851                final int N = processCpuTracker.countWorkingStats();
4852                int numProcs = 0;
4853                for (int i=0; i<N && numProcs<5; i++) {
4854                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4855                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4856                        numProcs++;
4857                        try {
4858                            synchronized (observer) {
4859                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4860                                observer.wait(200);  // Wait for write-close, give up after 200msec
4861                            }
4862                        } catch (InterruptedException e) {
4863                            Slog.wtf(TAG, e);
4864                        }
4865
4866                    }
4867                }
4868            }
4869        } finally {
4870            observer.stopWatching();
4871        }
4872    }
4873
4874    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4875        if (true || IS_USER_BUILD) {
4876            return;
4877        }
4878        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4879        if (tracesPath == null || tracesPath.length() == 0) {
4880            return;
4881        }
4882
4883        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4884        StrictMode.allowThreadDiskWrites();
4885        try {
4886            final File tracesFile = new File(tracesPath);
4887            final File tracesDir = tracesFile.getParentFile();
4888            final File tracesTmp = new File(tracesDir, "__tmp__");
4889            try {
4890                if (tracesFile.exists()) {
4891                    tracesTmp.delete();
4892                    tracesFile.renameTo(tracesTmp);
4893                }
4894                StringBuilder sb = new StringBuilder();
4895                Time tobj = new Time();
4896                tobj.set(System.currentTimeMillis());
4897                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4898                sb.append(": ");
4899                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4900                sb.append(" since ");
4901                sb.append(msg);
4902                FileOutputStream fos = new FileOutputStream(tracesFile);
4903                fos.write(sb.toString().getBytes());
4904                if (app == null) {
4905                    fos.write("\n*** No application process!".getBytes());
4906                }
4907                fos.close();
4908                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4909            } catch (IOException e) {
4910                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4911                return;
4912            }
4913
4914            if (app != null) {
4915                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4916                firstPids.add(app.pid);
4917                dumpStackTraces(tracesPath, firstPids, null, null, null);
4918            }
4919
4920            File lastTracesFile = null;
4921            File curTracesFile = null;
4922            for (int i=9; i>=0; i--) {
4923                String name = String.format(Locale.US, "slow%02d.txt", i);
4924                curTracesFile = new File(tracesDir, name);
4925                if (curTracesFile.exists()) {
4926                    if (lastTracesFile != null) {
4927                        curTracesFile.renameTo(lastTracesFile);
4928                    } else {
4929                        curTracesFile.delete();
4930                    }
4931                }
4932                lastTracesFile = curTracesFile;
4933            }
4934            tracesFile.renameTo(curTracesFile);
4935            if (tracesTmp.exists()) {
4936                tracesTmp.renameTo(tracesFile);
4937            }
4938        } finally {
4939            StrictMode.setThreadPolicy(oldPolicy);
4940        }
4941    }
4942
4943    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4944            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4945        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4946        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4947
4948        if (mController != null) {
4949            try {
4950                // 0 == continue, -1 = kill process immediately
4951                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4952                if (res < 0 && app.pid != MY_PID) {
4953                    app.kill("anr", true);
4954                }
4955            } catch (RemoteException e) {
4956                mController = null;
4957                Watchdog.getInstance().setActivityController(null);
4958            }
4959        }
4960
4961        long anrTime = SystemClock.uptimeMillis();
4962        if (MONITOR_CPU_USAGE) {
4963            updateCpuStatsNow();
4964        }
4965
4966        synchronized (this) {
4967            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4968            if (mShuttingDown) {
4969                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4970                return;
4971            } else if (app.notResponding) {
4972                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4973                return;
4974            } else if (app.crashing) {
4975                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4976                return;
4977            }
4978
4979            // In case we come through here for the same app before completing
4980            // this one, mark as anring now so we will bail out.
4981            app.notResponding = true;
4982
4983            // Log the ANR to the event log.
4984            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4985                    app.processName, app.info.flags, annotation);
4986
4987            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4988            firstPids.add(app.pid);
4989
4990            int parentPid = app.pid;
4991            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4992            if (parentPid != app.pid) firstPids.add(parentPid);
4993
4994            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4995
4996            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4997                ProcessRecord r = mLruProcesses.get(i);
4998                if (r != null && r.thread != null) {
4999                    int pid = r.pid;
5000                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5001                        if (r.persistent) {
5002                            firstPids.add(pid);
5003                        } else {
5004                            lastPids.put(pid, Boolean.TRUE);
5005                        }
5006                    }
5007                }
5008            }
5009        }
5010
5011        // Log the ANR to the main log.
5012        StringBuilder info = new StringBuilder();
5013        info.setLength(0);
5014        info.append("ANR in ").append(app.processName);
5015        if (activity != null && activity.shortComponentName != null) {
5016            info.append(" (").append(activity.shortComponentName).append(")");
5017        }
5018        info.append("\n");
5019        info.append("PID: ").append(app.pid).append("\n");
5020        if (annotation != null) {
5021            info.append("Reason: ").append(annotation).append("\n");
5022        }
5023        if (parent != null && parent != activity) {
5024            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5025        }
5026
5027        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5028
5029        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5030                NATIVE_STACKS_OF_INTEREST);
5031
5032        String cpuInfo = null;
5033        if (MONITOR_CPU_USAGE) {
5034            updateCpuStatsNow();
5035            synchronized (mProcessCpuTracker) {
5036                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5037            }
5038            info.append(processCpuTracker.printCurrentLoad());
5039            info.append(cpuInfo);
5040        }
5041
5042        info.append(processCpuTracker.printCurrentState(anrTime));
5043
5044        Slog.e(TAG, info.toString());
5045        if (tracesFile == null) {
5046            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5047            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5048        }
5049
5050        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5051                cpuInfo, tracesFile, null);
5052
5053        if (mController != null) {
5054            try {
5055                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5056                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5057                if (res != 0) {
5058                    if (res < 0 && app.pid != MY_PID) {
5059                        app.kill("anr", true);
5060                    } else {
5061                        synchronized (this) {
5062                            mServices.scheduleServiceTimeoutLocked(app);
5063                        }
5064                    }
5065                    return;
5066                }
5067            } catch (RemoteException e) {
5068                mController = null;
5069                Watchdog.getInstance().setActivityController(null);
5070            }
5071        }
5072
5073        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5074        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5075                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5076
5077        synchronized (this) {
5078            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5079
5080            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5081                app.kill("bg anr", true);
5082                return;
5083            }
5084
5085            // Set the app's notResponding state, and look up the errorReportReceiver
5086            makeAppNotRespondingLocked(app,
5087                    activity != null ? activity.shortComponentName : null,
5088                    annotation != null ? "ANR " + annotation : "ANR",
5089                    info.toString());
5090
5091            // Bring up the infamous App Not Responding dialog
5092            Message msg = Message.obtain();
5093            HashMap<String, Object> map = new HashMap<String, Object>();
5094            msg.what = SHOW_NOT_RESPONDING_MSG;
5095            msg.obj = map;
5096            msg.arg1 = aboveSystem ? 1 : 0;
5097            map.put("app", app);
5098            if (activity != null) {
5099                map.put("activity", activity);
5100            }
5101
5102            mUiHandler.sendMessage(msg);
5103        }
5104    }
5105
5106    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5107        if (!mLaunchWarningShown) {
5108            mLaunchWarningShown = true;
5109            mUiHandler.post(new Runnable() {
5110                @Override
5111                public void run() {
5112                    synchronized (ActivityManagerService.this) {
5113                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5114                        d.show();
5115                        mUiHandler.postDelayed(new Runnable() {
5116                            @Override
5117                            public void run() {
5118                                synchronized (ActivityManagerService.this) {
5119                                    d.dismiss();
5120                                    mLaunchWarningShown = false;
5121                                }
5122                            }
5123                        }, 4000);
5124                    }
5125                }
5126            });
5127        }
5128    }
5129
5130    @Override
5131    public boolean clearApplicationUserData(final String packageName,
5132            final IPackageDataObserver observer, int userId) {
5133        enforceNotIsolatedCaller("clearApplicationUserData");
5134        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5135            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5136        }
5137        int uid = Binder.getCallingUid();
5138        int pid = Binder.getCallingPid();
5139        userId = handleIncomingUser(pid, uid,
5140                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5141        long callingId = Binder.clearCallingIdentity();
5142        try {
5143            IPackageManager pm = AppGlobals.getPackageManager();
5144            int pkgUid = -1;
5145            synchronized(this) {
5146                try {
5147                    pkgUid = pm.getPackageUid(packageName, userId);
5148                } catch (RemoteException e) {
5149                }
5150                if (pkgUid == -1) {
5151                    Slog.w(TAG, "Invalid packageName: " + packageName);
5152                    if (observer != null) {
5153                        try {
5154                            observer.onRemoveCompleted(packageName, false);
5155                        } catch (RemoteException e) {
5156                            Slog.i(TAG, "Observer no longer exists.");
5157                        }
5158                    }
5159                    return false;
5160                }
5161                if (uid == pkgUid || checkComponentPermission(
5162                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5163                        pid, uid, -1, true)
5164                        == PackageManager.PERMISSION_GRANTED) {
5165                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5166                } else {
5167                    throw new SecurityException("PID " + pid + " does not have permission "
5168                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5169                                    + " of package " + packageName);
5170                }
5171
5172                // Remove all tasks match the cleared application package and user
5173                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5174                    final TaskRecord tr = mRecentTasks.get(i);
5175                    final String taskPackageName =
5176                            tr.getBaseIntent().getComponent().getPackageName();
5177                    if (tr.userId != userId) continue;
5178                    if (!taskPackageName.equals(packageName)) continue;
5179                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5180                }
5181            }
5182
5183            try {
5184                // Clear application user data
5185                pm.clearApplicationUserData(packageName, observer, userId);
5186
5187                synchronized(this) {
5188                    // Remove all permissions granted from/to this package
5189                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5190                }
5191
5192                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5193                        Uri.fromParts("package", packageName, null));
5194                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5195                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5196                        null, null, 0, null, null, null, null, false, false, userId);
5197            } catch (RemoteException e) {
5198            }
5199        } finally {
5200            Binder.restoreCallingIdentity(callingId);
5201        }
5202        return true;
5203    }
5204
5205    @Override
5206    public void killBackgroundProcesses(final String packageName, int userId) {
5207        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5208                != PackageManager.PERMISSION_GRANTED &&
5209                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5210                        != PackageManager.PERMISSION_GRANTED) {
5211            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5212                    + Binder.getCallingPid()
5213                    + ", uid=" + Binder.getCallingUid()
5214                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5215            Slog.w(TAG, msg);
5216            throw new SecurityException(msg);
5217        }
5218
5219        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5220                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5221        long callingId = Binder.clearCallingIdentity();
5222        try {
5223            IPackageManager pm = AppGlobals.getPackageManager();
5224            synchronized(this) {
5225                int appId = -1;
5226                try {
5227                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5228                } catch (RemoteException e) {
5229                }
5230                if (appId == -1) {
5231                    Slog.w(TAG, "Invalid packageName: " + packageName);
5232                    return;
5233                }
5234                killPackageProcessesLocked(packageName, appId, userId,
5235                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5236            }
5237        } finally {
5238            Binder.restoreCallingIdentity(callingId);
5239        }
5240    }
5241
5242    @Override
5243    public void killAllBackgroundProcesses() {
5244        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5245                != PackageManager.PERMISSION_GRANTED) {
5246            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5247                    + Binder.getCallingPid()
5248                    + ", uid=" + Binder.getCallingUid()
5249                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5250            Slog.w(TAG, msg);
5251            throw new SecurityException(msg);
5252        }
5253
5254        long callingId = Binder.clearCallingIdentity();
5255        try {
5256            synchronized(this) {
5257                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5258                final int NP = mProcessNames.getMap().size();
5259                for (int ip=0; ip<NP; ip++) {
5260                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5261                    final int NA = apps.size();
5262                    for (int ia=0; ia<NA; ia++) {
5263                        ProcessRecord app = apps.valueAt(ia);
5264                        if (app.persistent) {
5265                            // we don't kill persistent processes
5266                            continue;
5267                        }
5268                        if (app.removed) {
5269                            procs.add(app);
5270                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5271                            app.removed = true;
5272                            procs.add(app);
5273                        }
5274                    }
5275                }
5276
5277                int N = procs.size();
5278                for (int i=0; i<N; i++) {
5279                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5280                }
5281                mAllowLowerMemLevel = true;
5282                updateOomAdjLocked();
5283                doLowMemReportIfNeededLocked(null);
5284            }
5285        } finally {
5286            Binder.restoreCallingIdentity(callingId);
5287        }
5288    }
5289
5290    @Override
5291    public void forceStopPackage(final String packageName, int userId) {
5292        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5293                != PackageManager.PERMISSION_GRANTED) {
5294            String msg = "Permission Denial: forceStopPackage() from pid="
5295                    + Binder.getCallingPid()
5296                    + ", uid=" + Binder.getCallingUid()
5297                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5298            Slog.w(TAG, msg);
5299            throw new SecurityException(msg);
5300        }
5301        final int callingPid = Binder.getCallingPid();
5302        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5303                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5304        long callingId = Binder.clearCallingIdentity();
5305        try {
5306            IPackageManager pm = AppGlobals.getPackageManager();
5307            synchronized(this) {
5308                int[] users = userId == UserHandle.USER_ALL
5309                        ? getUsersLocked() : new int[] { userId };
5310                for (int user : users) {
5311                    int pkgUid = -1;
5312                    try {
5313                        pkgUid = pm.getPackageUid(packageName, user);
5314                    } catch (RemoteException e) {
5315                    }
5316                    if (pkgUid == -1) {
5317                        Slog.w(TAG, "Invalid packageName: " + packageName);
5318                        continue;
5319                    }
5320                    try {
5321                        pm.setPackageStoppedState(packageName, true, user);
5322                    } catch (RemoteException e) {
5323                    } catch (IllegalArgumentException e) {
5324                        Slog.w(TAG, "Failed trying to unstop package "
5325                                + packageName + ": " + e);
5326                    }
5327                    if (isUserRunningLocked(user, false)) {
5328                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5329                    }
5330                }
5331            }
5332        } finally {
5333            Binder.restoreCallingIdentity(callingId);
5334        }
5335    }
5336
5337    @Override
5338    public void addPackageDependency(String packageName) {
5339        synchronized (this) {
5340            int callingPid = Binder.getCallingPid();
5341            if (callingPid == Process.myPid()) {
5342                //  Yeah, um, no.
5343                return;
5344            }
5345            ProcessRecord proc;
5346            synchronized (mPidsSelfLocked) {
5347                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5348            }
5349            if (proc != null) {
5350                if (proc.pkgDeps == null) {
5351                    proc.pkgDeps = new ArraySet<String>(1);
5352                }
5353                proc.pkgDeps.add(packageName);
5354            }
5355        }
5356    }
5357
5358    /*
5359     * The pkg name and app id have to be specified.
5360     */
5361    @Override
5362    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5363        if (pkg == null) {
5364            return;
5365        }
5366        // Make sure the uid is valid.
5367        if (appid < 0) {
5368            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5369            return;
5370        }
5371        int callerUid = Binder.getCallingUid();
5372        // Only the system server can kill an application
5373        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5374            // Post an aysnc message to kill the application
5375            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5376            msg.arg1 = appid;
5377            msg.arg2 = 0;
5378            Bundle bundle = new Bundle();
5379            bundle.putString("pkg", pkg);
5380            bundle.putString("reason", reason);
5381            msg.obj = bundle;
5382            mHandler.sendMessage(msg);
5383        } else {
5384            throw new SecurityException(callerUid + " cannot kill pkg: " +
5385                    pkg);
5386        }
5387    }
5388
5389    @Override
5390    public void closeSystemDialogs(String reason) {
5391        enforceNotIsolatedCaller("closeSystemDialogs");
5392
5393        final int pid = Binder.getCallingPid();
5394        final int uid = Binder.getCallingUid();
5395        final long origId = Binder.clearCallingIdentity();
5396        try {
5397            synchronized (this) {
5398                // Only allow this from foreground processes, so that background
5399                // applications can't abuse it to prevent system UI from being shown.
5400                if (uid >= Process.FIRST_APPLICATION_UID) {
5401                    ProcessRecord proc;
5402                    synchronized (mPidsSelfLocked) {
5403                        proc = mPidsSelfLocked.get(pid);
5404                    }
5405                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5406                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5407                                + " from background process " + proc);
5408                        return;
5409                    }
5410                }
5411                closeSystemDialogsLocked(reason);
5412            }
5413        } finally {
5414            Binder.restoreCallingIdentity(origId);
5415        }
5416    }
5417
5418    void closeSystemDialogsLocked(String reason) {
5419        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5420        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5421                | Intent.FLAG_RECEIVER_FOREGROUND);
5422        if (reason != null) {
5423            intent.putExtra("reason", reason);
5424        }
5425        mWindowManager.closeSystemDialogs(reason);
5426
5427        mStackSupervisor.closeSystemDialogsLocked();
5428
5429        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5430                AppOpsManager.OP_NONE, null, false, false,
5431                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5432    }
5433
5434    @Override
5435    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5436        enforceNotIsolatedCaller("getProcessMemoryInfo");
5437        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5438        for (int i=pids.length-1; i>=0; i--) {
5439            ProcessRecord proc;
5440            int oomAdj;
5441            synchronized (this) {
5442                synchronized (mPidsSelfLocked) {
5443                    proc = mPidsSelfLocked.get(pids[i]);
5444                    oomAdj = proc != null ? proc.setAdj : 0;
5445                }
5446            }
5447            infos[i] = new Debug.MemoryInfo();
5448            Debug.getMemoryInfo(pids[i], infos[i]);
5449            if (proc != null) {
5450                synchronized (this) {
5451                    if (proc.thread != null && proc.setAdj == oomAdj) {
5452                        // Record this for posterity if the process has been stable.
5453                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5454                                infos[i].getTotalUss(), false, proc.pkgList);
5455                    }
5456                }
5457            }
5458        }
5459        return infos;
5460    }
5461
5462    @Override
5463    public long[] getProcessPss(int[] pids) {
5464        enforceNotIsolatedCaller("getProcessPss");
5465        long[] pss = new long[pids.length];
5466        for (int i=pids.length-1; i>=0; i--) {
5467            ProcessRecord proc;
5468            int oomAdj;
5469            synchronized (this) {
5470                synchronized (mPidsSelfLocked) {
5471                    proc = mPidsSelfLocked.get(pids[i]);
5472                    oomAdj = proc != null ? proc.setAdj : 0;
5473                }
5474            }
5475            long[] tmpUss = new long[1];
5476            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5477            if (proc != null) {
5478                synchronized (this) {
5479                    if (proc.thread != null && proc.setAdj == oomAdj) {
5480                        // Record this for posterity if the process has been stable.
5481                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5482                    }
5483                }
5484            }
5485        }
5486        return pss;
5487    }
5488
5489    @Override
5490    public void killApplicationProcess(String processName, int uid) {
5491        if (processName == null) {
5492            return;
5493        }
5494
5495        int callerUid = Binder.getCallingUid();
5496        // Only the system server can kill an application
5497        if (callerUid == Process.SYSTEM_UID) {
5498            synchronized (this) {
5499                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5500                if (app != null && app.thread != null) {
5501                    try {
5502                        app.thread.scheduleSuicide();
5503                    } catch (RemoteException e) {
5504                        // If the other end already died, then our work here is done.
5505                    }
5506                } else {
5507                    Slog.w(TAG, "Process/uid not found attempting kill of "
5508                            + processName + " / " + uid);
5509                }
5510            }
5511        } else {
5512            throw new SecurityException(callerUid + " cannot kill app process: " +
5513                    processName);
5514        }
5515    }
5516
5517    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5518        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5519                false, true, false, false, UserHandle.getUserId(uid), reason);
5520        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5521                Uri.fromParts("package", packageName, null));
5522        if (!mProcessesReady) {
5523            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5524                    | Intent.FLAG_RECEIVER_FOREGROUND);
5525        }
5526        intent.putExtra(Intent.EXTRA_UID, uid);
5527        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5528        broadcastIntentLocked(null, null, intent,
5529                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5530                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5531    }
5532
5533
5534    private final boolean killPackageProcessesLocked(String packageName, int appId,
5535            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5536            boolean doit, boolean evenPersistent, String reason) {
5537        ArrayList<ProcessRecord> procs = new ArrayList<>();
5538
5539        // Remove all processes this package may have touched: all with the
5540        // same UID (except for the system or root user), and all whose name
5541        // matches the package name.
5542        final int NP = mProcessNames.getMap().size();
5543        for (int ip=0; ip<NP; ip++) {
5544            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5545            final int NA = apps.size();
5546            for (int ia=0; ia<NA; ia++) {
5547                ProcessRecord app = apps.valueAt(ia);
5548                if (app.persistent && !evenPersistent) {
5549                    // we don't kill persistent processes
5550                    continue;
5551                }
5552                if (app.removed) {
5553                    if (doit) {
5554                        procs.add(app);
5555                    }
5556                    continue;
5557                }
5558
5559                // Skip process if it doesn't meet our oom adj requirement.
5560                if (app.setAdj < minOomAdj) {
5561                    continue;
5562                }
5563
5564                // If no package is specified, we call all processes under the
5565                // give user id.
5566                if (packageName == null) {
5567                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5568                        continue;
5569                    }
5570                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5571                        continue;
5572                    }
5573                // Package has been specified, we want to hit all processes
5574                // that match it.  We need to qualify this by the processes
5575                // that are running under the specified app and user ID.
5576                } else {
5577                    final boolean isDep = app.pkgDeps != null
5578                            && app.pkgDeps.contains(packageName);
5579                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5580                        continue;
5581                    }
5582                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5583                        continue;
5584                    }
5585                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5586                        continue;
5587                    }
5588                }
5589
5590                // Process has passed all conditions, kill it!
5591                if (!doit) {
5592                    return true;
5593                }
5594                app.removed = true;
5595                procs.add(app);
5596            }
5597        }
5598
5599        int N = procs.size();
5600        for (int i=0; i<N; i++) {
5601            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5602        }
5603        updateOomAdjLocked();
5604        return N > 0;
5605    }
5606
5607    private void cleanupDisabledPackageComponentsLocked(
5608            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5609
5610        Set<String> disabledClasses = null;
5611        boolean packageDisabled = false;
5612        IPackageManager pm = AppGlobals.getPackageManager();
5613
5614        if (changedClasses == null) {
5615            // Nothing changed...
5616            return;
5617        }
5618
5619        // Determine enable/disable state of the package and its components.
5620        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5621        for (int i = changedClasses.length - 1; i >= 0; i--) {
5622            final String changedClass = changedClasses[i];
5623
5624            if (changedClass.equals(packageName)) {
5625                try {
5626                    // Entire package setting changed
5627                    enabled = pm.getApplicationEnabledSetting(packageName,
5628                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5629                } catch (Exception e) {
5630                    // No such package/component; probably racing with uninstall.  In any
5631                    // event it means we have nothing further to do here.
5632                    return;
5633                }
5634                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5635                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5636                if (packageDisabled) {
5637                    // Entire package is disabled.
5638                    // No need to continue to check component states.
5639                    disabledClasses = null;
5640                    break;
5641                }
5642            } else {
5643                try {
5644                    enabled = pm.getComponentEnabledSetting(
5645                            new ComponentName(packageName, changedClass),
5646                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5647                } catch (Exception e) {
5648                    // As above, probably racing with uninstall.
5649                    return;
5650                }
5651                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5652                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5653                    if (disabledClasses == null) {
5654                        disabledClasses = new ArraySet<>(changedClasses.length);
5655                    }
5656                    disabledClasses.add(changedClass);
5657                }
5658            }
5659        }
5660
5661        if (!packageDisabled && disabledClasses == null) {
5662            // Nothing to do here...
5663            return;
5664        }
5665
5666        // Clean-up disabled activities.
5667        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5668                packageName, disabledClasses, true, false, userId) && mBooted) {
5669            mStackSupervisor.resumeTopActivitiesLocked();
5670            mStackSupervisor.scheduleIdleLocked();
5671        }
5672
5673        // Clean-up disabled tasks
5674        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5675
5676        // Clean-up disabled services.
5677        mServices.bringDownDisabledPackageServicesLocked(
5678                packageName, disabledClasses, userId, false, killProcess, true);
5679
5680        // Clean-up disabled providers.
5681        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5682        mProviderMap.collectPackageProvidersLocked(
5683                packageName, disabledClasses, true, false, userId, providers);
5684        for (int i = providers.size() - 1; i >= 0; i--) {
5685            removeDyingProviderLocked(null, providers.get(i), true);
5686        }
5687
5688        // Clean-up disabled broadcast receivers.
5689        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5690            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5691                    packageName, disabledClasses, userId, true);
5692        }
5693
5694    }
5695
5696    final boolean forceStopPackageLocked(String packageName, int appId,
5697            boolean callerWillRestart, boolean purgeCache, boolean doit,
5698            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5699        int i;
5700
5701        if (userId == UserHandle.USER_ALL && packageName == null) {
5702            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5703        }
5704
5705        if (appId < 0 && packageName != null) {
5706            try {
5707                appId = UserHandle.getAppId(
5708                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5709            } catch (RemoteException e) {
5710            }
5711        }
5712
5713        if (doit) {
5714            if (packageName != null) {
5715                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5716                        + " user=" + userId + ": " + reason);
5717            } else {
5718                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5719            }
5720
5721            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5722            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5723                SparseArray<Long> ba = pmap.valueAt(ip);
5724                for (i = ba.size() - 1; i >= 0; i--) {
5725                    boolean remove = false;
5726                    final int entUid = ba.keyAt(i);
5727                    if (packageName != null) {
5728                        if (userId == UserHandle.USER_ALL) {
5729                            if (UserHandle.getAppId(entUid) == appId) {
5730                                remove = true;
5731                            }
5732                        } else {
5733                            if (entUid == UserHandle.getUid(userId, appId)) {
5734                                remove = true;
5735                            }
5736                        }
5737                    } else if (UserHandle.getUserId(entUid) == userId) {
5738                        remove = true;
5739                    }
5740                    if (remove) {
5741                        ba.removeAt(i);
5742                    }
5743                }
5744                if (ba.size() == 0) {
5745                    pmap.removeAt(ip);
5746                }
5747            }
5748        }
5749
5750        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5751                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5752                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5753
5754        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5755                packageName, null, doit, evenPersistent, userId)) {
5756            if (!doit) {
5757                return true;
5758            }
5759            didSomething = true;
5760        }
5761
5762        if (mServices.bringDownDisabledPackageServicesLocked(
5763                packageName, null, userId, evenPersistent, true, doit)) {
5764            if (!doit) {
5765                return true;
5766            }
5767            didSomething = true;
5768        }
5769
5770        if (packageName == null) {
5771            // Remove all sticky broadcasts from this user.
5772            mStickyBroadcasts.remove(userId);
5773        }
5774
5775        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5776        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5777                userId, providers)) {
5778            if (!doit) {
5779                return true;
5780            }
5781            didSomething = true;
5782        }
5783        for (i = providers.size() - 1; i >= 0; i--) {
5784            removeDyingProviderLocked(null, providers.get(i), true);
5785        }
5786
5787        // Remove transient permissions granted from/to this package/user
5788        removeUriPermissionsForPackageLocked(packageName, userId, false);
5789
5790        if (doit) {
5791            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5792                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5793                        packageName, null, userId, doit);
5794            }
5795        }
5796
5797        if (packageName == null || uninstalling) {
5798            // Remove pending intents.  For now we only do this when force
5799            // stopping users, because we have some problems when doing this
5800            // for packages -- app widgets are not currently cleaned up for
5801            // such packages, so they can be left with bad pending intents.
5802            if (mIntentSenderRecords.size() > 0) {
5803                Iterator<WeakReference<PendingIntentRecord>> it
5804                        = mIntentSenderRecords.values().iterator();
5805                while (it.hasNext()) {
5806                    WeakReference<PendingIntentRecord> wpir = it.next();
5807                    if (wpir == null) {
5808                        it.remove();
5809                        continue;
5810                    }
5811                    PendingIntentRecord pir = wpir.get();
5812                    if (pir == null) {
5813                        it.remove();
5814                        continue;
5815                    }
5816                    if (packageName == null) {
5817                        // Stopping user, remove all objects for the user.
5818                        if (pir.key.userId != userId) {
5819                            // Not the same user, skip it.
5820                            continue;
5821                        }
5822                    } else {
5823                        if (UserHandle.getAppId(pir.uid) != appId) {
5824                            // Different app id, skip it.
5825                            continue;
5826                        }
5827                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5828                            // Different user, skip it.
5829                            continue;
5830                        }
5831                        if (!pir.key.packageName.equals(packageName)) {
5832                            // Different package, skip it.
5833                            continue;
5834                        }
5835                    }
5836                    if (!doit) {
5837                        return true;
5838                    }
5839                    didSomething = true;
5840                    it.remove();
5841                    pir.canceled = true;
5842                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5843                        pir.key.activity.pendingResults.remove(pir.ref);
5844                    }
5845                }
5846            }
5847        }
5848
5849        if (doit) {
5850            if (purgeCache && packageName != null) {
5851                AttributeCache ac = AttributeCache.instance();
5852                if (ac != null) {
5853                    ac.removePackage(packageName);
5854                }
5855            }
5856            if (mBooted) {
5857                mStackSupervisor.resumeTopActivitiesLocked();
5858                mStackSupervisor.scheduleIdleLocked();
5859            }
5860        }
5861
5862        return didSomething;
5863    }
5864
5865    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5866        ProcessRecord old = mProcessNames.remove(name, uid);
5867        if (old != null) {
5868            old.uidRecord.numProcs--;
5869            if (old.uidRecord.numProcs == 0) {
5870                // No more processes using this uid, tell clients it is gone.
5871                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5872                        "No more processes in " + old.uidRecord);
5873                enqueueUidChangeLocked(old.uidRecord, true);
5874                mActiveUids.remove(uid);
5875            }
5876            old.uidRecord = null;
5877        }
5878        mIsolatedProcesses.remove(uid);
5879        return old;
5880    }
5881
5882    private final void addProcessNameLocked(ProcessRecord proc) {
5883        // We shouldn't already have a process under this name, but just in case we
5884        // need to clean up whatever may be there now.
5885        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5886        if (old == proc && proc.persistent) {
5887            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5888            Slog.w(TAG, "Re-adding persistent process " + proc);
5889        } else if (old != null) {
5890            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5891        }
5892        UidRecord uidRec = mActiveUids.get(proc.uid);
5893        if (uidRec == null) {
5894            uidRec = new UidRecord(proc.uid);
5895            // This is the first appearance of the uid, report it now!
5896            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5897                    "Creating new process uid: " + uidRec);
5898            mActiveUids.put(proc.uid, uidRec);
5899            enqueueUidChangeLocked(uidRec, false);
5900        }
5901        proc.uidRecord = uidRec;
5902        uidRec.numProcs++;
5903        mProcessNames.put(proc.processName, proc.uid, proc);
5904        if (proc.isolated) {
5905            mIsolatedProcesses.put(proc.uid, proc);
5906        }
5907    }
5908
5909    private final boolean removeProcessLocked(ProcessRecord app,
5910            boolean callerWillRestart, boolean allowRestart, String reason) {
5911        final String name = app.processName;
5912        final int uid = app.uid;
5913        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5914            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5915
5916        removeProcessNameLocked(name, uid);
5917        if (mHeavyWeightProcess == app) {
5918            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5919                    mHeavyWeightProcess.userId, 0));
5920            mHeavyWeightProcess = null;
5921        }
5922        boolean needRestart = false;
5923        if (app.pid > 0 && app.pid != MY_PID) {
5924            int pid = app.pid;
5925            synchronized (mPidsSelfLocked) {
5926                mPidsSelfLocked.remove(pid);
5927                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5928            }
5929            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5930            if (app.isolated) {
5931                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5932            }
5933            boolean willRestart = false;
5934            if (app.persistent && !app.isolated) {
5935                if (!callerWillRestart) {
5936                    willRestart = true;
5937                } else {
5938                    needRestart = true;
5939                }
5940            }
5941            app.kill(reason, true);
5942            handleAppDiedLocked(app, willRestart, allowRestart);
5943            if (willRestart) {
5944                removeLruProcessLocked(app);
5945                addAppLocked(app.info, false, null /* ABI override */);
5946            }
5947        } else {
5948            mRemovedProcesses.add(app);
5949        }
5950
5951        return needRestart;
5952    }
5953
5954    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5955        cleanupAppInLaunchingProvidersLocked(app, true);
5956        removeProcessLocked(app, false, true, "timeout publishing content providers");
5957    }
5958
5959    private final void processStartTimedOutLocked(ProcessRecord app) {
5960        final int pid = app.pid;
5961        boolean gone = false;
5962        synchronized (mPidsSelfLocked) {
5963            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5964            if (knownApp != null && knownApp.thread == null) {
5965                mPidsSelfLocked.remove(pid);
5966                gone = true;
5967            }
5968        }
5969
5970        if (gone) {
5971            Slog.w(TAG, "Process " + app + " failed to attach");
5972            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5973                    pid, app.uid, app.processName);
5974            removeProcessNameLocked(app.processName, app.uid);
5975            if (mHeavyWeightProcess == app) {
5976                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5977                        mHeavyWeightProcess.userId, 0));
5978                mHeavyWeightProcess = null;
5979            }
5980            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5981            if (app.isolated) {
5982                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5983            }
5984            // Take care of any launching providers waiting for this process.
5985            cleanupAppInLaunchingProvidersLocked(app, true);
5986            // Take care of any services that are waiting for the process.
5987            mServices.processStartTimedOutLocked(app);
5988            app.kill("start timeout", true);
5989            removeLruProcessLocked(app);
5990            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5991                Slog.w(TAG, "Unattached app died before backup, skipping");
5992                try {
5993                    IBackupManager bm = IBackupManager.Stub.asInterface(
5994                            ServiceManager.getService(Context.BACKUP_SERVICE));
5995                    bm.agentDisconnected(app.info.packageName);
5996                } catch (RemoteException e) {
5997                    // Can't happen; the backup manager is local
5998                }
5999            }
6000            if (isPendingBroadcastProcessLocked(pid)) {
6001                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6002                skipPendingBroadcastLocked(pid);
6003            }
6004        } else {
6005            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6006        }
6007    }
6008
6009    private final boolean attachApplicationLocked(IApplicationThread thread,
6010            int pid) {
6011
6012        // Find the application record that is being attached...  either via
6013        // the pid if we are running in multiple processes, or just pull the
6014        // next app record if we are emulating process with anonymous threads.
6015        ProcessRecord app;
6016        if (pid != MY_PID && pid >= 0) {
6017            synchronized (mPidsSelfLocked) {
6018                app = mPidsSelfLocked.get(pid);
6019            }
6020        } else {
6021            app = null;
6022        }
6023
6024        if (app == null) {
6025            Slog.w(TAG, "No pending application record for pid " + pid
6026                    + " (IApplicationThread " + thread + "); dropping process");
6027            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6028            if (pid > 0 && pid != MY_PID) {
6029                Process.killProcessQuiet(pid);
6030                //TODO: killProcessGroup(app.info.uid, pid);
6031            } else {
6032                try {
6033                    thread.scheduleExit();
6034                } catch (Exception e) {
6035                    // Ignore exceptions.
6036                }
6037            }
6038            return false;
6039        }
6040
6041        // If this application record is still attached to a previous
6042        // process, clean it up now.
6043        if (app.thread != null) {
6044            handleAppDiedLocked(app, true, true);
6045        }
6046
6047        // Tell the process all about itself.
6048
6049        if (DEBUG_ALL) Slog.v(
6050                TAG, "Binding process pid " + pid + " to record " + app);
6051
6052        final String processName = app.processName;
6053        try {
6054            AppDeathRecipient adr = new AppDeathRecipient(
6055                    app, pid, thread);
6056            thread.asBinder().linkToDeath(adr, 0);
6057            app.deathRecipient = adr;
6058        } catch (RemoteException e) {
6059            app.resetPackageList(mProcessStats);
6060            startProcessLocked(app, "link fail", processName);
6061            return false;
6062        }
6063
6064        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6065
6066        app.makeActive(thread, mProcessStats);
6067        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6068        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6069        app.forcingToForeground = null;
6070        updateProcessForegroundLocked(app, false, false);
6071        app.hasShownUi = false;
6072        app.debugging = false;
6073        app.cached = false;
6074        app.killedByAm = false;
6075
6076        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6077
6078        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6079        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6080
6081        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6082            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6083            msg.obj = app;
6084            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6085        }
6086
6087        if (!normalMode) {
6088            Slog.i(TAG, "Launching preboot mode app: " + app);
6089        }
6090
6091        if (DEBUG_ALL) Slog.v(
6092            TAG, "New app record " + app
6093            + " thread=" + thread.asBinder() + " pid=" + pid);
6094        try {
6095            int testMode = IApplicationThread.DEBUG_OFF;
6096            if (mDebugApp != null && mDebugApp.equals(processName)) {
6097                testMode = mWaitForDebugger
6098                    ? IApplicationThread.DEBUG_WAIT
6099                    : IApplicationThread.DEBUG_ON;
6100                app.debugging = true;
6101                if (mDebugTransient) {
6102                    mDebugApp = mOrigDebugApp;
6103                    mWaitForDebugger = mOrigWaitForDebugger;
6104                }
6105            }
6106            String profileFile = app.instrumentationProfileFile;
6107            ParcelFileDescriptor profileFd = null;
6108            int samplingInterval = 0;
6109            boolean profileAutoStop = false;
6110            if (mProfileApp != null && mProfileApp.equals(processName)) {
6111                mProfileProc = app;
6112                profileFile = mProfileFile;
6113                profileFd = mProfileFd;
6114                samplingInterval = mSamplingInterval;
6115                profileAutoStop = mAutoStopProfiler;
6116            }
6117            boolean enableTrackAllocation = false;
6118            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6119                enableTrackAllocation = true;
6120                mTrackAllocationApp = null;
6121            }
6122
6123            // If the app is being launched for restore or full backup, set it up specially
6124            boolean isRestrictedBackupMode = false;
6125            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6126                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6127                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6128                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6129            }
6130
6131            ensurePackageDexOpt(app.instrumentationInfo != null
6132                    ? app.instrumentationInfo.packageName
6133                    : app.info.packageName);
6134            if (app.instrumentationClass != null) {
6135                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6136            }
6137            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6138                    + processName + " with config " + mConfiguration);
6139            ApplicationInfo appInfo = app.instrumentationInfo != null
6140                    ? app.instrumentationInfo : app.info;
6141            app.compat = compatibilityInfoForPackageLocked(appInfo);
6142            if (profileFd != null) {
6143                profileFd = profileFd.dup();
6144            }
6145            ProfilerInfo profilerInfo = profileFile == null ? null
6146                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6147            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6148                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6149                    app.instrumentationUiAutomationConnection, testMode,
6150                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6151                    isRestrictedBackupMode || !normalMode, app.persistent,
6152                    new Configuration(mConfiguration), app.compat,
6153                    getCommonServicesLocked(app.isolated),
6154                    mCoreSettingsObserver.getCoreSettingsLocked());
6155            updateLruProcessLocked(app, false, null);
6156            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6157        } catch (Exception e) {
6158            // todo: Yikes!  What should we do?  For now we will try to
6159            // start another process, but that could easily get us in
6160            // an infinite loop of restarting processes...
6161            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6162
6163            app.resetPackageList(mProcessStats);
6164            app.unlinkDeathRecipient();
6165            startProcessLocked(app, "bind fail", processName);
6166            return false;
6167        }
6168
6169        // Remove this record from the list of starting applications.
6170        mPersistentStartingProcesses.remove(app);
6171        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6172                "Attach application locked removing on hold: " + app);
6173        mProcessesOnHold.remove(app);
6174
6175        boolean badApp = false;
6176        boolean didSomething = false;
6177
6178        // See if the top visible activity is waiting to run in this process...
6179        if (normalMode) {
6180            try {
6181                if (mStackSupervisor.attachApplicationLocked(app)) {
6182                    didSomething = true;
6183                }
6184            } catch (Exception e) {
6185                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6186                badApp = true;
6187            }
6188        }
6189
6190        // Find any services that should be running in this process...
6191        if (!badApp) {
6192            try {
6193                didSomething |= mServices.attachApplicationLocked(app, processName);
6194            } catch (Exception e) {
6195                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6196                badApp = true;
6197            }
6198        }
6199
6200        // Check if a next-broadcast receiver is in this process...
6201        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6202            try {
6203                didSomething |= sendPendingBroadcastsLocked(app);
6204            } catch (Exception e) {
6205                // If the app died trying to launch the receiver we declare it 'bad'
6206                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6207                badApp = true;
6208            }
6209        }
6210
6211        // Check whether the next backup agent is in this process...
6212        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6213            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6214                    "New app is backup target, launching agent for " + app);
6215            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6216            try {
6217                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6218                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6219                        mBackupTarget.backupMode);
6220            } catch (Exception e) {
6221                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6222                badApp = true;
6223            }
6224        }
6225
6226        if (badApp) {
6227            app.kill("error during init", true);
6228            handleAppDiedLocked(app, false, true);
6229            return false;
6230        }
6231
6232        if (!didSomething) {
6233            updateOomAdjLocked();
6234        }
6235
6236        return true;
6237    }
6238
6239    @Override
6240    public final void attachApplication(IApplicationThread thread) {
6241        synchronized (this) {
6242            int callingPid = Binder.getCallingPid();
6243            final long origId = Binder.clearCallingIdentity();
6244            attachApplicationLocked(thread, callingPid);
6245            Binder.restoreCallingIdentity(origId);
6246        }
6247    }
6248
6249    @Override
6250    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6251        final long origId = Binder.clearCallingIdentity();
6252        synchronized (this) {
6253            ActivityStack stack = ActivityRecord.getStackLocked(token);
6254            if (stack != null) {
6255                ActivityRecord r =
6256                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6257                if (stopProfiling) {
6258                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6259                        try {
6260                            mProfileFd.close();
6261                        } catch (IOException e) {
6262                        }
6263                        clearProfilerLocked();
6264                    }
6265                }
6266            }
6267        }
6268        Binder.restoreCallingIdentity(origId);
6269    }
6270
6271    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6272        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6273                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6274    }
6275
6276    void enableScreenAfterBoot() {
6277        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6278                SystemClock.uptimeMillis());
6279        mWindowManager.enableScreenAfterBoot();
6280
6281        synchronized (this) {
6282            updateEventDispatchingLocked();
6283        }
6284    }
6285
6286    @Override
6287    public void showBootMessage(final CharSequence msg, final boolean always) {
6288        if (Binder.getCallingUid() != Process.myUid()) {
6289            // These days only the core system can call this, so apps can't get in
6290            // the way of what we show about running them.
6291        }
6292        mWindowManager.showBootMessage(msg, always);
6293    }
6294
6295    @Override
6296    public void keyguardWaitingForActivityDrawn() {
6297        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6298        final long token = Binder.clearCallingIdentity();
6299        try {
6300            synchronized (this) {
6301                if (DEBUG_LOCKSCREEN) logLockScreen("");
6302                mWindowManager.keyguardWaitingForActivityDrawn();
6303                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6304                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6305                    updateSleepIfNeededLocked();
6306                }
6307            }
6308        } finally {
6309            Binder.restoreCallingIdentity(token);
6310        }
6311    }
6312
6313    @Override
6314    public void keyguardGoingAway(boolean disableWindowAnimations,
6315            boolean keyguardGoingToNotificationShade) {
6316        enforceNotIsolatedCaller("keyguardGoingAway");
6317        final long token = Binder.clearCallingIdentity();
6318        try {
6319            synchronized (this) {
6320                if (DEBUG_LOCKSCREEN) logLockScreen("");
6321                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6322                        keyguardGoingToNotificationShade);
6323                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6324                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6325                    updateSleepIfNeededLocked();
6326                }
6327            }
6328        } finally {
6329            Binder.restoreCallingIdentity(token);
6330        }
6331    }
6332
6333    final void finishBooting() {
6334        synchronized (this) {
6335            if (!mBootAnimationComplete) {
6336                mCallFinishBooting = true;
6337                return;
6338            }
6339            mCallFinishBooting = false;
6340        }
6341
6342        ArraySet<String> completedIsas = new ArraySet<String>();
6343        for (String abi : Build.SUPPORTED_ABIS) {
6344            Process.establishZygoteConnectionForAbi(abi);
6345            final String instructionSet = VMRuntime.getInstructionSet(abi);
6346            if (!completedIsas.contains(instructionSet)) {
6347                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6348                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6349                }
6350                completedIsas.add(instructionSet);
6351            }
6352        }
6353
6354        IntentFilter pkgFilter = new IntentFilter();
6355        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6356        pkgFilter.addDataScheme("package");
6357        mContext.registerReceiver(new BroadcastReceiver() {
6358            @Override
6359            public void onReceive(Context context, Intent intent) {
6360                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6361                if (pkgs != null) {
6362                    for (String pkg : pkgs) {
6363                        synchronized (ActivityManagerService.this) {
6364                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6365                                    0, "query restart")) {
6366                                setResultCode(Activity.RESULT_OK);
6367                                return;
6368                            }
6369                        }
6370                    }
6371                }
6372            }
6373        }, pkgFilter);
6374
6375        IntentFilter dumpheapFilter = new IntentFilter();
6376        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6377        mContext.registerReceiver(new BroadcastReceiver() {
6378            @Override
6379            public void onReceive(Context context, Intent intent) {
6380                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6381                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6382                } else {
6383                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6384                }
6385            }
6386        }, dumpheapFilter);
6387
6388        // Let system services know.
6389        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6390
6391        synchronized (this) {
6392            // Ensure that any processes we had put on hold are now started
6393            // up.
6394            final int NP = mProcessesOnHold.size();
6395            if (NP > 0) {
6396                ArrayList<ProcessRecord> procs =
6397                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6398                for (int ip=0; ip<NP; ip++) {
6399                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6400                            + procs.get(ip));
6401                    startProcessLocked(procs.get(ip), "on-hold", null);
6402                }
6403            }
6404
6405            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6406                // Start looking for apps that are abusing wake locks.
6407                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6408                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6409                // Tell anyone interested that we are done booting!
6410                SystemProperties.set("sys.boot_completed", "1");
6411
6412                // And trigger dev.bootcomplete if we are not showing encryption progress
6413                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6414                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6415                    SystemProperties.set("dev.bootcomplete", "1");
6416                }
6417                mUserController.sendBootCompletedLocked(
6418                        new IIntentReceiver.Stub() {
6419                            @Override
6420                            public void performReceive(Intent intent, int resultCode,
6421                                    String data, Bundle extras, boolean ordered,
6422                                    boolean sticky, int sendingUser) {
6423                                synchronized (ActivityManagerService.this) {
6424                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6425                                            true, false);
6426                                }
6427                            }
6428                        });
6429                scheduleStartProfilesLocked();
6430            }
6431        }
6432    }
6433
6434    @Override
6435    public void bootAnimationComplete() {
6436        final boolean callFinishBooting;
6437        synchronized (this) {
6438            callFinishBooting = mCallFinishBooting;
6439            mBootAnimationComplete = true;
6440        }
6441        if (callFinishBooting) {
6442            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6443            finishBooting();
6444            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6445        }
6446    }
6447
6448    final void ensureBootCompleted() {
6449        boolean booting;
6450        boolean enableScreen;
6451        synchronized (this) {
6452            booting = mBooting;
6453            mBooting = false;
6454            enableScreen = !mBooted;
6455            mBooted = true;
6456        }
6457
6458        if (booting) {
6459            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6460            finishBooting();
6461            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6462        }
6463
6464        if (enableScreen) {
6465            enableScreenAfterBoot();
6466        }
6467    }
6468
6469    @Override
6470    public final void activityResumed(IBinder token) {
6471        final long origId = Binder.clearCallingIdentity();
6472        synchronized(this) {
6473            ActivityStack stack = ActivityRecord.getStackLocked(token);
6474            if (stack != null) {
6475                ActivityRecord.activityResumedLocked(token);
6476            }
6477        }
6478        Binder.restoreCallingIdentity(origId);
6479    }
6480
6481    @Override
6482    public final void activityPaused(IBinder token) {
6483        final long origId = Binder.clearCallingIdentity();
6484        synchronized(this) {
6485            ActivityStack stack = ActivityRecord.getStackLocked(token);
6486            if (stack != null) {
6487                stack.activityPausedLocked(token, false);
6488            }
6489        }
6490        Binder.restoreCallingIdentity(origId);
6491    }
6492
6493    @Override
6494    public final void activityStopped(IBinder token, Bundle icicle,
6495            PersistableBundle persistentState, CharSequence description) {
6496        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6497
6498        // Refuse possible leaked file descriptors
6499        if (icicle != null && icicle.hasFileDescriptors()) {
6500            throw new IllegalArgumentException("File descriptors passed in Bundle");
6501        }
6502
6503        final long origId = Binder.clearCallingIdentity();
6504
6505        synchronized (this) {
6506            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6507            if (r != null) {
6508                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6509            }
6510        }
6511
6512        trimApplications();
6513
6514        Binder.restoreCallingIdentity(origId);
6515    }
6516
6517    @Override
6518    public final void activityDestroyed(IBinder token) {
6519        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6520        synchronized (this) {
6521            ActivityStack stack = ActivityRecord.getStackLocked(token);
6522            if (stack != null) {
6523                stack.activityDestroyedLocked(token, "activityDestroyed");
6524            }
6525        }
6526    }
6527
6528    @Override
6529    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6530            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6531        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6532                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6533        synchronized (this) {
6534            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6535            if (record == null) {
6536                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6537                        + "found for: " + token);
6538            }
6539            record.setSizeConfigurations(horizontalSizeConfiguration,
6540                    verticalSizeConfigurations, smallestSizeConfigurations);
6541        }
6542    }
6543
6544    @Override
6545    public final void backgroundResourcesReleased(IBinder token) {
6546        final long origId = Binder.clearCallingIdentity();
6547        try {
6548            synchronized (this) {
6549                ActivityStack stack = ActivityRecord.getStackLocked(token);
6550                if (stack != null) {
6551                    stack.backgroundResourcesReleased();
6552                }
6553            }
6554        } finally {
6555            Binder.restoreCallingIdentity(origId);
6556        }
6557    }
6558
6559    @Override
6560    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6561        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6562    }
6563
6564    @Override
6565    public final void notifyEnterAnimationComplete(IBinder token) {
6566        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6567    }
6568
6569    @Override
6570    public String getCallingPackage(IBinder token) {
6571        synchronized (this) {
6572            ActivityRecord r = getCallingRecordLocked(token);
6573            return r != null ? r.info.packageName : null;
6574        }
6575    }
6576
6577    @Override
6578    public ComponentName getCallingActivity(IBinder token) {
6579        synchronized (this) {
6580            ActivityRecord r = getCallingRecordLocked(token);
6581            return r != null ? r.intent.getComponent() : null;
6582        }
6583    }
6584
6585    private ActivityRecord getCallingRecordLocked(IBinder token) {
6586        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6587        if (r == null) {
6588            return null;
6589        }
6590        return r.resultTo;
6591    }
6592
6593    @Override
6594    public ComponentName getActivityClassForToken(IBinder token) {
6595        synchronized(this) {
6596            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6597            if (r == null) {
6598                return null;
6599            }
6600            return r.intent.getComponent();
6601        }
6602    }
6603
6604    @Override
6605    public String getPackageForToken(IBinder token) {
6606        synchronized(this) {
6607            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6608            if (r == null) {
6609                return null;
6610            }
6611            return r.packageName;
6612        }
6613    }
6614
6615    @Override
6616    public boolean isRootVoiceInteraction(IBinder token) {
6617        synchronized(this) {
6618            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6619            if (r == null) {
6620                return false;
6621            }
6622            return r.rootVoiceInteraction;
6623        }
6624    }
6625
6626    @Override
6627    public IIntentSender getIntentSender(int type,
6628            String packageName, IBinder token, String resultWho,
6629            int requestCode, Intent[] intents, String[] resolvedTypes,
6630            int flags, Bundle options, int userId) {
6631        enforceNotIsolatedCaller("getIntentSender");
6632        // Refuse possible leaked file descriptors
6633        if (intents != null) {
6634            if (intents.length < 1) {
6635                throw new IllegalArgumentException("Intents array length must be >= 1");
6636            }
6637            for (int i=0; i<intents.length; i++) {
6638                Intent intent = intents[i];
6639                if (intent != null) {
6640                    if (intent.hasFileDescriptors()) {
6641                        throw new IllegalArgumentException("File descriptors passed in Intent");
6642                    }
6643                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6644                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6645                        throw new IllegalArgumentException(
6646                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6647                    }
6648                    intents[i] = new Intent(intent);
6649                }
6650            }
6651            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6652                throw new IllegalArgumentException(
6653                        "Intent array length does not match resolvedTypes length");
6654            }
6655        }
6656        if (options != null) {
6657            if (options.hasFileDescriptors()) {
6658                throw new IllegalArgumentException("File descriptors passed in options");
6659            }
6660        }
6661
6662        synchronized(this) {
6663            int callingUid = Binder.getCallingUid();
6664            int origUserId = userId;
6665            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6666                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6667                    ALLOW_NON_FULL, "getIntentSender", null);
6668            if (origUserId == UserHandle.USER_CURRENT) {
6669                // We don't want to evaluate this until the pending intent is
6670                // actually executed.  However, we do want to always do the
6671                // security checking for it above.
6672                userId = UserHandle.USER_CURRENT;
6673            }
6674            try {
6675                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6676                    int uid = AppGlobals.getPackageManager()
6677                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6678                    if (!UserHandle.isSameApp(callingUid, uid)) {
6679                        String msg = "Permission Denial: getIntentSender() from pid="
6680                            + Binder.getCallingPid()
6681                            + ", uid=" + Binder.getCallingUid()
6682                            + ", (need uid=" + uid + ")"
6683                            + " is not allowed to send as package " + packageName;
6684                        Slog.w(TAG, msg);
6685                        throw new SecurityException(msg);
6686                    }
6687                }
6688
6689                return getIntentSenderLocked(type, packageName, callingUid, userId,
6690                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6691
6692            } catch (RemoteException e) {
6693                throw new SecurityException(e);
6694            }
6695        }
6696    }
6697
6698    IIntentSender getIntentSenderLocked(int type, String packageName,
6699            int callingUid, int userId, IBinder token, String resultWho,
6700            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6701            Bundle options) {
6702        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6703        ActivityRecord activity = null;
6704        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6705            activity = ActivityRecord.isInStackLocked(token);
6706            if (activity == null) {
6707                return null;
6708            }
6709            if (activity.finishing) {
6710                return null;
6711            }
6712        }
6713
6714        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6715        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6716        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6717        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6718                |PendingIntent.FLAG_UPDATE_CURRENT);
6719
6720        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6721                type, packageName, activity, resultWho,
6722                requestCode, intents, resolvedTypes, flags, options, userId);
6723        WeakReference<PendingIntentRecord> ref;
6724        ref = mIntentSenderRecords.get(key);
6725        PendingIntentRecord rec = ref != null ? ref.get() : null;
6726        if (rec != null) {
6727            if (!cancelCurrent) {
6728                if (updateCurrent) {
6729                    if (rec.key.requestIntent != null) {
6730                        rec.key.requestIntent.replaceExtras(intents != null ?
6731                                intents[intents.length - 1] : null);
6732                    }
6733                    if (intents != null) {
6734                        intents[intents.length-1] = rec.key.requestIntent;
6735                        rec.key.allIntents = intents;
6736                        rec.key.allResolvedTypes = resolvedTypes;
6737                    } else {
6738                        rec.key.allIntents = null;
6739                        rec.key.allResolvedTypes = null;
6740                    }
6741                }
6742                return rec;
6743            }
6744            rec.canceled = true;
6745            mIntentSenderRecords.remove(key);
6746        }
6747        if (noCreate) {
6748            return rec;
6749        }
6750        rec = new PendingIntentRecord(this, key, callingUid);
6751        mIntentSenderRecords.put(key, rec.ref);
6752        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6753            if (activity.pendingResults == null) {
6754                activity.pendingResults
6755                        = new HashSet<WeakReference<PendingIntentRecord>>();
6756            }
6757            activity.pendingResults.add(rec.ref);
6758        }
6759        return rec;
6760    }
6761
6762    @Override
6763    public void cancelIntentSender(IIntentSender sender) {
6764        if (!(sender instanceof PendingIntentRecord)) {
6765            return;
6766        }
6767        synchronized(this) {
6768            PendingIntentRecord rec = (PendingIntentRecord)sender;
6769            try {
6770                int uid = AppGlobals.getPackageManager()
6771                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6772                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6773                    String msg = "Permission Denial: cancelIntentSender() from pid="
6774                        + Binder.getCallingPid()
6775                        + ", uid=" + Binder.getCallingUid()
6776                        + " is not allowed to cancel packges "
6777                        + rec.key.packageName;
6778                    Slog.w(TAG, msg);
6779                    throw new SecurityException(msg);
6780                }
6781            } catch (RemoteException e) {
6782                throw new SecurityException(e);
6783            }
6784            cancelIntentSenderLocked(rec, true);
6785        }
6786    }
6787
6788    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6789        rec.canceled = true;
6790        mIntentSenderRecords.remove(rec.key);
6791        if (cleanActivity && rec.key.activity != null) {
6792            rec.key.activity.pendingResults.remove(rec.ref);
6793        }
6794    }
6795
6796    @Override
6797    public String getPackageForIntentSender(IIntentSender pendingResult) {
6798        if (!(pendingResult instanceof PendingIntentRecord)) {
6799            return null;
6800        }
6801        try {
6802            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803            return res.key.packageName;
6804        } catch (ClassCastException e) {
6805        }
6806        return null;
6807    }
6808
6809    @Override
6810    public int getUidForIntentSender(IIntentSender sender) {
6811        if (sender instanceof PendingIntentRecord) {
6812            try {
6813                PendingIntentRecord res = (PendingIntentRecord)sender;
6814                return res.uid;
6815            } catch (ClassCastException e) {
6816            }
6817        }
6818        return -1;
6819    }
6820
6821    @Override
6822    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6823        if (!(pendingResult instanceof PendingIntentRecord)) {
6824            return false;
6825        }
6826        try {
6827            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6828            if (res.key.allIntents == null) {
6829                return false;
6830            }
6831            for (int i=0; i<res.key.allIntents.length; i++) {
6832                Intent intent = res.key.allIntents[i];
6833                if (intent.getPackage() != null && intent.getComponent() != null) {
6834                    return false;
6835                }
6836            }
6837            return true;
6838        } catch (ClassCastException e) {
6839        }
6840        return false;
6841    }
6842
6843    @Override
6844    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6845        if (!(pendingResult instanceof PendingIntentRecord)) {
6846            return false;
6847        }
6848        try {
6849            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6850            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6851                return true;
6852            }
6853            return false;
6854        } catch (ClassCastException e) {
6855        }
6856        return false;
6857    }
6858
6859    @Override
6860    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6861        if (!(pendingResult instanceof PendingIntentRecord)) {
6862            return null;
6863        }
6864        try {
6865            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6866            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6867        } catch (ClassCastException e) {
6868        }
6869        return null;
6870    }
6871
6872    @Override
6873    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6874        if (!(pendingResult instanceof PendingIntentRecord)) {
6875            return null;
6876        }
6877        try {
6878            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6879            synchronized (this) {
6880                return getTagForIntentSenderLocked(res, prefix);
6881            }
6882        } catch (ClassCastException e) {
6883        }
6884        return null;
6885    }
6886
6887    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6888        final Intent intent = res.key.requestIntent;
6889        if (intent != null) {
6890            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6891                    || res.lastTagPrefix.equals(prefix))) {
6892                return res.lastTag;
6893            }
6894            res.lastTagPrefix = prefix;
6895            final StringBuilder sb = new StringBuilder(128);
6896            if (prefix != null) {
6897                sb.append(prefix);
6898            }
6899            if (intent.getAction() != null) {
6900                sb.append(intent.getAction());
6901            } else if (intent.getComponent() != null) {
6902                intent.getComponent().appendShortString(sb);
6903            } else {
6904                sb.append("?");
6905            }
6906            return res.lastTag = sb.toString();
6907        }
6908        return null;
6909    }
6910
6911    @Override
6912    public void setProcessLimit(int max) {
6913        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6914                "setProcessLimit()");
6915        synchronized (this) {
6916            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6917            mProcessLimitOverride = max;
6918        }
6919        trimApplications();
6920    }
6921
6922    @Override
6923    public int getProcessLimit() {
6924        synchronized (this) {
6925            return mProcessLimitOverride;
6926        }
6927    }
6928
6929    void foregroundTokenDied(ForegroundToken token) {
6930        synchronized (ActivityManagerService.this) {
6931            synchronized (mPidsSelfLocked) {
6932                ForegroundToken cur
6933                    = mForegroundProcesses.get(token.pid);
6934                if (cur != token) {
6935                    return;
6936                }
6937                mForegroundProcesses.remove(token.pid);
6938                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6939                if (pr == null) {
6940                    return;
6941                }
6942                pr.forcingToForeground = null;
6943                updateProcessForegroundLocked(pr, false, false);
6944            }
6945            updateOomAdjLocked();
6946        }
6947    }
6948
6949    @Override
6950    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6951        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6952                "setProcessForeground()");
6953        synchronized(this) {
6954            boolean changed = false;
6955
6956            synchronized (mPidsSelfLocked) {
6957                ProcessRecord pr = mPidsSelfLocked.get(pid);
6958                if (pr == null && isForeground) {
6959                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6960                    return;
6961                }
6962                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6963                if (oldToken != null) {
6964                    oldToken.token.unlinkToDeath(oldToken, 0);
6965                    mForegroundProcesses.remove(pid);
6966                    if (pr != null) {
6967                        pr.forcingToForeground = null;
6968                    }
6969                    changed = true;
6970                }
6971                if (isForeground && token != null) {
6972                    ForegroundToken newToken = new ForegroundToken() {
6973                        @Override
6974                        public void binderDied() {
6975                            foregroundTokenDied(this);
6976                        }
6977                    };
6978                    newToken.pid = pid;
6979                    newToken.token = token;
6980                    try {
6981                        token.linkToDeath(newToken, 0);
6982                        mForegroundProcesses.put(pid, newToken);
6983                        pr.forcingToForeground = token;
6984                        changed = true;
6985                    } catch (RemoteException e) {
6986                        // If the process died while doing this, we will later
6987                        // do the cleanup with the process death link.
6988                    }
6989                }
6990            }
6991
6992            if (changed) {
6993                updateOomAdjLocked();
6994            }
6995        }
6996    }
6997
6998    // =========================================================
6999    // PROCESS INFO
7000    // =========================================================
7001
7002    static class ProcessInfoService extends IProcessInfoService.Stub {
7003        final ActivityManagerService mActivityManagerService;
7004        ProcessInfoService(ActivityManagerService activityManagerService) {
7005            mActivityManagerService = activityManagerService;
7006        }
7007
7008        @Override
7009        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7010            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7011        }
7012    }
7013
7014    /**
7015     * For each PID in the given input array, write the current process state
7016     * for that process into the output array, or -1 to indicate that no
7017     * process with the given PID exists.
7018     */
7019    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7020        if (pids == null) {
7021            throw new NullPointerException("pids");
7022        } else if (states == null) {
7023            throw new NullPointerException("states");
7024        } else if (pids.length != states.length) {
7025            throw new IllegalArgumentException("input and output arrays have different lengths!");
7026        }
7027
7028        synchronized (mPidsSelfLocked) {
7029            for (int i = 0; i < pids.length; i++) {
7030                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7031                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7032                        pr.curProcState;
7033            }
7034        }
7035    }
7036
7037    // =========================================================
7038    // PERMISSIONS
7039    // =========================================================
7040
7041    static class PermissionController extends IPermissionController.Stub {
7042        ActivityManagerService mActivityManagerService;
7043        PermissionController(ActivityManagerService activityManagerService) {
7044            mActivityManagerService = activityManagerService;
7045        }
7046
7047        @Override
7048        public boolean checkPermission(String permission, int pid, int uid) {
7049            return mActivityManagerService.checkPermission(permission, pid,
7050                    uid) == PackageManager.PERMISSION_GRANTED;
7051        }
7052
7053        @Override
7054        public String[] getPackagesForUid(int uid) {
7055            return mActivityManagerService.mContext.getPackageManager()
7056                    .getPackagesForUid(uid);
7057        }
7058
7059        @Override
7060        public boolean isRuntimePermission(String permission) {
7061            try {
7062                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7063                        .getPermissionInfo(permission, 0);
7064                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7065            } catch (NameNotFoundException nnfe) {
7066                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7067            }
7068            return false;
7069        }
7070    }
7071
7072    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7073        @Override
7074        public int checkComponentPermission(String permission, int pid, int uid,
7075                int owningUid, boolean exported) {
7076            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7077                    owningUid, exported);
7078        }
7079
7080        @Override
7081        public Object getAMSLock() {
7082            return ActivityManagerService.this;
7083        }
7084    }
7085
7086    /**
7087     * This can be called with or without the global lock held.
7088     */
7089    int checkComponentPermission(String permission, int pid, int uid,
7090            int owningUid, boolean exported) {
7091        if (pid == MY_PID) {
7092            return PackageManager.PERMISSION_GRANTED;
7093        }
7094        return ActivityManager.checkComponentPermission(permission, uid,
7095                owningUid, exported);
7096    }
7097
7098    /**
7099     * As the only public entry point for permissions checking, this method
7100     * can enforce the semantic that requesting a check on a null global
7101     * permission is automatically denied.  (Internally a null permission
7102     * string is used when calling {@link #checkComponentPermission} in cases
7103     * when only uid-based security is needed.)
7104     *
7105     * This can be called with or without the global lock held.
7106     */
7107    @Override
7108    public int checkPermission(String permission, int pid, int uid) {
7109        if (permission == null) {
7110            return PackageManager.PERMISSION_DENIED;
7111        }
7112        return checkComponentPermission(permission, pid, uid, -1, true);
7113    }
7114
7115    @Override
7116    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7117        if (permission == null) {
7118            return PackageManager.PERMISSION_DENIED;
7119        }
7120
7121        // We might be performing an operation on behalf of an indirect binder
7122        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7123        // client identity accordingly before proceeding.
7124        Identity tlsIdentity = sCallerIdentity.get();
7125        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7126            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7127                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7128            uid = tlsIdentity.uid;
7129            pid = tlsIdentity.pid;
7130        }
7131
7132        return checkComponentPermission(permission, pid, uid, -1, true);
7133    }
7134
7135    /**
7136     * Binder IPC calls go through the public entry point.
7137     * This can be called with or without the global lock held.
7138     */
7139    int checkCallingPermission(String permission) {
7140        return checkPermission(permission,
7141                Binder.getCallingPid(),
7142                UserHandle.getAppId(Binder.getCallingUid()));
7143    }
7144
7145    /**
7146     * This can be called with or without the global lock held.
7147     */
7148    void enforceCallingPermission(String permission, String func) {
7149        if (checkCallingPermission(permission)
7150                == PackageManager.PERMISSION_GRANTED) {
7151            return;
7152        }
7153
7154        String msg = "Permission Denial: " + func + " from pid="
7155                + Binder.getCallingPid()
7156                + ", uid=" + Binder.getCallingUid()
7157                + " requires " + permission;
7158        Slog.w(TAG, msg);
7159        throw new SecurityException(msg);
7160    }
7161
7162    /**
7163     * Determine if UID is holding permissions required to access {@link Uri} in
7164     * the given {@link ProviderInfo}. Final permission checking is always done
7165     * in {@link ContentProvider}.
7166     */
7167    private final boolean checkHoldingPermissionsLocked(
7168            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7169        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7170                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7171        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7172            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7173                    != PERMISSION_GRANTED) {
7174                return false;
7175            }
7176        }
7177        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7178    }
7179
7180    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7181            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7182        if (pi.applicationInfo.uid == uid) {
7183            return true;
7184        } else if (!pi.exported) {
7185            return false;
7186        }
7187
7188        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7189        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7190        try {
7191            // check if target holds top-level <provider> permissions
7192            if (!readMet && pi.readPermission != null && considerUidPermissions
7193                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7194                readMet = true;
7195            }
7196            if (!writeMet && pi.writePermission != null && considerUidPermissions
7197                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7198                writeMet = true;
7199            }
7200
7201            // track if unprotected read/write is allowed; any denied
7202            // <path-permission> below removes this ability
7203            boolean allowDefaultRead = pi.readPermission == null;
7204            boolean allowDefaultWrite = pi.writePermission == null;
7205
7206            // check if target holds any <path-permission> that match uri
7207            final PathPermission[] pps = pi.pathPermissions;
7208            if (pps != null) {
7209                final String path = grantUri.uri.getPath();
7210                int i = pps.length;
7211                while (i > 0 && (!readMet || !writeMet)) {
7212                    i--;
7213                    PathPermission pp = pps[i];
7214                    if (pp.match(path)) {
7215                        if (!readMet) {
7216                            final String pprperm = pp.getReadPermission();
7217                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7218                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7219                                    + ": match=" + pp.match(path)
7220                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7221                            if (pprperm != null) {
7222                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7223                                        == PERMISSION_GRANTED) {
7224                                    readMet = true;
7225                                } else {
7226                                    allowDefaultRead = false;
7227                                }
7228                            }
7229                        }
7230                        if (!writeMet) {
7231                            final String ppwperm = pp.getWritePermission();
7232                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7233                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7234                                    + ": match=" + pp.match(path)
7235                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7236                            if (ppwperm != null) {
7237                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7238                                        == PERMISSION_GRANTED) {
7239                                    writeMet = true;
7240                                } else {
7241                                    allowDefaultWrite = false;
7242                                }
7243                            }
7244                        }
7245                    }
7246                }
7247            }
7248
7249            // grant unprotected <provider> read/write, if not blocked by
7250            // <path-permission> above
7251            if (allowDefaultRead) readMet = true;
7252            if (allowDefaultWrite) writeMet = true;
7253
7254        } catch (RemoteException e) {
7255            return false;
7256        }
7257
7258        return readMet && writeMet;
7259    }
7260
7261    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7262        ProviderInfo pi = null;
7263        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7264        if (cpr != null) {
7265            pi = cpr.info;
7266        } else {
7267            try {
7268                pi = AppGlobals.getPackageManager().resolveContentProvider(
7269                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7270            } catch (RemoteException ex) {
7271            }
7272        }
7273        return pi;
7274    }
7275
7276    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7277        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7278        if (targetUris != null) {
7279            return targetUris.get(grantUri);
7280        }
7281        return null;
7282    }
7283
7284    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7285            String targetPkg, int targetUid, GrantUri grantUri) {
7286        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7287        if (targetUris == null) {
7288            targetUris = Maps.newArrayMap();
7289            mGrantedUriPermissions.put(targetUid, targetUris);
7290        }
7291
7292        UriPermission perm = targetUris.get(grantUri);
7293        if (perm == null) {
7294            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7295            targetUris.put(grantUri, perm);
7296        }
7297
7298        return perm;
7299    }
7300
7301    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7302            final int modeFlags) {
7303        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7304        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7305                : UriPermission.STRENGTH_OWNED;
7306
7307        // Root gets to do everything.
7308        if (uid == 0) {
7309            return true;
7310        }
7311
7312        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7313        if (perms == null) return false;
7314
7315        // First look for exact match
7316        final UriPermission exactPerm = perms.get(grantUri);
7317        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7318            return true;
7319        }
7320
7321        // No exact match, look for prefixes
7322        final int N = perms.size();
7323        for (int i = 0; i < N; i++) {
7324            final UriPermission perm = perms.valueAt(i);
7325            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7326                    && perm.getStrength(modeFlags) >= minStrength) {
7327                return true;
7328            }
7329        }
7330
7331        return false;
7332    }
7333
7334    /**
7335     * @param uri This uri must NOT contain an embedded userId.
7336     * @param userId The userId in which the uri is to be resolved.
7337     */
7338    @Override
7339    public int checkUriPermission(Uri uri, int pid, int uid,
7340            final int modeFlags, int userId, IBinder callerToken) {
7341        enforceNotIsolatedCaller("checkUriPermission");
7342
7343        // Another redirected-binder-call permissions check as in
7344        // {@link checkPermissionWithToken}.
7345        Identity tlsIdentity = sCallerIdentity.get();
7346        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7347            uid = tlsIdentity.uid;
7348            pid = tlsIdentity.pid;
7349        }
7350
7351        // Our own process gets to do everything.
7352        if (pid == MY_PID) {
7353            return PackageManager.PERMISSION_GRANTED;
7354        }
7355        synchronized (this) {
7356            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7357                    ? PackageManager.PERMISSION_GRANTED
7358                    : PackageManager.PERMISSION_DENIED;
7359        }
7360    }
7361
7362    /**
7363     * Check if the targetPkg can be granted permission to access uri by
7364     * the callingUid using the given modeFlags.  Throws a security exception
7365     * if callingUid is not allowed to do this.  Returns the uid of the target
7366     * if the URI permission grant should be performed; returns -1 if it is not
7367     * needed (for example targetPkg already has permission to access the URI).
7368     * If you already know the uid of the target, you can supply it in
7369     * lastTargetUid else set that to -1.
7370     */
7371    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7372            final int modeFlags, int lastTargetUid) {
7373        if (!Intent.isAccessUriMode(modeFlags)) {
7374            return -1;
7375        }
7376
7377        if (targetPkg != null) {
7378            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7379                    "Checking grant " + targetPkg + " permission to " + grantUri);
7380        }
7381
7382        final IPackageManager pm = AppGlobals.getPackageManager();
7383
7384        // If this is not a content: uri, we can't do anything with it.
7385        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7386            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7387                    "Can't grant URI permission for non-content URI: " + grantUri);
7388            return -1;
7389        }
7390
7391        final String authority = grantUri.uri.getAuthority();
7392        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7393        if (pi == null) {
7394            Slog.w(TAG, "No content provider found for permission check: " +
7395                    grantUri.uri.toSafeString());
7396            return -1;
7397        }
7398
7399        int targetUid = lastTargetUid;
7400        if (targetUid < 0 && targetPkg != null) {
7401            try {
7402                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7403                if (targetUid < 0) {
7404                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7405                            "Can't grant URI permission no uid for: " + targetPkg);
7406                    return -1;
7407                }
7408            } catch (RemoteException ex) {
7409                return -1;
7410            }
7411        }
7412
7413        if (targetUid >= 0) {
7414            // First...  does the target actually need this permission?
7415            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7416                // No need to grant the target this permission.
7417                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7418                        "Target " + targetPkg + " already has full permission to " + grantUri);
7419                return -1;
7420            }
7421        } else {
7422            // First...  there is no target package, so can anyone access it?
7423            boolean allowed = pi.exported;
7424            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7425                if (pi.readPermission != null) {
7426                    allowed = false;
7427                }
7428            }
7429            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7430                if (pi.writePermission != null) {
7431                    allowed = false;
7432                }
7433            }
7434            if (allowed) {
7435                return -1;
7436            }
7437        }
7438
7439        /* There is a special cross user grant if:
7440         * - The target is on another user.
7441         * - Apps on the current user can access the uri without any uid permissions.
7442         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7443         * grant uri permissions.
7444         */
7445        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7446                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7447                modeFlags, false /*without considering the uid permissions*/);
7448
7449        // Second...  is the provider allowing granting of URI permissions?
7450        if (!specialCrossUserGrant) {
7451            if (!pi.grantUriPermissions) {
7452                throw new SecurityException("Provider " + pi.packageName
7453                        + "/" + pi.name
7454                        + " does not allow granting of Uri permissions (uri "
7455                        + grantUri + ")");
7456            }
7457            if (pi.uriPermissionPatterns != null) {
7458                final int N = pi.uriPermissionPatterns.length;
7459                boolean allowed = false;
7460                for (int i=0; i<N; i++) {
7461                    if (pi.uriPermissionPatterns[i] != null
7462                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7463                        allowed = true;
7464                        break;
7465                    }
7466                }
7467                if (!allowed) {
7468                    throw new SecurityException("Provider " + pi.packageName
7469                            + "/" + pi.name
7470                            + " does not allow granting of permission to path of Uri "
7471                            + grantUri);
7472                }
7473            }
7474        }
7475
7476        // Third...  does the caller itself have permission to access
7477        // this uri?
7478        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7479            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7480                // Require they hold a strong enough Uri permission
7481                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7482                    throw new SecurityException("Uid " + callingUid
7483                            + " does not have permission to uri " + grantUri);
7484                }
7485            }
7486        }
7487        return targetUid;
7488    }
7489
7490    /**
7491     * @param uri This uri must NOT contain an embedded userId.
7492     * @param userId The userId in which the uri is to be resolved.
7493     */
7494    @Override
7495    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7496            final int modeFlags, int userId) {
7497        enforceNotIsolatedCaller("checkGrantUriPermission");
7498        synchronized(this) {
7499            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7500                    new GrantUri(userId, uri, false), modeFlags, -1);
7501        }
7502    }
7503
7504    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7505            final int modeFlags, UriPermissionOwner owner) {
7506        if (!Intent.isAccessUriMode(modeFlags)) {
7507            return;
7508        }
7509
7510        // So here we are: the caller has the assumed permission
7511        // to the uri, and the target doesn't.  Let's now give this to
7512        // the target.
7513
7514        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7515                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7516
7517        final String authority = grantUri.uri.getAuthority();
7518        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7519        if (pi == null) {
7520            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7521            return;
7522        }
7523
7524        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7525            grantUri.prefix = true;
7526        }
7527        final UriPermission perm = findOrCreateUriPermissionLocked(
7528                pi.packageName, targetPkg, targetUid, grantUri);
7529        perm.grantModes(modeFlags, owner);
7530    }
7531
7532    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7533            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7534        if (targetPkg == null) {
7535            throw new NullPointerException("targetPkg");
7536        }
7537        int targetUid;
7538        final IPackageManager pm = AppGlobals.getPackageManager();
7539        try {
7540            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7541        } catch (RemoteException ex) {
7542            return;
7543        }
7544
7545        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7546                targetUid);
7547        if (targetUid < 0) {
7548            return;
7549        }
7550
7551        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7552                owner);
7553    }
7554
7555    static class NeededUriGrants extends ArrayList<GrantUri> {
7556        final String targetPkg;
7557        final int targetUid;
7558        final int flags;
7559
7560        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7561            this.targetPkg = targetPkg;
7562            this.targetUid = targetUid;
7563            this.flags = flags;
7564        }
7565    }
7566
7567    /**
7568     * Like checkGrantUriPermissionLocked, but takes an Intent.
7569     */
7570    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7571            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7572        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7573                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7574                + " clip=" + (intent != null ? intent.getClipData() : null)
7575                + " from " + intent + "; flags=0x"
7576                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7577
7578        if (targetPkg == null) {
7579            throw new NullPointerException("targetPkg");
7580        }
7581
7582        if (intent == null) {
7583            return null;
7584        }
7585        Uri data = intent.getData();
7586        ClipData clip = intent.getClipData();
7587        if (data == null && clip == null) {
7588            return null;
7589        }
7590        // Default userId for uris in the intent (if they don't specify it themselves)
7591        int contentUserHint = intent.getContentUserHint();
7592        if (contentUserHint == UserHandle.USER_CURRENT) {
7593            contentUserHint = UserHandle.getUserId(callingUid);
7594        }
7595        final IPackageManager pm = AppGlobals.getPackageManager();
7596        int targetUid;
7597        if (needed != null) {
7598            targetUid = needed.targetUid;
7599        } else {
7600            try {
7601                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7602            } catch (RemoteException ex) {
7603                return null;
7604            }
7605            if (targetUid < 0) {
7606                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7607                        "Can't grant URI permission no uid for: " + targetPkg
7608                        + " on user " + targetUserId);
7609                return null;
7610            }
7611        }
7612        if (data != null) {
7613            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7614            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7615                    targetUid);
7616            if (targetUid > 0) {
7617                if (needed == null) {
7618                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7619                }
7620                needed.add(grantUri);
7621            }
7622        }
7623        if (clip != null) {
7624            for (int i=0; i<clip.getItemCount(); i++) {
7625                Uri uri = clip.getItemAt(i).getUri();
7626                if (uri != null) {
7627                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7628                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7629                            targetUid);
7630                    if (targetUid > 0) {
7631                        if (needed == null) {
7632                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7633                        }
7634                        needed.add(grantUri);
7635                    }
7636                } else {
7637                    Intent clipIntent = clip.getItemAt(i).getIntent();
7638                    if (clipIntent != null) {
7639                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7640                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7641                        if (newNeeded != null) {
7642                            needed = newNeeded;
7643                        }
7644                    }
7645                }
7646            }
7647        }
7648
7649        return needed;
7650    }
7651
7652    /**
7653     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7654     */
7655    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7656            UriPermissionOwner owner) {
7657        if (needed != null) {
7658            for (int i=0; i<needed.size(); i++) {
7659                GrantUri grantUri = needed.get(i);
7660                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7661                        grantUri, needed.flags, owner);
7662            }
7663        }
7664    }
7665
7666    void grantUriPermissionFromIntentLocked(int callingUid,
7667            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7668        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7669                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7670        if (needed == null) {
7671            return;
7672        }
7673
7674        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7675    }
7676
7677    /**
7678     * @param uri This uri must NOT contain an embedded userId.
7679     * @param userId The userId in which the uri is to be resolved.
7680     */
7681    @Override
7682    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7683            final int modeFlags, int userId) {
7684        enforceNotIsolatedCaller("grantUriPermission");
7685        GrantUri grantUri = new GrantUri(userId, uri, false);
7686        synchronized(this) {
7687            final ProcessRecord r = getRecordForAppLocked(caller);
7688            if (r == null) {
7689                throw new SecurityException("Unable to find app for caller "
7690                        + caller
7691                        + " when granting permission to uri " + grantUri);
7692            }
7693            if (targetPkg == null) {
7694                throw new IllegalArgumentException("null target");
7695            }
7696            if (grantUri == null) {
7697                throw new IllegalArgumentException("null uri");
7698            }
7699
7700            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7701                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7702                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7703                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7704
7705            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7706                    UserHandle.getUserId(r.uid));
7707        }
7708    }
7709
7710    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7711        if (perm.modeFlags == 0) {
7712            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7713                    perm.targetUid);
7714            if (perms != null) {
7715                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7716                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7717
7718                perms.remove(perm.uri);
7719                if (perms.isEmpty()) {
7720                    mGrantedUriPermissions.remove(perm.targetUid);
7721                }
7722            }
7723        }
7724    }
7725
7726    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7727        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7728                "Revoking all granted permissions to " + grantUri);
7729
7730        final IPackageManager pm = AppGlobals.getPackageManager();
7731        final String authority = grantUri.uri.getAuthority();
7732        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7733        if (pi == null) {
7734            Slog.w(TAG, "No content provider found for permission revoke: "
7735                    + grantUri.toSafeString());
7736            return;
7737        }
7738
7739        // Does the caller have this permission on the URI?
7740        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7741            // If they don't have direct access to the URI, then revoke any
7742            // ownerless URI permissions that have been granted to them.
7743            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7744            if (perms != null) {
7745                boolean persistChanged = false;
7746                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7747                    final UriPermission perm = it.next();
7748                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7749                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7750                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7751                                "Revoking non-owned " + perm.targetUid
7752                                + " permission to " + perm.uri);
7753                        persistChanged |= perm.revokeModes(
7754                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7755                        if (perm.modeFlags == 0) {
7756                            it.remove();
7757                        }
7758                    }
7759                }
7760                if (perms.isEmpty()) {
7761                    mGrantedUriPermissions.remove(callingUid);
7762                }
7763                if (persistChanged) {
7764                    schedulePersistUriGrants();
7765                }
7766            }
7767            return;
7768        }
7769
7770        boolean persistChanged = false;
7771
7772        // Go through all of the permissions and remove any that match.
7773        int N = mGrantedUriPermissions.size();
7774        for (int i = 0; i < N; i++) {
7775            final int targetUid = mGrantedUriPermissions.keyAt(i);
7776            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7777
7778            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7779                final UriPermission perm = it.next();
7780                if (perm.uri.sourceUserId == grantUri.sourceUserId
7781                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7782                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7783                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7784                    persistChanged |= perm.revokeModes(
7785                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7786                    if (perm.modeFlags == 0) {
7787                        it.remove();
7788                    }
7789                }
7790            }
7791
7792            if (perms.isEmpty()) {
7793                mGrantedUriPermissions.remove(targetUid);
7794                N--;
7795                i--;
7796            }
7797        }
7798
7799        if (persistChanged) {
7800            schedulePersistUriGrants();
7801        }
7802    }
7803
7804    /**
7805     * @param uri This uri must NOT contain an embedded userId.
7806     * @param userId The userId in which the uri is to be resolved.
7807     */
7808    @Override
7809    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7810            int userId) {
7811        enforceNotIsolatedCaller("revokeUriPermission");
7812        synchronized(this) {
7813            final ProcessRecord r = getRecordForAppLocked(caller);
7814            if (r == null) {
7815                throw new SecurityException("Unable to find app for caller "
7816                        + caller
7817                        + " when revoking permission to uri " + uri);
7818            }
7819            if (uri == null) {
7820                Slog.w(TAG, "revokeUriPermission: null uri");
7821                return;
7822            }
7823
7824            if (!Intent.isAccessUriMode(modeFlags)) {
7825                return;
7826            }
7827
7828            final String authority = uri.getAuthority();
7829            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7830            if (pi == null) {
7831                Slog.w(TAG, "No content provider found for permission revoke: "
7832                        + uri.toSafeString());
7833                return;
7834            }
7835
7836            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7837        }
7838    }
7839
7840    /**
7841     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7842     * given package.
7843     *
7844     * @param packageName Package name to match, or {@code null} to apply to all
7845     *            packages.
7846     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7847     *            to all users.
7848     * @param persistable If persistable grants should be removed.
7849     */
7850    private void removeUriPermissionsForPackageLocked(
7851            String packageName, int userHandle, boolean persistable) {
7852        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7853            throw new IllegalArgumentException("Must narrow by either package or user");
7854        }
7855
7856        boolean persistChanged = false;
7857
7858        int N = mGrantedUriPermissions.size();
7859        for (int i = 0; i < N; i++) {
7860            final int targetUid = mGrantedUriPermissions.keyAt(i);
7861            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7862
7863            // Only inspect grants matching user
7864            if (userHandle == UserHandle.USER_ALL
7865                    || userHandle == UserHandle.getUserId(targetUid)) {
7866                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7867                    final UriPermission perm = it.next();
7868
7869                    // Only inspect grants matching package
7870                    if (packageName == null || perm.sourcePkg.equals(packageName)
7871                            || perm.targetPkg.equals(packageName)) {
7872                        persistChanged |= perm.revokeModes(persistable
7873                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7874
7875                        // Only remove when no modes remain; any persisted grants
7876                        // will keep this alive.
7877                        if (perm.modeFlags == 0) {
7878                            it.remove();
7879                        }
7880                    }
7881                }
7882
7883                if (perms.isEmpty()) {
7884                    mGrantedUriPermissions.remove(targetUid);
7885                    N--;
7886                    i--;
7887                }
7888            }
7889        }
7890
7891        if (persistChanged) {
7892            schedulePersistUriGrants();
7893        }
7894    }
7895
7896    @Override
7897    public IBinder newUriPermissionOwner(String name) {
7898        enforceNotIsolatedCaller("newUriPermissionOwner");
7899        synchronized(this) {
7900            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7901            return owner.getExternalTokenLocked();
7902        }
7903    }
7904
7905    /**
7906     * @param uri This uri must NOT contain an embedded userId.
7907     * @param sourceUserId The userId in which the uri is to be resolved.
7908     * @param targetUserId The userId of the app that receives the grant.
7909     */
7910    @Override
7911    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7912            final int modeFlags, int sourceUserId, int targetUserId) {
7913        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7914                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7915        synchronized(this) {
7916            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7917            if (owner == null) {
7918                throw new IllegalArgumentException("Unknown owner: " + token);
7919            }
7920            if (fromUid != Binder.getCallingUid()) {
7921                if (Binder.getCallingUid() != Process.myUid()) {
7922                    // Only system code can grant URI permissions on behalf
7923                    // of other users.
7924                    throw new SecurityException("nice try");
7925                }
7926            }
7927            if (targetPkg == null) {
7928                throw new IllegalArgumentException("null target");
7929            }
7930            if (uri == null) {
7931                throw new IllegalArgumentException("null uri");
7932            }
7933
7934            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7935                    modeFlags, owner, targetUserId);
7936        }
7937    }
7938
7939    /**
7940     * @param uri This uri must NOT contain an embedded userId.
7941     * @param userId The userId in which the uri is to be resolved.
7942     */
7943    @Override
7944    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7945        synchronized(this) {
7946            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7947            if (owner == null) {
7948                throw new IllegalArgumentException("Unknown owner: " + token);
7949            }
7950
7951            if (uri == null) {
7952                owner.removeUriPermissionsLocked(mode);
7953            } else {
7954                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7955            }
7956        }
7957    }
7958
7959    private void schedulePersistUriGrants() {
7960        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7961            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7962                    10 * DateUtils.SECOND_IN_MILLIS);
7963        }
7964    }
7965
7966    private void writeGrantedUriPermissions() {
7967        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7968
7969        // Snapshot permissions so we can persist without lock
7970        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7971        synchronized (this) {
7972            final int size = mGrantedUriPermissions.size();
7973            for (int i = 0; i < size; i++) {
7974                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7975                for (UriPermission perm : perms.values()) {
7976                    if (perm.persistedModeFlags != 0) {
7977                        persist.add(perm.snapshot());
7978                    }
7979                }
7980            }
7981        }
7982
7983        FileOutputStream fos = null;
7984        try {
7985            fos = mGrantFile.startWrite();
7986
7987            XmlSerializer out = new FastXmlSerializer();
7988            out.setOutput(fos, StandardCharsets.UTF_8.name());
7989            out.startDocument(null, true);
7990            out.startTag(null, TAG_URI_GRANTS);
7991            for (UriPermission.Snapshot perm : persist) {
7992                out.startTag(null, TAG_URI_GRANT);
7993                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7994                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7995                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7996                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7997                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7998                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7999                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8000                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8001                out.endTag(null, TAG_URI_GRANT);
8002            }
8003            out.endTag(null, TAG_URI_GRANTS);
8004            out.endDocument();
8005
8006            mGrantFile.finishWrite(fos);
8007        } catch (IOException e) {
8008            if (fos != null) {
8009                mGrantFile.failWrite(fos);
8010            }
8011        }
8012    }
8013
8014    private void readGrantedUriPermissionsLocked() {
8015        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8016
8017        final long now = System.currentTimeMillis();
8018
8019        FileInputStream fis = null;
8020        try {
8021            fis = mGrantFile.openRead();
8022            final XmlPullParser in = Xml.newPullParser();
8023            in.setInput(fis, StandardCharsets.UTF_8.name());
8024
8025            int type;
8026            while ((type = in.next()) != END_DOCUMENT) {
8027                final String tag = in.getName();
8028                if (type == START_TAG) {
8029                    if (TAG_URI_GRANT.equals(tag)) {
8030                        final int sourceUserId;
8031                        final int targetUserId;
8032                        final int userHandle = readIntAttribute(in,
8033                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8034                        if (userHandle != UserHandle.USER_NULL) {
8035                            // For backwards compatibility.
8036                            sourceUserId = userHandle;
8037                            targetUserId = userHandle;
8038                        } else {
8039                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8040                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8041                        }
8042                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8043                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8044                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8045                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8046                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8047                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8048
8049                        // Sanity check that provider still belongs to source package
8050                        final ProviderInfo pi = getProviderInfoLocked(
8051                                uri.getAuthority(), sourceUserId);
8052                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8053                            int targetUid = -1;
8054                            try {
8055                                targetUid = AppGlobals.getPackageManager()
8056                                        .getPackageUid(targetPkg, targetUserId);
8057                            } catch (RemoteException e) {
8058                            }
8059                            if (targetUid != -1) {
8060                                final UriPermission perm = findOrCreateUriPermissionLocked(
8061                                        sourcePkg, targetPkg, targetUid,
8062                                        new GrantUri(sourceUserId, uri, prefix));
8063                                perm.initPersistedModes(modeFlags, createdTime);
8064                            }
8065                        } else {
8066                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8067                                    + " but instead found " + pi);
8068                        }
8069                    }
8070                }
8071            }
8072        } catch (FileNotFoundException e) {
8073            // Missing grants is okay
8074        } catch (IOException e) {
8075            Slog.wtf(TAG, "Failed reading Uri grants", e);
8076        } catch (XmlPullParserException e) {
8077            Slog.wtf(TAG, "Failed reading Uri grants", e);
8078        } finally {
8079            IoUtils.closeQuietly(fis);
8080        }
8081    }
8082
8083    /**
8084     * @param uri This uri must NOT contain an embedded userId.
8085     * @param userId The userId in which the uri is to be resolved.
8086     */
8087    @Override
8088    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8089        enforceNotIsolatedCaller("takePersistableUriPermission");
8090
8091        Preconditions.checkFlagsArgument(modeFlags,
8092                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8093
8094        synchronized (this) {
8095            final int callingUid = Binder.getCallingUid();
8096            boolean persistChanged = false;
8097            GrantUri grantUri = new GrantUri(userId, uri, false);
8098
8099            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8100                    new GrantUri(userId, uri, false));
8101            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8102                    new GrantUri(userId, uri, true));
8103
8104            final boolean exactValid = (exactPerm != null)
8105                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8106            final boolean prefixValid = (prefixPerm != null)
8107                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8108
8109            if (!(exactValid || prefixValid)) {
8110                throw new SecurityException("No persistable permission grants found for UID "
8111                        + callingUid + " and Uri " + grantUri.toSafeString());
8112            }
8113
8114            if (exactValid) {
8115                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8116            }
8117            if (prefixValid) {
8118                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8119            }
8120
8121            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8122
8123            if (persistChanged) {
8124                schedulePersistUriGrants();
8125            }
8126        }
8127    }
8128
8129    /**
8130     * @param uri This uri must NOT contain an embedded userId.
8131     * @param userId The userId in which the uri is to be resolved.
8132     */
8133    @Override
8134    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8135        enforceNotIsolatedCaller("releasePersistableUriPermission");
8136
8137        Preconditions.checkFlagsArgument(modeFlags,
8138                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8139
8140        synchronized (this) {
8141            final int callingUid = Binder.getCallingUid();
8142            boolean persistChanged = false;
8143
8144            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8145                    new GrantUri(userId, uri, false));
8146            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8147                    new GrantUri(userId, uri, true));
8148            if (exactPerm == null && prefixPerm == null) {
8149                throw new SecurityException("No permission grants found for UID " + callingUid
8150                        + " and Uri " + uri.toSafeString());
8151            }
8152
8153            if (exactPerm != null) {
8154                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8155                removeUriPermissionIfNeededLocked(exactPerm);
8156            }
8157            if (prefixPerm != null) {
8158                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8159                removeUriPermissionIfNeededLocked(prefixPerm);
8160            }
8161
8162            if (persistChanged) {
8163                schedulePersistUriGrants();
8164            }
8165        }
8166    }
8167
8168    /**
8169     * Prune any older {@link UriPermission} for the given UID until outstanding
8170     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8171     *
8172     * @return if any mutations occured that require persisting.
8173     */
8174    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8175        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8176        if (perms == null) return false;
8177        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8178
8179        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8180        for (UriPermission perm : perms.values()) {
8181            if (perm.persistedModeFlags != 0) {
8182                persisted.add(perm);
8183            }
8184        }
8185
8186        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8187        if (trimCount <= 0) return false;
8188
8189        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8190        for (int i = 0; i < trimCount; i++) {
8191            final UriPermission perm = persisted.get(i);
8192
8193            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8194                    "Trimming grant created at " + perm.persistedCreateTime);
8195
8196            perm.releasePersistableModes(~0);
8197            removeUriPermissionIfNeededLocked(perm);
8198        }
8199
8200        return true;
8201    }
8202
8203    @Override
8204    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8205            String packageName, boolean incoming) {
8206        enforceNotIsolatedCaller("getPersistedUriPermissions");
8207        Preconditions.checkNotNull(packageName, "packageName");
8208
8209        final int callingUid = Binder.getCallingUid();
8210        final IPackageManager pm = AppGlobals.getPackageManager();
8211        try {
8212            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8213            if (packageUid != callingUid) {
8214                throw new SecurityException(
8215                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8216            }
8217        } catch (RemoteException e) {
8218            throw new SecurityException("Failed to verify package name ownership");
8219        }
8220
8221        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8222        synchronized (this) {
8223            if (incoming) {
8224                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8225                        callingUid);
8226                if (perms == null) {
8227                    Slog.w(TAG, "No permission grants found for " + packageName);
8228                } else {
8229                    for (UriPermission perm : perms.values()) {
8230                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8231                            result.add(perm.buildPersistedPublicApiObject());
8232                        }
8233                    }
8234                }
8235            } else {
8236                final int size = mGrantedUriPermissions.size();
8237                for (int i = 0; i < size; i++) {
8238                    final ArrayMap<GrantUri, UriPermission> perms =
8239                            mGrantedUriPermissions.valueAt(i);
8240                    for (UriPermission perm : perms.values()) {
8241                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8242                            result.add(perm.buildPersistedPublicApiObject());
8243                        }
8244                    }
8245                }
8246            }
8247        }
8248        return new ParceledListSlice<android.content.UriPermission>(result);
8249    }
8250
8251    @Override
8252    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8253        synchronized (this) {
8254            ProcessRecord app =
8255                who != null ? getRecordForAppLocked(who) : null;
8256            if (app == null) return;
8257
8258            Message msg = Message.obtain();
8259            msg.what = WAIT_FOR_DEBUGGER_MSG;
8260            msg.obj = app;
8261            msg.arg1 = waiting ? 1 : 0;
8262            mUiHandler.sendMessage(msg);
8263        }
8264    }
8265
8266    @Override
8267    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8268        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8269        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8270        outInfo.availMem = Process.getFreeMemory();
8271        outInfo.totalMem = Process.getTotalMemory();
8272        outInfo.threshold = homeAppMem;
8273        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8274        outInfo.hiddenAppThreshold = cachedAppMem;
8275        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8276                ProcessList.SERVICE_ADJ);
8277        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8278                ProcessList.VISIBLE_APP_ADJ);
8279        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8280                ProcessList.FOREGROUND_APP_ADJ);
8281    }
8282
8283    // =========================================================
8284    // TASK MANAGEMENT
8285    // =========================================================
8286
8287    @Override
8288    public List<IAppTask> getAppTasks(String callingPackage) {
8289        int callingUid = Binder.getCallingUid();
8290        long ident = Binder.clearCallingIdentity();
8291
8292        synchronized(this) {
8293            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8294            try {
8295                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8296
8297                final int N = mRecentTasks.size();
8298                for (int i = 0; i < N; i++) {
8299                    TaskRecord tr = mRecentTasks.get(i);
8300                    // Skip tasks that do not match the caller.  We don't need to verify
8301                    // callingPackage, because we are also limiting to callingUid and know
8302                    // that will limit to the correct security sandbox.
8303                    if (tr.effectiveUid != callingUid) {
8304                        continue;
8305                    }
8306                    Intent intent = tr.getBaseIntent();
8307                    if (intent == null ||
8308                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8309                        continue;
8310                    }
8311                    ActivityManager.RecentTaskInfo taskInfo =
8312                            createRecentTaskInfoFromTaskRecord(tr);
8313                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8314                    list.add(taskImpl);
8315                }
8316            } finally {
8317                Binder.restoreCallingIdentity(ident);
8318            }
8319            return list;
8320        }
8321    }
8322
8323    @Override
8324    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8325        final int callingUid = Binder.getCallingUid();
8326        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8327
8328        synchronized(this) {
8329            if (DEBUG_ALL) Slog.v(
8330                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8331
8332            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8333                    callingUid);
8334
8335            // TODO: Improve with MRU list from all ActivityStacks.
8336            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8337        }
8338
8339        return list;
8340    }
8341
8342    /**
8343     * Creates a new RecentTaskInfo from a TaskRecord.
8344     */
8345    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8346        // Update the task description to reflect any changes in the task stack
8347        tr.updateTaskDescription();
8348
8349        // Compose the recent task info
8350        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8351        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8352        rti.persistentId = tr.taskId;
8353        rti.baseIntent = new Intent(tr.getBaseIntent());
8354        rti.origActivity = tr.origActivity;
8355        rti.realActivity = tr.realActivity;
8356        rti.description = tr.lastDescription;
8357        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8358        rti.userId = tr.userId;
8359        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8360        rti.firstActiveTime = tr.firstActiveTime;
8361        rti.lastActiveTime = tr.lastActiveTime;
8362        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8363        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8364        rti.numActivities = 0;
8365
8366        ActivityRecord base = null;
8367        ActivityRecord top = null;
8368        ActivityRecord tmp;
8369
8370        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8371            tmp = tr.mActivities.get(i);
8372            if (tmp.finishing) {
8373                continue;
8374            }
8375            base = tmp;
8376            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8377                top = base;
8378            }
8379            rti.numActivities++;
8380        }
8381
8382        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8383        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8384
8385        return rti;
8386    }
8387
8388    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8389        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8390                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8391        if (!allowed) {
8392            if (checkPermission(android.Manifest.permission.GET_TASKS,
8393                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8394                // Temporary compatibility: some existing apps on the system image may
8395                // still be requesting the old permission and not switched to the new
8396                // one; if so, we'll still allow them full access.  This means we need
8397                // to see if they are holding the old permission and are a system app.
8398                try {
8399                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8400                        allowed = true;
8401                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8402                                + " is using old GET_TASKS but privileged; allowing");
8403                    }
8404                } catch (RemoteException e) {
8405                }
8406            }
8407        }
8408        if (!allowed) {
8409            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8410                    + " does not hold REAL_GET_TASKS; limiting output");
8411        }
8412        return allowed;
8413    }
8414
8415    @Override
8416    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8417        final int callingUid = Binder.getCallingUid();
8418        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8419                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8420
8421        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8422        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8423        synchronized (this) {
8424            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8425                    callingUid);
8426            final boolean detailed = checkCallingPermission(
8427                    android.Manifest.permission.GET_DETAILED_TASKS)
8428                    == PackageManager.PERMISSION_GRANTED;
8429
8430            final int recentsCount = mRecentTasks.size();
8431            ArrayList<ActivityManager.RecentTaskInfo> res =
8432                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8433
8434            final Set<Integer> includedUsers;
8435            if (includeProfiles) {
8436                includedUsers = getProfileIdsLocked(userId);
8437            } else {
8438                includedUsers = new HashSet<>();
8439            }
8440            includedUsers.add(Integer.valueOf(userId));
8441
8442            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8443                TaskRecord tr = mRecentTasks.get(i);
8444                // Only add calling user or related users recent tasks
8445                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8446                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8447                    continue;
8448                }
8449
8450                // Return the entry if desired by the caller.  We always return
8451                // the first entry, because callers always expect this to be the
8452                // foreground app.  We may filter others if the caller has
8453                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8454                // we should exclude the entry.
8455
8456                if (i == 0
8457                        || withExcluded
8458                        || (tr.intent == null)
8459                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8460                                == 0)) {
8461                    if (!allowed) {
8462                        // If the caller doesn't have the GET_TASKS permission, then only
8463                        // allow them to see a small subset of tasks -- their own and home.
8464                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8465                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8466                            continue;
8467                        }
8468                    }
8469                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8470                        if (tr.stack != null && tr.stack.isHomeStack()) {
8471                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8472                                    "Skipping, home stack task: " + tr);
8473                            continue;
8474                        }
8475                    }
8476                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8477                        // Don't include auto remove tasks that are finished or finishing.
8478                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8479                                "Skipping, auto-remove without activity: " + tr);
8480                        continue;
8481                    }
8482                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8483                            && !tr.isAvailable) {
8484                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8485                                "Skipping, unavail real act: " + tr);
8486                        continue;
8487                    }
8488
8489                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8490                    if (!detailed) {
8491                        rti.baseIntent.replaceExtras((Bundle)null);
8492                    }
8493
8494                    res.add(rti);
8495                    maxNum--;
8496                }
8497            }
8498            return res;
8499        }
8500    }
8501
8502    @Override
8503    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8504        synchronized (this) {
8505            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8506                    "getTaskThumbnail()");
8507            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8508                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8509            if (tr != null) {
8510                return tr.getTaskThumbnailLocked();
8511            }
8512        }
8513        return null;
8514    }
8515
8516    @Override
8517    public int addAppTask(IBinder activityToken, Intent intent,
8518            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8519        final int callingUid = Binder.getCallingUid();
8520        final long callingIdent = Binder.clearCallingIdentity();
8521
8522        try {
8523            synchronized (this) {
8524                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8525                if (r == null) {
8526                    throw new IllegalArgumentException("Activity does not exist; token="
8527                            + activityToken);
8528                }
8529                ComponentName comp = intent.getComponent();
8530                if (comp == null) {
8531                    throw new IllegalArgumentException("Intent " + intent
8532                            + " must specify explicit component");
8533                }
8534                if (thumbnail.getWidth() != mThumbnailWidth
8535                        || thumbnail.getHeight() != mThumbnailHeight) {
8536                    throw new IllegalArgumentException("Bad thumbnail size: got "
8537                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8538                            + mThumbnailWidth + "x" + mThumbnailHeight);
8539                }
8540                if (intent.getSelector() != null) {
8541                    intent.setSelector(null);
8542                }
8543                if (intent.getSourceBounds() != null) {
8544                    intent.setSourceBounds(null);
8545                }
8546                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8547                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8548                        // The caller has added this as an auto-remove task...  that makes no
8549                        // sense, so turn off auto-remove.
8550                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8551                    }
8552                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8553                    // Must be a new task.
8554                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8555                }
8556                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8557                    mLastAddedTaskActivity = null;
8558                }
8559                ActivityInfo ainfo = mLastAddedTaskActivity;
8560                if (ainfo == null) {
8561                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8562                            comp, 0, UserHandle.getUserId(callingUid));
8563                    if (ainfo.applicationInfo.uid != callingUid) {
8564                        throw new SecurityException(
8565                                "Can't add task for another application: target uid="
8566                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8567                    }
8568                }
8569
8570                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8571                        intent, description);
8572
8573                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8574                if (trimIdx >= 0) {
8575                    // If this would have caused a trim, then we'll abort because that
8576                    // means it would be added at the end of the list but then just removed.
8577                    return INVALID_TASK_ID;
8578                }
8579
8580                final int N = mRecentTasks.size();
8581                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8582                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8583                    tr.removedFromRecents();
8584                }
8585
8586                task.inRecents = true;
8587                mRecentTasks.add(task);
8588                r.task.stack.addTask(task, false, false);
8589
8590                task.setLastThumbnail(thumbnail);
8591                task.freeLastThumbnail();
8592
8593                return task.taskId;
8594            }
8595        } finally {
8596            Binder.restoreCallingIdentity(callingIdent);
8597        }
8598    }
8599
8600    @Override
8601    public Point getAppTaskThumbnailSize() {
8602        synchronized (this) {
8603            return new Point(mThumbnailWidth,  mThumbnailHeight);
8604        }
8605    }
8606
8607    @Override
8608    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8609        synchronized (this) {
8610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8611            if (r != null) {
8612                r.setTaskDescription(td);
8613                r.task.updateTaskDescription();
8614            }
8615        }
8616    }
8617
8618    @Override
8619    public void setTaskResizeable(int taskId, boolean resizeable) {
8620        synchronized (this) {
8621            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8622                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8623            if (task == null) {
8624                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8625                return;
8626            }
8627            if (task.mResizeable != resizeable) {
8628                task.mResizeable = resizeable;
8629                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8630                mStackSupervisor.resumeTopActivitiesLocked();
8631            }
8632        }
8633    }
8634
8635    @Override
8636    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8637        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8638                "resizeTask()");
8639        long ident = Binder.clearCallingIdentity();
8640        try {
8641            synchronized (this) {
8642                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8643                if (task == null) {
8644                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8645                    return;
8646                }
8647                // Place the task in the right stack if it isn't there already based on
8648                // the requested bounds.
8649                // The stack transition logic is:
8650                // - a null bounds on a freeform task moves that task to fullscreen
8651                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8652                //   that task to freeform
8653                // - otherwise the task is not moved
8654                // Note it's not allowed to resize a home, docked, or pinned stack task.
8655                int stackId = task.stack.mStackId;
8656                if (stackId == HOME_STACK_ID || stackId == DOCKED_STACK_ID
8657                        || stackId == PINNED_STACK_ID) {
8658                    throw new IllegalArgumentException("trying to resizeTask on a "
8659                            + "home or docked task");
8660                }
8661                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8662                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8663                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8664                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8665                }
8666                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8667                if (stackId != task.stack.mStackId) {
8668                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8669                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8670                    preserveWindow = false;
8671                }
8672
8673                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8674            }
8675        } finally {
8676            Binder.restoreCallingIdentity(ident);
8677        }
8678    }
8679
8680    @Override
8681    public Rect getTaskBounds(int taskId) {
8682        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8683                "getTaskBounds()");
8684        long ident = Binder.clearCallingIdentity();
8685        Rect rect = new Rect();
8686        try {
8687            synchronized (this) {
8688                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8689                if (task == null) {
8690                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8691                    return rect;
8692                }
8693                mWindowManager.getTaskBounds(task.taskId, rect);
8694            }
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698        return rect;
8699    }
8700
8701    @Override
8702    public Bitmap getTaskDescriptionIcon(String filename) {
8703        if (!FileUtils.isValidExtFilename(filename)
8704                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8705            throw new IllegalArgumentException("Bad filename: " + filename);
8706        }
8707        return mTaskPersister.getTaskDescriptionIcon(filename);
8708    }
8709
8710    @Override
8711    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8712            throws RemoteException {
8713        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8714                opts.getCustomInPlaceResId() == 0) {
8715            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8716                    "with valid animation");
8717        }
8718        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8719        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8720                opts.getCustomInPlaceResId());
8721        mWindowManager.executeAppTransition();
8722    }
8723
8724    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
8725            boolean removeFromRecents) {
8726        if (removeFromRecents) {
8727            mRecentTasks.remove(tr);
8728            tr.removedFromRecents();
8729        }
8730        ComponentName component = tr.getBaseIntent().getComponent();
8731        if (component == null) {
8732            Slog.w(TAG, "No component for base intent of task: " + tr);
8733            return;
8734        }
8735
8736        // Find any running services associated with this app and stop if needed.
8737        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8738
8739        if (!killProcess) {
8740            return;
8741        }
8742
8743        // Determine if the process(es) for this task should be killed.
8744        final String pkg = component.getPackageName();
8745        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8746        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8747        for (int i = 0; i < pmap.size(); i++) {
8748
8749            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8750            for (int j = 0; j < uids.size(); j++) {
8751                ProcessRecord proc = uids.valueAt(j);
8752                if (proc.userId != tr.userId) {
8753                    // Don't kill process for a different user.
8754                    continue;
8755                }
8756                if (proc == mHomeProcess) {
8757                    // Don't kill the home process along with tasks from the same package.
8758                    continue;
8759                }
8760                if (!proc.pkgList.containsKey(pkg)) {
8761                    // Don't kill process that is not associated with this task.
8762                    continue;
8763                }
8764
8765                for (int k = 0; k < proc.activities.size(); k++) {
8766                    TaskRecord otherTask = proc.activities.get(k).task;
8767                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8768                        // Don't kill process(es) that has an activity in a different task that is
8769                        // also in recents.
8770                        return;
8771                    }
8772                }
8773
8774                if (proc.foregroundServices) {
8775                    // Don't kill process(es) with foreground service.
8776                    return;
8777                }
8778
8779                // Add process to kill list.
8780                procsToKill.add(proc);
8781            }
8782        }
8783
8784        // Kill the running processes.
8785        for (int i = 0; i < procsToKill.size(); i++) {
8786            ProcessRecord pr = procsToKill.get(i);
8787            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8788                    && pr.curReceiver == null) {
8789                pr.kill("remove task", true);
8790            } else {
8791                // We delay killing processes that are not in the background or running a receiver.
8792                pr.waitingToKill = "remove task";
8793            }
8794        }
8795    }
8796
8797    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8798        // Remove all tasks with activities in the specified package from the list of recent tasks
8799        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8800            TaskRecord tr = mRecentTasks.get(i);
8801            if (tr.userId != userId) continue;
8802
8803            ComponentName cn = tr.intent.getComponent();
8804            if (cn != null && cn.getPackageName().equals(packageName)) {
8805                // If the package name matches, remove the task.
8806                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
8807            }
8808        }
8809    }
8810
8811    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8812            int userId) {
8813
8814        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8815            TaskRecord tr = mRecentTasks.get(i);
8816            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8817                continue;
8818            }
8819
8820            ComponentName cn = tr.intent.getComponent();
8821            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8822                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8823            if (sameComponent) {
8824                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
8825            }
8826        }
8827    }
8828
8829    /**
8830     * Removes the task with the specified task id.
8831     *
8832     * @param taskId Identifier of the task to be removed.
8833     * @param killProcess Kill any process associated with the task if possible.
8834     * @param removeFromRecents Whether to also remove the task from recents.
8835     * @return Returns true if the given task was found and removed.
8836     */
8837    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
8838            boolean removeFromRecents) {
8839        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8840                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8841        if (tr != null) {
8842            tr.removeTaskActivitiesLocked();
8843            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
8844            if (tr.isPersistable) {
8845                notifyTaskPersisterLocked(null, true);
8846            }
8847            return true;
8848        }
8849        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8850        return false;
8851    }
8852
8853    @Override
8854    public boolean removeTask(int taskId) {
8855        synchronized (this) {
8856            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8857                    "removeTask()");
8858            long ident = Binder.clearCallingIdentity();
8859            try {
8860                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
8861            } finally {
8862                Binder.restoreCallingIdentity(ident);
8863            }
8864        }
8865    }
8866
8867    /**
8868     * TODO: Add mController hook
8869     */
8870    @Override
8871    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8872        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8873
8874        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8875        synchronized(this) {
8876            moveTaskToFrontLocked(taskId, flags, options);
8877        }
8878    }
8879
8880    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8881        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8882                Binder.getCallingUid(), -1, -1, "Task to front")) {
8883            ActivityOptions.abort(options);
8884            return;
8885        }
8886        final long origId = Binder.clearCallingIdentity();
8887        try {
8888            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8889            if (task == null) {
8890                Slog.d(TAG, "Could not find task for id: "+ taskId);
8891                return;
8892            }
8893            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8894                mStackSupervisor.showLockTaskToast();
8895                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8896                return;
8897            }
8898            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8899            if (prev != null && prev.isRecentsActivity()) {
8900                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8901            }
8902            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8903        } finally {
8904            Binder.restoreCallingIdentity(origId);
8905        }
8906        ActivityOptions.abort(options);
8907    }
8908
8909    /**
8910     * Moves an activity, and all of the other activities within the same task, to the bottom
8911     * of the history stack.  The activity's order within the task is unchanged.
8912     *
8913     * @param token A reference to the activity we wish to move
8914     * @param nonRoot If false then this only works if the activity is the root
8915     *                of a task; if true it will work for any activity in a task.
8916     * @return Returns true if the move completed, false if not.
8917     */
8918    @Override
8919    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8920        enforceNotIsolatedCaller("moveActivityTaskToBack");
8921        synchronized(this) {
8922            final long origId = Binder.clearCallingIdentity();
8923            try {
8924                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8925                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8926                if (task != null) {
8927                    if (mStackSupervisor.isLockedTask(task)) {
8928                        mStackSupervisor.showLockTaskToast();
8929                        return false;
8930                    }
8931                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8932                }
8933            } finally {
8934                Binder.restoreCallingIdentity(origId);
8935            }
8936        }
8937        return false;
8938    }
8939
8940    @Override
8941    public void moveTaskBackwards(int task) {
8942        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8943                "moveTaskBackwards()");
8944
8945        synchronized(this) {
8946            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8947                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8948                return;
8949            }
8950            final long origId = Binder.clearCallingIdentity();
8951            moveTaskBackwardsLocked(task);
8952            Binder.restoreCallingIdentity(origId);
8953        }
8954    }
8955
8956    private final void moveTaskBackwardsLocked(int task) {
8957        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8958    }
8959
8960    @Override
8961    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8962            IActivityContainerCallback callback) throws RemoteException {
8963        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8964                "createActivityContainer()");
8965        synchronized (this) {
8966            if (parentActivityToken == null) {
8967                throw new IllegalArgumentException("parent token must not be null");
8968            }
8969            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8970            if (r == null) {
8971                return null;
8972            }
8973            if (callback == null) {
8974                throw new IllegalArgumentException("callback must not be null");
8975            }
8976            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8977        }
8978    }
8979
8980    @Override
8981    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8982        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8983                "deleteActivityContainer()");
8984        synchronized (this) {
8985            mStackSupervisor.deleteActivityContainer(container);
8986        }
8987    }
8988
8989    @Override
8990    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8991        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8992                "createStackOnDisplay()");
8993        synchronized (this) {
8994            final int stackId = mStackSupervisor.getNextStackId();
8995            final ActivityStack stack =
8996                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
8997            if (stack == null) {
8998                return null;
8999            }
9000            return stack.mActivityContainer;
9001        }
9002    }
9003
9004    @Override
9005    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9006        synchronized (this) {
9007            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9008            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9009                return stack.mActivityContainer.getDisplayId();
9010            }
9011            return Display.DEFAULT_DISPLAY;
9012        }
9013    }
9014
9015    @Override
9016    public int getActivityStackId(IBinder token) throws RemoteException {
9017        synchronized (this) {
9018            ActivityStack stack = ActivityRecord.getStackLocked(token);
9019            if (stack == null) {
9020                return INVALID_STACK_ID;
9021            }
9022            return stack.mStackId;
9023        }
9024    }
9025
9026    @Override
9027    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9028        if (stackId == HOME_STACK_ID) {
9029            throw new IllegalArgumentException(
9030                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9031        }
9032        synchronized (this) {
9033            long ident = Binder.clearCallingIdentity();
9034            try {
9035                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9036                if (r == null) {
9037                    throw new IllegalArgumentException(
9038                            "moveActivityToStack: No activity record matching token=" + token);
9039                }
9040                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9041                        + " to stackId=" + stackId);
9042                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9043                        "moveActivityToStack");
9044            } finally {
9045                Binder.restoreCallingIdentity(ident);
9046            }
9047        }
9048    }
9049
9050    @Override
9051    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9052        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9053                "moveTaskToStack()");
9054        if (stackId == HOME_STACK_ID) {
9055            throw new IllegalArgumentException(
9056                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9057        }
9058        synchronized (this) {
9059            long ident = Binder.clearCallingIdentity();
9060            try {
9061                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9062                        + " to stackId=" + stackId + " toTop=" + toTop);
9063                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9064                        "moveTaskToStack");
9065            } finally {
9066                Binder.restoreCallingIdentity(ident);
9067            }
9068        }
9069    }
9070
9071    /**
9072     * Moves the input task to the docked stack.
9073     *
9074     * @param taskId Id of task to move.
9075     * @param createMode The mode the docked stack should be created in if it doesn't exist
9076     *                   already. See
9077     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9078     *                   and
9079     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9080     * @param toTop If the task and stack should be moved to the top.
9081     */
9082    @Override
9083    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) {
9084        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9085                "moveTaskToDockedStack()");
9086        synchronized (this) {
9087            long ident = Binder.clearCallingIdentity();
9088            try {
9089                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9090                        + " to createMode=" + createMode + " toTop=" + toTop);
9091                mWindowManager.setDockedStackCreateMode(createMode);
9092                mStackSupervisor.moveTaskToStackLocked(
9093                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack");
9094            } finally {
9095                Binder.restoreCallingIdentity(ident);
9096            }
9097        }
9098    }
9099
9100    /**
9101     * Moves the top activity in the input stackId to the pinned stack.
9102     *
9103     * @param stackId Id of stack to move the top activity to pinned stack.
9104     * @param bounds Bounds to use for pinned stack.
9105     *
9106     * @return True if the top activity of the input stack was successfully moved to the pinned
9107     *          stack.
9108     */
9109    @Override
9110    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9111        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9112                "moveTopActivityToPinnedStack()");
9113        synchronized (this) {
9114            long ident = Binder.clearCallingIdentity();
9115            try {
9116                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9117            } finally {
9118                Binder.restoreCallingIdentity(ident);
9119            }
9120        }
9121    }
9122
9123    @Override
9124    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9125        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9126                "resizeStack()");
9127        long ident = Binder.clearCallingIdentity();
9128        try {
9129            synchronized (this) {
9130                mStackSupervisor.resizeStackLocked(
9131                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9132            }
9133        } finally {
9134            Binder.restoreCallingIdentity(ident);
9135        }
9136    }
9137
9138    @Override
9139    public void positionTaskInStack(int taskId, int stackId, int position) {
9140        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9141                "positionTaskInStack()");
9142        if (stackId == HOME_STACK_ID) {
9143            throw new IllegalArgumentException(
9144                    "positionTaskInStack: Attempt to change the position of task "
9145                    + taskId + " in/to home stack");
9146        }
9147        synchronized (this) {
9148            long ident = Binder.clearCallingIdentity();
9149            try {
9150                if (DEBUG_STACK) Slog.d(TAG_STACK,
9151                        "positionTaskInStack: positioning task=" + taskId
9152                        + " in stackId=" + stackId + " at position=" + position);
9153                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9154            } finally {
9155                Binder.restoreCallingIdentity(ident);
9156            }
9157        }
9158    }
9159
9160    @Override
9161    public List<StackInfo> getAllStackInfos() {
9162        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9163                "getAllStackInfos()");
9164        long ident = Binder.clearCallingIdentity();
9165        try {
9166            synchronized (this) {
9167                return mStackSupervisor.getAllStackInfosLocked();
9168            }
9169        } finally {
9170            Binder.restoreCallingIdentity(ident);
9171        }
9172    }
9173
9174    @Override
9175    public StackInfo getStackInfo(int stackId) {
9176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9177                "getStackInfo()");
9178        long ident = Binder.clearCallingIdentity();
9179        try {
9180            synchronized (this) {
9181                return mStackSupervisor.getStackInfoLocked(stackId);
9182            }
9183        } finally {
9184            Binder.restoreCallingIdentity(ident);
9185        }
9186    }
9187
9188    @Override
9189    public boolean isInHomeStack(int taskId) {
9190        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9191                "getStackInfo()");
9192        long ident = Binder.clearCallingIdentity();
9193        try {
9194            synchronized (this) {
9195                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9196                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9197                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9198            }
9199        } finally {
9200            Binder.restoreCallingIdentity(ident);
9201        }
9202    }
9203
9204    @Override
9205    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9206        synchronized(this) {
9207            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9208        }
9209    }
9210
9211    @Override
9212    public void updateDeviceOwner(String packageName) {
9213        final int callingUid = Binder.getCallingUid();
9214        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9215            throw new SecurityException("updateDeviceOwner called from non-system process");
9216        }
9217        synchronized (this) {
9218            mDeviceOwnerName = packageName;
9219        }
9220    }
9221
9222    @Override
9223    public void updateLockTaskPackages(int userId, String[] packages) {
9224        final int callingUid = Binder.getCallingUid();
9225        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9226            throw new SecurityException("updateLockTaskPackage called from non-system process");
9227        }
9228        synchronized (this) {
9229            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9230                    Arrays.toString(packages));
9231            mLockTaskPackages.put(userId, packages);
9232            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9233        }
9234    }
9235
9236
9237    void startLockTaskModeLocked(TaskRecord task) {
9238        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9239        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9240            return;
9241        }
9242
9243        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9244        // is initiated by system after the pinning request was shown and locked mode is initiated
9245        // by an authorized app directly
9246        final int callingUid = Binder.getCallingUid();
9247        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9248        long ident = Binder.clearCallingIdentity();
9249        try {
9250            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9251            if (!isSystemInitiated) {
9252                task.mLockTaskUid = callingUid;
9253                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9254                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9255                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9256                    StatusBarManagerInternal statusBarManager =
9257                            LocalServices.getService(StatusBarManagerInternal.class);
9258                    if (statusBarManager != null) {
9259                        statusBarManager.showScreenPinningRequest();
9260                    }
9261                    return;
9262                }
9263
9264                if (stack == null || task != stack.topTask()) {
9265                    throw new IllegalArgumentException("Invalid task, not in foreground");
9266                }
9267            }
9268            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9269                    "Locking fully");
9270            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9271                    ActivityManager.LOCK_TASK_MODE_PINNED :
9272                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9273                    "startLockTask", true);
9274        } finally {
9275            Binder.restoreCallingIdentity(ident);
9276        }
9277    }
9278
9279    @Override
9280    public void startLockTaskMode(int taskId) {
9281        synchronized (this) {
9282            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9283            if (task != null) {
9284                startLockTaskModeLocked(task);
9285            }
9286        }
9287    }
9288
9289    @Override
9290    public void startLockTaskMode(IBinder token) {
9291        synchronized (this) {
9292            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9293            if (r == null) {
9294                return;
9295            }
9296            final TaskRecord task = r.task;
9297            if (task != null) {
9298                startLockTaskModeLocked(task);
9299            }
9300        }
9301    }
9302
9303    @Override
9304    public void startLockTaskModeOnCurrent() throws RemoteException {
9305        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9306                "startLockTaskModeOnCurrent");
9307        long ident = Binder.clearCallingIdentity();
9308        try {
9309            synchronized (this) {
9310                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9311                if (r != null) {
9312                    startLockTaskModeLocked(r.task);
9313                }
9314            }
9315        } finally {
9316            Binder.restoreCallingIdentity(ident);
9317        }
9318    }
9319
9320    @Override
9321    public void stopLockTaskMode() {
9322        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9323        if (lockTask == null) {
9324            // Our work here is done.
9325            return;
9326        }
9327
9328        final int callingUid = Binder.getCallingUid();
9329        final int lockTaskUid = lockTask.mLockTaskUid;
9330        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9331        // It is possible lockTaskMode was started by the system process because
9332        // android:lockTaskMode is set to a locking value in the application manifest instead of
9333        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9334        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9335        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9336                callingUid != lockTaskUid
9337                && (lockTaskUid != 0
9338                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9339            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9340                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9341        }
9342
9343        long ident = Binder.clearCallingIdentity();
9344        try {
9345            Log.d(TAG, "stopLockTaskMode");
9346            // Stop lock task
9347            synchronized (this) {
9348                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9349                        "stopLockTask", true);
9350            }
9351        } finally {
9352            Binder.restoreCallingIdentity(ident);
9353        }
9354    }
9355
9356    @Override
9357    public void stopLockTaskModeOnCurrent() throws RemoteException {
9358        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9359                "stopLockTaskModeOnCurrent");
9360        long ident = Binder.clearCallingIdentity();
9361        try {
9362            stopLockTaskMode();
9363        } finally {
9364            Binder.restoreCallingIdentity(ident);
9365        }
9366    }
9367
9368    @Override
9369    public boolean isInLockTaskMode() {
9370        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9371    }
9372
9373    @Override
9374    public int getLockTaskModeState() {
9375        synchronized (this) {
9376            return mStackSupervisor.getLockTaskModeState();
9377        }
9378    }
9379
9380    @Override
9381    public void showLockTaskEscapeMessage(IBinder token) {
9382        synchronized (this) {
9383            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9384            if (r == null) {
9385                return;
9386            }
9387            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9388        }
9389    }
9390
9391    // =========================================================
9392    // CONTENT PROVIDERS
9393    // =========================================================
9394
9395    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9396        List<ProviderInfo> providers = null;
9397        try {
9398            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9399                queryContentProviders(app.processName, app.uid,
9400                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9401            providers = slice != null ? slice.getList() : null;
9402        } catch (RemoteException ex) {
9403        }
9404        if (DEBUG_MU) Slog.v(TAG_MU,
9405                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9406        int userId = app.userId;
9407        if (providers != null) {
9408            int N = providers.size();
9409            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9410            for (int i=0; i<N; i++) {
9411                ProviderInfo cpi =
9412                    (ProviderInfo)providers.get(i);
9413                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9414                        cpi.name, cpi.flags);
9415                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9416                    // This is a singleton provider, but a user besides the
9417                    // default user is asking to initialize a process it runs
9418                    // in...  well, no, it doesn't actually run in this process,
9419                    // it runs in the process of the default user.  Get rid of it.
9420                    providers.remove(i);
9421                    N--;
9422                    i--;
9423                    continue;
9424                }
9425
9426                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9427                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9428                if (cpr == null) {
9429                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9430                    mProviderMap.putProviderByClass(comp, cpr);
9431                }
9432                if (DEBUG_MU) Slog.v(TAG_MU,
9433                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9434                app.pubProviders.put(cpi.name, cpr);
9435                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9436                    // Don't add this if it is a platform component that is marked
9437                    // to run in multiple processes, because this is actually
9438                    // part of the framework so doesn't make sense to track as a
9439                    // separate apk in the process.
9440                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9441                            mProcessStats);
9442                }
9443                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9444            }
9445        }
9446        return providers;
9447    }
9448
9449    /**
9450     * Check if {@link ProcessRecord} has a possible chance at accessing the
9451     * given {@link ProviderInfo}. Final permission checking is always done
9452     * in {@link ContentProvider}.
9453     */
9454    private final String checkContentProviderPermissionLocked(
9455            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9456        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9457        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9458        boolean checkedGrants = false;
9459        if (checkUser) {
9460            // Looking for cross-user grants before enforcing the typical cross-users permissions
9461            int tmpTargetUserId = unsafeConvertIncomingUserLocked(userId);
9462            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9463                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9464                    return null;
9465                }
9466                checkedGrants = true;
9467            }
9468            userId = handleIncomingUser(callingPid, callingUid, userId,
9469                    false, ALLOW_NON_FULL,
9470                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9471            if (userId != tmpTargetUserId) {
9472                // When we actually went to determine the final targer user ID, this ended
9473                // up different than our initial check for the authority.  This is because
9474                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9475                // SELF.  So we need to re-check the grants again.
9476                checkedGrants = false;
9477            }
9478        }
9479        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9480                cpi.applicationInfo.uid, cpi.exported)
9481                == PackageManager.PERMISSION_GRANTED) {
9482            return null;
9483        }
9484        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9485                cpi.applicationInfo.uid, cpi.exported)
9486                == PackageManager.PERMISSION_GRANTED) {
9487            return null;
9488        }
9489
9490        PathPermission[] pps = cpi.pathPermissions;
9491        if (pps != null) {
9492            int i = pps.length;
9493            while (i > 0) {
9494                i--;
9495                PathPermission pp = pps[i];
9496                String pprperm = pp.getReadPermission();
9497                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9498                        cpi.applicationInfo.uid, cpi.exported)
9499                        == PackageManager.PERMISSION_GRANTED) {
9500                    return null;
9501                }
9502                String ppwperm = pp.getWritePermission();
9503                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9504                        cpi.applicationInfo.uid, cpi.exported)
9505                        == PackageManager.PERMISSION_GRANTED) {
9506                    return null;
9507                }
9508            }
9509        }
9510        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9511            return null;
9512        }
9513
9514        String msg;
9515        if (!cpi.exported) {
9516            msg = "Permission Denial: opening provider " + cpi.name
9517                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9518                    + ", uid=" + callingUid + ") that is not exported from uid "
9519                    + cpi.applicationInfo.uid;
9520        } else {
9521            msg = "Permission Denial: opening provider " + cpi.name
9522                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9523                    + ", uid=" + callingUid + ") requires "
9524                    + cpi.readPermission + " or " + cpi.writePermission;
9525        }
9526        Slog.w(TAG, msg);
9527        return msg;
9528    }
9529
9530    /**
9531     * Returns if the ContentProvider has granted a uri to callingUid
9532     */
9533    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9534        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9535        if (perms != null) {
9536            for (int i=perms.size()-1; i>=0; i--) {
9537                GrantUri grantUri = perms.keyAt(i);
9538                if (grantUri.sourceUserId == userId || !checkUser) {
9539                    if (matchesProvider(grantUri.uri, cpi)) {
9540                        return true;
9541                    }
9542                }
9543            }
9544        }
9545        return false;
9546    }
9547
9548    /**
9549     * Returns true if the uri authority is one of the authorities specified in the provider.
9550     */
9551    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9552        String uriAuth = uri.getAuthority();
9553        String cpiAuth = cpi.authority;
9554        if (cpiAuth.indexOf(';') == -1) {
9555            return cpiAuth.equals(uriAuth);
9556        }
9557        String[] cpiAuths = cpiAuth.split(";");
9558        int length = cpiAuths.length;
9559        for (int i = 0; i < length; i++) {
9560            if (cpiAuths[i].equals(uriAuth)) return true;
9561        }
9562        return false;
9563    }
9564
9565    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9566            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9567        if (r != null) {
9568            for (int i=0; i<r.conProviders.size(); i++) {
9569                ContentProviderConnection conn = r.conProviders.get(i);
9570                if (conn.provider == cpr) {
9571                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9572                            "Adding provider requested by "
9573                            + r.processName + " from process "
9574                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9575                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9576                    if (stable) {
9577                        conn.stableCount++;
9578                        conn.numStableIncs++;
9579                    } else {
9580                        conn.unstableCount++;
9581                        conn.numUnstableIncs++;
9582                    }
9583                    return conn;
9584                }
9585            }
9586            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9587            if (stable) {
9588                conn.stableCount = 1;
9589                conn.numStableIncs = 1;
9590            } else {
9591                conn.unstableCount = 1;
9592                conn.numUnstableIncs = 1;
9593            }
9594            cpr.connections.add(conn);
9595            r.conProviders.add(conn);
9596            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9597            return conn;
9598        }
9599        cpr.addExternalProcessHandleLocked(externalProcessToken);
9600        return null;
9601    }
9602
9603    boolean decProviderCountLocked(ContentProviderConnection conn,
9604            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9605        if (conn != null) {
9606            cpr = conn.provider;
9607            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9608                    "Removing provider requested by "
9609                    + conn.client.processName + " from process "
9610                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9611                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9612            if (stable) {
9613                conn.stableCount--;
9614            } else {
9615                conn.unstableCount--;
9616            }
9617            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9618                cpr.connections.remove(conn);
9619                conn.client.conProviders.remove(conn);
9620                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9621                return true;
9622            }
9623            return false;
9624        }
9625        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9626        return false;
9627    }
9628
9629    private void checkTime(long startTime, String where) {
9630        long now = SystemClock.elapsedRealtime();
9631        if ((now-startTime) > 1000) {
9632            // If we are taking more than a second, log about it.
9633            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9634        }
9635    }
9636
9637    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9638            String name, IBinder token, boolean stable, int userId) {
9639        ContentProviderRecord cpr;
9640        ContentProviderConnection conn = null;
9641        ProviderInfo cpi = null;
9642
9643        synchronized(this) {
9644            long startTime = SystemClock.elapsedRealtime();
9645
9646            ProcessRecord r = null;
9647            if (caller != null) {
9648                r = getRecordForAppLocked(caller);
9649                if (r == null) {
9650                    throw new SecurityException(
9651                            "Unable to find app for caller " + caller
9652                          + " (pid=" + Binder.getCallingPid()
9653                          + ") when getting content provider " + name);
9654                }
9655            }
9656
9657            boolean checkCrossUser = true;
9658
9659            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9660
9661            // First check if this content provider has been published...
9662            cpr = mProviderMap.getProviderByName(name, userId);
9663            // If that didn't work, check if it exists for user 0 and then
9664            // verify that it's a singleton provider before using it.
9665            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9666                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9667                if (cpr != null) {
9668                    cpi = cpr.info;
9669                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9670                            cpi.name, cpi.flags)
9671                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9672                        userId = UserHandle.USER_SYSTEM;
9673                        checkCrossUser = false;
9674                    } else {
9675                        cpr = null;
9676                        cpi = null;
9677                    }
9678                }
9679            }
9680
9681            boolean providerRunning = cpr != null;
9682            if (providerRunning) {
9683                cpi = cpr.info;
9684                String msg;
9685                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9686                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9687                        != null) {
9688                    throw new SecurityException(msg);
9689                }
9690                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9691
9692                if (r != null && cpr.canRunHere(r)) {
9693                    // This provider has been published or is in the process
9694                    // of being published...  but it is also allowed to run
9695                    // in the caller's process, so don't make a connection
9696                    // and just let the caller instantiate its own instance.
9697                    ContentProviderHolder holder = cpr.newHolder(null);
9698                    // don't give caller the provider object, it needs
9699                    // to make its own.
9700                    holder.provider = null;
9701                    return holder;
9702                }
9703
9704                final long origId = Binder.clearCallingIdentity();
9705
9706                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9707
9708                // In this case the provider instance already exists, so we can
9709                // return it right away.
9710                conn = incProviderCountLocked(r, cpr, token, stable);
9711                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9712                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9713                        // If this is a perceptible app accessing the provider,
9714                        // make sure to count it as being accessed and thus
9715                        // back up on the LRU list.  This is good because
9716                        // content providers are often expensive to start.
9717                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9718                        updateLruProcessLocked(cpr.proc, false, null);
9719                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9720                    }
9721                }
9722
9723                if (cpr.proc != null) {
9724                    if (false) {
9725                        if (cpr.name.flattenToShortString().equals(
9726                                "com.android.providers.calendar/.CalendarProvider2")) {
9727                            Slog.v(TAG, "****************** KILLING "
9728                                + cpr.name.flattenToShortString());
9729                            Process.killProcess(cpr.proc.pid);
9730                        }
9731                    }
9732                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9733                    boolean success = updateOomAdjLocked(cpr.proc);
9734                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9735                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9736                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9737                    // NOTE: there is still a race here where a signal could be
9738                    // pending on the process even though we managed to update its
9739                    // adj level.  Not sure what to do about this, but at least
9740                    // the race is now smaller.
9741                    if (!success) {
9742                        // Uh oh...  it looks like the provider's process
9743                        // has been killed on us.  We need to wait for a new
9744                        // process to be started, and make sure its death
9745                        // doesn't kill our process.
9746                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9747                                + " is crashing; detaching " + r);
9748                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9749                        checkTime(startTime, "getContentProviderImpl: before appDied");
9750                        appDiedLocked(cpr.proc);
9751                        checkTime(startTime, "getContentProviderImpl: after appDied");
9752                        if (!lastRef) {
9753                            // This wasn't the last ref our process had on
9754                            // the provider...  we have now been killed, bail.
9755                            return null;
9756                        }
9757                        providerRunning = false;
9758                        conn = null;
9759                    }
9760                }
9761
9762                Binder.restoreCallingIdentity(origId);
9763            }
9764
9765            if (!providerRunning) {
9766                try {
9767                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9768                    cpi = AppGlobals.getPackageManager().
9769                        resolveContentProvider(name,
9770                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9771                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9772                } catch (RemoteException ex) {
9773                }
9774                if (cpi == null) {
9775                    return null;
9776                }
9777                // If the provider is a singleton AND
9778                // (it's a call within the same user || the provider is a
9779                // privileged app)
9780                // Then allow connecting to the singleton provider
9781                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9782                        cpi.name, cpi.flags)
9783                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9784                if (singleton) {
9785                    userId = UserHandle.USER_SYSTEM;
9786                }
9787                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9788                checkTime(startTime, "getContentProviderImpl: got app info for user");
9789
9790                String msg;
9791                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9792                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9793                        != null) {
9794                    throw new SecurityException(msg);
9795                }
9796                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9797
9798                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9799                        && !cpi.processName.equals("system")) {
9800                    // If this content provider does not run in the system
9801                    // process, and the system is not yet ready to run other
9802                    // processes, then fail fast instead of hanging.
9803                    throw new IllegalArgumentException(
9804                            "Attempt to launch content provider before system ready");
9805                }
9806
9807                // Make sure that the user who owns this provider is running.  If not,
9808                // we don't want to allow it to run.
9809                if (!isUserRunningLocked(userId, false)) {
9810                    Slog.w(TAG, "Unable to launch app "
9811                            + cpi.applicationInfo.packageName + "/"
9812                            + cpi.applicationInfo.uid + " for provider "
9813                            + name + ": user " + userId + " is stopped");
9814                    return null;
9815                }
9816
9817                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9818                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9819                cpr = mProviderMap.getProviderByClass(comp, userId);
9820                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9821                final boolean firstClass = cpr == null;
9822                if (firstClass) {
9823                    final long ident = Binder.clearCallingIdentity();
9824                    try {
9825                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9826                        ApplicationInfo ai =
9827                            AppGlobals.getPackageManager().
9828                                getApplicationInfo(
9829                                        cpi.applicationInfo.packageName,
9830                                        STOCK_PM_FLAGS, userId);
9831                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9832                        if (ai == null) {
9833                            Slog.w(TAG, "No package info for content provider "
9834                                    + cpi.name);
9835                            return null;
9836                        }
9837                        ai = getAppInfoForUser(ai, userId);
9838                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9839                    } catch (RemoteException ex) {
9840                        // pm is in same process, this will never happen.
9841                    } finally {
9842                        Binder.restoreCallingIdentity(ident);
9843                    }
9844                }
9845
9846                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9847
9848                if (r != null && cpr.canRunHere(r)) {
9849                    // If this is a multiprocess provider, then just return its
9850                    // info and allow the caller to instantiate it.  Only do
9851                    // this if the provider is the same user as the caller's
9852                    // process, or can run as root (so can be in any process).
9853                    return cpr.newHolder(null);
9854                }
9855
9856                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9857                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9858                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9859
9860                // This is single process, and our app is now connecting to it.
9861                // See if we are already in the process of launching this
9862                // provider.
9863                final int N = mLaunchingProviders.size();
9864                int i;
9865                for (i = 0; i < N; i++) {
9866                    if (mLaunchingProviders.get(i) == cpr) {
9867                        break;
9868                    }
9869                }
9870
9871                // If the provider is not already being launched, then get it
9872                // started.
9873                if (i >= N) {
9874                    final long origId = Binder.clearCallingIdentity();
9875
9876                    try {
9877                        // Content provider is now in use, its package can't be stopped.
9878                        try {
9879                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9880                            AppGlobals.getPackageManager().setPackageStoppedState(
9881                                    cpr.appInfo.packageName, false, userId);
9882                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9883                        } catch (RemoteException e) {
9884                        } catch (IllegalArgumentException e) {
9885                            Slog.w(TAG, "Failed trying to unstop package "
9886                                    + cpr.appInfo.packageName + ": " + e);
9887                        }
9888
9889                        // Use existing process if already started
9890                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9891                        ProcessRecord proc = getProcessRecordLocked(
9892                                cpi.processName, cpr.appInfo.uid, false);
9893                        if (proc != null && proc.thread != null) {
9894                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9895                                    "Installing in existing process " + proc);
9896                            if (!proc.pubProviders.containsKey(cpi.name)) {
9897                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9898                                proc.pubProviders.put(cpi.name, cpr);
9899                                try {
9900                                    proc.thread.scheduleInstallProvider(cpi);
9901                                } catch (RemoteException e) {
9902                                }
9903                            }
9904                        } else {
9905                            checkTime(startTime, "getContentProviderImpl: before start process");
9906                            proc = startProcessLocked(cpi.processName,
9907                                    cpr.appInfo, false, 0, "content provider",
9908                                    new ComponentName(cpi.applicationInfo.packageName,
9909                                            cpi.name), false, false, false);
9910                            checkTime(startTime, "getContentProviderImpl: after start process");
9911                            if (proc == null) {
9912                                Slog.w(TAG, "Unable to launch app "
9913                                        + cpi.applicationInfo.packageName + "/"
9914                                        + cpi.applicationInfo.uid + " for provider "
9915                                        + name + ": process is bad");
9916                                return null;
9917                            }
9918                        }
9919                        cpr.launchingApp = proc;
9920                        mLaunchingProviders.add(cpr);
9921                    } finally {
9922                        Binder.restoreCallingIdentity(origId);
9923                    }
9924                }
9925
9926                checkTime(startTime, "getContentProviderImpl: updating data structures");
9927
9928                // Make sure the provider is published (the same provider class
9929                // may be published under multiple names).
9930                if (firstClass) {
9931                    mProviderMap.putProviderByClass(comp, cpr);
9932                }
9933
9934                mProviderMap.putProviderByName(name, cpr);
9935                conn = incProviderCountLocked(r, cpr, token, stable);
9936                if (conn != null) {
9937                    conn.waiting = true;
9938                }
9939            }
9940            checkTime(startTime, "getContentProviderImpl: done!");
9941        }
9942
9943        // Wait for the provider to be published...
9944        synchronized (cpr) {
9945            while (cpr.provider == null) {
9946                if (cpr.launchingApp == null) {
9947                    Slog.w(TAG, "Unable to launch app "
9948                            + cpi.applicationInfo.packageName + "/"
9949                            + cpi.applicationInfo.uid + " for provider "
9950                            + name + ": launching app became null");
9951                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9952                            UserHandle.getUserId(cpi.applicationInfo.uid),
9953                            cpi.applicationInfo.packageName,
9954                            cpi.applicationInfo.uid, name);
9955                    return null;
9956                }
9957                try {
9958                    if (DEBUG_MU) Slog.v(TAG_MU,
9959                            "Waiting to start provider " + cpr
9960                            + " launchingApp=" + cpr.launchingApp);
9961                    if (conn != null) {
9962                        conn.waiting = true;
9963                    }
9964                    cpr.wait();
9965                } catch (InterruptedException ex) {
9966                } finally {
9967                    if (conn != null) {
9968                        conn.waiting = false;
9969                    }
9970                }
9971            }
9972        }
9973        return cpr != null ? cpr.newHolder(conn) : null;
9974    }
9975
9976    @Override
9977    public final ContentProviderHolder getContentProvider(
9978            IApplicationThread caller, String name, int userId, boolean stable) {
9979        enforceNotIsolatedCaller("getContentProvider");
9980        if (caller == null) {
9981            String msg = "null IApplicationThread when getting content provider "
9982                    + name;
9983            Slog.w(TAG, msg);
9984            throw new SecurityException(msg);
9985        }
9986        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9987        // with cross-user grant.
9988        return getContentProviderImpl(caller, name, null, stable, userId);
9989    }
9990
9991    public ContentProviderHolder getContentProviderExternal(
9992            String name, int userId, IBinder token) {
9993        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9994            "Do not have permission in call getContentProviderExternal()");
9995        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9996                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9997        return getContentProviderExternalUnchecked(name, token, userId);
9998    }
9999
10000    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10001            IBinder token, int userId) {
10002        return getContentProviderImpl(null, name, token, true, userId);
10003    }
10004
10005    /**
10006     * Drop a content provider from a ProcessRecord's bookkeeping
10007     */
10008    public void removeContentProvider(IBinder connection, boolean stable) {
10009        enforceNotIsolatedCaller("removeContentProvider");
10010        long ident = Binder.clearCallingIdentity();
10011        try {
10012            synchronized (this) {
10013                ContentProviderConnection conn;
10014                try {
10015                    conn = (ContentProviderConnection)connection;
10016                } catch (ClassCastException e) {
10017                    String msg ="removeContentProvider: " + connection
10018                            + " not a ContentProviderConnection";
10019                    Slog.w(TAG, msg);
10020                    throw new IllegalArgumentException(msg);
10021                }
10022                if (conn == null) {
10023                    throw new NullPointerException("connection is null");
10024                }
10025                if (decProviderCountLocked(conn, null, null, stable)) {
10026                    updateOomAdjLocked();
10027                }
10028            }
10029        } finally {
10030            Binder.restoreCallingIdentity(ident);
10031        }
10032    }
10033
10034    public void removeContentProviderExternal(String name, IBinder token) {
10035        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10036            "Do not have permission in call removeContentProviderExternal()");
10037        int userId = UserHandle.getCallingUserId();
10038        long ident = Binder.clearCallingIdentity();
10039        try {
10040            removeContentProviderExternalUnchecked(name, token, userId);
10041        } finally {
10042            Binder.restoreCallingIdentity(ident);
10043        }
10044    }
10045
10046    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10047        synchronized (this) {
10048            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10049            if(cpr == null) {
10050                //remove from mProvidersByClass
10051                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10052                return;
10053            }
10054
10055            //update content provider record entry info
10056            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10057            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10058            if (localCpr.hasExternalProcessHandles()) {
10059                if (localCpr.removeExternalProcessHandleLocked(token)) {
10060                    updateOomAdjLocked();
10061                } else {
10062                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10063                            + " with no external reference for token: "
10064                            + token + ".");
10065                }
10066            } else {
10067                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10068                        + " with no external references.");
10069            }
10070        }
10071    }
10072
10073    public final void publishContentProviders(IApplicationThread caller,
10074            List<ContentProviderHolder> providers) {
10075        if (providers == null) {
10076            return;
10077        }
10078
10079        enforceNotIsolatedCaller("publishContentProviders");
10080        synchronized (this) {
10081            final ProcessRecord r = getRecordForAppLocked(caller);
10082            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10083            if (r == null) {
10084                throw new SecurityException(
10085                        "Unable to find app for caller " + caller
10086                      + " (pid=" + Binder.getCallingPid()
10087                      + ") when publishing content providers");
10088            }
10089
10090            final long origId = Binder.clearCallingIdentity();
10091
10092            final int N = providers.size();
10093            for (int i = 0; i < N; i++) {
10094                ContentProviderHolder src = providers.get(i);
10095                if (src == null || src.info == null || src.provider == null) {
10096                    continue;
10097                }
10098                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10099                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10100                if (dst != null) {
10101                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10102                    mProviderMap.putProviderByClass(comp, dst);
10103                    String names[] = dst.info.authority.split(";");
10104                    for (int j = 0; j < names.length; j++) {
10105                        mProviderMap.putProviderByName(names[j], dst);
10106                    }
10107
10108                    int launchingCount = mLaunchingProviders.size();
10109                    int j;
10110                    boolean wasInLaunchingProviders = false;
10111                    for (j = 0; j < launchingCount; j++) {
10112                        if (mLaunchingProviders.get(j) == dst) {
10113                            mLaunchingProviders.remove(j);
10114                            wasInLaunchingProviders = true;
10115                            j--;
10116                            launchingCount--;
10117                        }
10118                    }
10119                    if (wasInLaunchingProviders) {
10120                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10121                    }
10122                    synchronized (dst) {
10123                        dst.provider = src.provider;
10124                        dst.proc = r;
10125                        dst.notifyAll();
10126                    }
10127                    updateOomAdjLocked(r);
10128                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10129                            src.info.authority);
10130                }
10131            }
10132
10133            Binder.restoreCallingIdentity(origId);
10134        }
10135    }
10136
10137    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10138        ContentProviderConnection conn;
10139        try {
10140            conn = (ContentProviderConnection)connection;
10141        } catch (ClassCastException e) {
10142            String msg ="refContentProvider: " + connection
10143                    + " not a ContentProviderConnection";
10144            Slog.w(TAG, msg);
10145            throw new IllegalArgumentException(msg);
10146        }
10147        if (conn == null) {
10148            throw new NullPointerException("connection is null");
10149        }
10150
10151        synchronized (this) {
10152            if (stable > 0) {
10153                conn.numStableIncs += stable;
10154            }
10155            stable = conn.stableCount + stable;
10156            if (stable < 0) {
10157                throw new IllegalStateException("stableCount < 0: " + stable);
10158            }
10159
10160            if (unstable > 0) {
10161                conn.numUnstableIncs += unstable;
10162            }
10163            unstable = conn.unstableCount + unstable;
10164            if (unstable < 0) {
10165                throw new IllegalStateException("unstableCount < 0: " + unstable);
10166            }
10167
10168            if ((stable+unstable) <= 0) {
10169                throw new IllegalStateException("ref counts can't go to zero here: stable="
10170                        + stable + " unstable=" + unstable);
10171            }
10172            conn.stableCount = stable;
10173            conn.unstableCount = unstable;
10174            return !conn.dead;
10175        }
10176    }
10177
10178    public void unstableProviderDied(IBinder connection) {
10179        ContentProviderConnection conn;
10180        try {
10181            conn = (ContentProviderConnection)connection;
10182        } catch (ClassCastException e) {
10183            String msg ="refContentProvider: " + connection
10184                    + " not a ContentProviderConnection";
10185            Slog.w(TAG, msg);
10186            throw new IllegalArgumentException(msg);
10187        }
10188        if (conn == null) {
10189            throw new NullPointerException("connection is null");
10190        }
10191
10192        // Safely retrieve the content provider associated with the connection.
10193        IContentProvider provider;
10194        synchronized (this) {
10195            provider = conn.provider.provider;
10196        }
10197
10198        if (provider == null) {
10199            // Um, yeah, we're way ahead of you.
10200            return;
10201        }
10202
10203        // Make sure the caller is being honest with us.
10204        if (provider.asBinder().pingBinder()) {
10205            // Er, no, still looks good to us.
10206            synchronized (this) {
10207                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10208                        + " says " + conn + " died, but we don't agree");
10209                return;
10210            }
10211        }
10212
10213        // Well look at that!  It's dead!
10214        synchronized (this) {
10215            if (conn.provider.provider != provider) {
10216                // But something changed...  good enough.
10217                return;
10218            }
10219
10220            ProcessRecord proc = conn.provider.proc;
10221            if (proc == null || proc.thread == null) {
10222                // Seems like the process is already cleaned up.
10223                return;
10224            }
10225
10226            // As far as we're concerned, this is just like receiving a
10227            // death notification...  just a bit prematurely.
10228            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10229                    + ") early provider death");
10230            final long ident = Binder.clearCallingIdentity();
10231            try {
10232                appDiedLocked(proc);
10233            } finally {
10234                Binder.restoreCallingIdentity(ident);
10235            }
10236        }
10237    }
10238
10239    @Override
10240    public void appNotRespondingViaProvider(IBinder connection) {
10241        enforceCallingPermission(
10242                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10243
10244        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10245        if (conn == null) {
10246            Slog.w(TAG, "ContentProviderConnection is null");
10247            return;
10248        }
10249
10250        final ProcessRecord host = conn.provider.proc;
10251        if (host == null) {
10252            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10253            return;
10254        }
10255
10256        final long token = Binder.clearCallingIdentity();
10257        try {
10258            appNotResponding(host, null, null, false, "ContentProvider not responding");
10259        } finally {
10260            Binder.restoreCallingIdentity(token);
10261        }
10262    }
10263
10264    public final void installSystemProviders() {
10265        List<ProviderInfo> providers;
10266        synchronized (this) {
10267            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10268            providers = generateApplicationProvidersLocked(app);
10269            if (providers != null) {
10270                for (int i=providers.size()-1; i>=0; i--) {
10271                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10272                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10273                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10274                                + ": not system .apk");
10275                        providers.remove(i);
10276                    }
10277                }
10278            }
10279        }
10280        if (providers != null) {
10281            mSystemThread.installSystemProviders(providers);
10282        }
10283
10284        mCoreSettingsObserver = new CoreSettingsObserver(this);
10285
10286        //mUsageStatsService.monitorPackages();
10287    }
10288
10289    /**
10290     * Allows apps to retrieve the MIME type of a URI.
10291     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10292     * users, then it does not need permission to access the ContentProvider.
10293     * Either, it needs cross-user uri grants.
10294     *
10295     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10296     *
10297     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10298     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10299     */
10300    public String getProviderMimeType(Uri uri, int userId) {
10301        enforceNotIsolatedCaller("getProviderMimeType");
10302        final String name = uri.getAuthority();
10303        int callingUid = Binder.getCallingUid();
10304        int callingPid = Binder.getCallingPid();
10305        long ident = 0;
10306        boolean clearedIdentity = false;
10307        synchronized (this) {
10308            userId = unsafeConvertIncomingUserLocked(userId);
10309        }
10310        if (canClearIdentity(callingPid, callingUid, userId)) {
10311            clearedIdentity = true;
10312            ident = Binder.clearCallingIdentity();
10313        }
10314        ContentProviderHolder holder = null;
10315        try {
10316            holder = getContentProviderExternalUnchecked(name, null, userId);
10317            if (holder != null) {
10318                return holder.provider.getType(uri);
10319            }
10320        } catch (RemoteException e) {
10321            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10322            return null;
10323        } finally {
10324            // We need to clear the identity to call removeContentProviderExternalUnchecked
10325            if (!clearedIdentity) {
10326                ident = Binder.clearCallingIdentity();
10327            }
10328            try {
10329                if (holder != null) {
10330                    removeContentProviderExternalUnchecked(name, null, userId);
10331                }
10332            } finally {
10333                Binder.restoreCallingIdentity(ident);
10334            }
10335        }
10336
10337        return null;
10338    }
10339
10340    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10341        if (UserHandle.getUserId(callingUid) == userId) {
10342            return true;
10343        }
10344        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10345                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10346                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10347                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10348                return true;
10349        }
10350        return false;
10351    }
10352
10353    // =========================================================
10354    // GLOBAL MANAGEMENT
10355    // =========================================================
10356
10357    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10358            boolean isolated, int isolatedUid) {
10359        String proc = customProcess != null ? customProcess : info.processName;
10360        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10361        final int userId = UserHandle.getUserId(info.uid);
10362        int uid = info.uid;
10363        if (isolated) {
10364            if (isolatedUid == 0) {
10365                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10366                while (true) {
10367                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10368                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10369                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10370                    }
10371                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10372                    mNextIsolatedProcessUid++;
10373                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10374                        // No process for this uid, use it.
10375                        break;
10376                    }
10377                    stepsLeft--;
10378                    if (stepsLeft <= 0) {
10379                        return null;
10380                    }
10381                }
10382            } else {
10383                // Special case for startIsolatedProcess (internal only), where
10384                // the uid of the isolated process is specified by the caller.
10385                uid = isolatedUid;
10386            }
10387        }
10388        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10389        if (!mBooted && !mBooting
10390                && userId == UserHandle.USER_SYSTEM
10391                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10392            r.persistent = true;
10393        }
10394        addProcessNameLocked(r);
10395        return r;
10396    }
10397
10398    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10399            String abiOverride) {
10400        ProcessRecord app;
10401        if (!isolated) {
10402            app = getProcessRecordLocked(info.processName, info.uid, true);
10403        } else {
10404            app = null;
10405        }
10406
10407        if (app == null) {
10408            app = newProcessRecordLocked(info, null, isolated, 0);
10409            updateLruProcessLocked(app, false, null);
10410            updateOomAdjLocked();
10411        }
10412
10413        // This package really, really can not be stopped.
10414        try {
10415            AppGlobals.getPackageManager().setPackageStoppedState(
10416                    info.packageName, false, UserHandle.getUserId(app.uid));
10417        } catch (RemoteException e) {
10418        } catch (IllegalArgumentException e) {
10419            Slog.w(TAG, "Failed trying to unstop package "
10420                    + info.packageName + ": " + e);
10421        }
10422
10423        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10424            app.persistent = true;
10425            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10426        }
10427        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10428            mPersistentStartingProcesses.add(app);
10429            startProcessLocked(app, "added application", app.processName, abiOverride,
10430                    null /* entryPoint */, null /* entryPointArgs */);
10431        }
10432
10433        return app;
10434    }
10435
10436    public void unhandledBack() {
10437        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10438                "unhandledBack()");
10439
10440        synchronized(this) {
10441            final long origId = Binder.clearCallingIdentity();
10442            try {
10443                getFocusedStack().unhandledBackLocked();
10444            } finally {
10445                Binder.restoreCallingIdentity(origId);
10446            }
10447        }
10448    }
10449
10450    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10451        enforceNotIsolatedCaller("openContentUri");
10452        final int userId = UserHandle.getCallingUserId();
10453        String name = uri.getAuthority();
10454        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10455        ParcelFileDescriptor pfd = null;
10456        if (cph != null) {
10457            // We record the binder invoker's uid in thread-local storage before
10458            // going to the content provider to open the file.  Later, in the code
10459            // that handles all permissions checks, we look for this uid and use
10460            // that rather than the Activity Manager's own uid.  The effect is that
10461            // we do the check against the caller's permissions even though it looks
10462            // to the content provider like the Activity Manager itself is making
10463            // the request.
10464            Binder token = new Binder();
10465            sCallerIdentity.set(new Identity(
10466                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10467            try {
10468                pfd = cph.provider.openFile(null, uri, "r", null, token);
10469            } catch (FileNotFoundException e) {
10470                // do nothing; pfd will be returned null
10471            } finally {
10472                // Ensure that whatever happens, we clean up the identity state
10473                sCallerIdentity.remove();
10474                // Ensure we're done with the provider.
10475                removeContentProviderExternalUnchecked(name, null, userId);
10476            }
10477        } else {
10478            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10479        }
10480        return pfd;
10481    }
10482
10483    // Actually is sleeping or shutting down or whatever else in the future
10484    // is an inactive state.
10485    public boolean isSleepingOrShuttingDown() {
10486        return isSleeping() || mShuttingDown;
10487    }
10488
10489    public boolean isSleeping() {
10490        return mSleeping;
10491    }
10492
10493    void onWakefulnessChanged(int wakefulness) {
10494        synchronized(this) {
10495            mWakefulness = wakefulness;
10496            updateSleepIfNeededLocked();
10497        }
10498    }
10499
10500    void finishRunningVoiceLocked() {
10501        if (mRunningVoice != null) {
10502            mRunningVoice = null;
10503            mVoiceWakeLock.release();
10504            updateSleepIfNeededLocked();
10505        }
10506    }
10507
10508    void startTimeTrackingFocusedActivityLocked() {
10509        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10510            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10511        }
10512    }
10513
10514    void updateSleepIfNeededLocked() {
10515        if (mSleeping && !shouldSleepLocked()) {
10516            mSleeping = false;
10517            startTimeTrackingFocusedActivityLocked();
10518            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10519            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10520            updateOomAdjLocked();
10521        } else if (!mSleeping && shouldSleepLocked()) {
10522            mSleeping = true;
10523            if (mCurAppTimeTracker != null) {
10524                mCurAppTimeTracker.stop();
10525            }
10526            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10527            mStackSupervisor.goingToSleepLocked();
10528            updateOomAdjLocked();
10529
10530            // Initialize the wake times of all processes.
10531            checkExcessivePowerUsageLocked(false);
10532            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10533            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10534            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10535        }
10536    }
10537
10538    private boolean shouldSleepLocked() {
10539        // Resume applications while running a voice interactor.
10540        if (mRunningVoice != null) {
10541            return false;
10542        }
10543
10544        // TODO: Transform the lock screen state into a sleep token instead.
10545        switch (mWakefulness) {
10546            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10547            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10548            case PowerManagerInternal.WAKEFULNESS_DOZING:
10549                // Pause applications whenever the lock screen is shown or any sleep
10550                // tokens have been acquired.
10551                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10552            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10553            default:
10554                // If we're asleep then pause applications unconditionally.
10555                return true;
10556        }
10557    }
10558
10559    /** Pokes the task persister. */
10560    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10561        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10562            // Never persist the home stack.
10563            return;
10564        }
10565        mTaskPersister.wakeup(task, flush);
10566    }
10567
10568    /** Notifies all listeners when the task stack has changed. */
10569    void notifyTaskStackChangedLocked() {
10570        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10571        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10572        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10573    }
10574
10575    @Override
10576    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10577        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10578    }
10579
10580    @Override
10581    public boolean shutdown(int timeout) {
10582        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10583                != PackageManager.PERMISSION_GRANTED) {
10584            throw new SecurityException("Requires permission "
10585                    + android.Manifest.permission.SHUTDOWN);
10586        }
10587
10588        boolean timedout = false;
10589
10590        synchronized(this) {
10591            mShuttingDown = true;
10592            updateEventDispatchingLocked();
10593            timedout = mStackSupervisor.shutdownLocked(timeout);
10594        }
10595
10596        mAppOpsService.shutdown();
10597        if (mUsageStatsService != null) {
10598            mUsageStatsService.prepareShutdown();
10599        }
10600        mBatteryStatsService.shutdown();
10601        synchronized (this) {
10602            mProcessStats.shutdownLocked();
10603            notifyTaskPersisterLocked(null, true);
10604        }
10605
10606        return timedout;
10607    }
10608
10609    public final void activitySlept(IBinder token) {
10610        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10611
10612        final long origId = Binder.clearCallingIdentity();
10613
10614        synchronized (this) {
10615            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10616            if (r != null) {
10617                mStackSupervisor.activitySleptLocked(r);
10618            }
10619        }
10620
10621        Binder.restoreCallingIdentity(origId);
10622    }
10623
10624    private String lockScreenShownToString() {
10625        switch (mLockScreenShown) {
10626            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10627            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10628            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10629            default: return "Unknown=" + mLockScreenShown;
10630        }
10631    }
10632
10633    void logLockScreen(String msg) {
10634        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10635                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10636                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10637                + " mSleeping=" + mSleeping);
10638    }
10639
10640    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10641        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10642        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10643            boolean wasRunningVoice = mRunningVoice != null;
10644            mRunningVoice = session;
10645            if (!wasRunningVoice) {
10646                mVoiceWakeLock.acquire();
10647                updateSleepIfNeededLocked();
10648            }
10649        }
10650    }
10651
10652    private void updateEventDispatchingLocked() {
10653        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10654    }
10655
10656    public void setLockScreenShown(boolean shown) {
10657        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10658                != PackageManager.PERMISSION_GRANTED) {
10659            throw new SecurityException("Requires permission "
10660                    + android.Manifest.permission.DEVICE_POWER);
10661        }
10662
10663        synchronized(this) {
10664            long ident = Binder.clearCallingIdentity();
10665            try {
10666                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10667                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10668                updateSleepIfNeededLocked();
10669            } finally {
10670                Binder.restoreCallingIdentity(ident);
10671            }
10672        }
10673    }
10674
10675    @Override
10676    public void stopAppSwitches() {
10677        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10678                != PackageManager.PERMISSION_GRANTED) {
10679            throw new SecurityException("Requires permission "
10680                    + android.Manifest.permission.STOP_APP_SWITCHES);
10681        }
10682
10683        synchronized(this) {
10684            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10685                    + APP_SWITCH_DELAY_TIME;
10686            mDidAppSwitch = false;
10687            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10688            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10689            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10690        }
10691    }
10692
10693    public void resumeAppSwitches() {
10694        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10695                != PackageManager.PERMISSION_GRANTED) {
10696            throw new SecurityException("Requires permission "
10697                    + android.Manifest.permission.STOP_APP_SWITCHES);
10698        }
10699
10700        synchronized(this) {
10701            // Note that we don't execute any pending app switches... we will
10702            // let those wait until either the timeout, or the next start
10703            // activity request.
10704            mAppSwitchesAllowedTime = 0;
10705        }
10706    }
10707
10708    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10709            int callingPid, int callingUid, String name) {
10710        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10711            return true;
10712        }
10713
10714        int perm = checkComponentPermission(
10715                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10716                sourceUid, -1, true);
10717        if (perm == PackageManager.PERMISSION_GRANTED) {
10718            return true;
10719        }
10720
10721        // If the actual IPC caller is different from the logical source, then
10722        // also see if they are allowed to control app switches.
10723        if (callingUid != -1 && callingUid != sourceUid) {
10724            perm = checkComponentPermission(
10725                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10726                    callingUid, -1, true);
10727            if (perm == PackageManager.PERMISSION_GRANTED) {
10728                return true;
10729            }
10730        }
10731
10732        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10733        return false;
10734    }
10735
10736    public void setDebugApp(String packageName, boolean waitForDebugger,
10737            boolean persistent) {
10738        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10739                "setDebugApp()");
10740
10741        long ident = Binder.clearCallingIdentity();
10742        try {
10743            // Note that this is not really thread safe if there are multiple
10744            // callers into it at the same time, but that's not a situation we
10745            // care about.
10746            if (persistent) {
10747                final ContentResolver resolver = mContext.getContentResolver();
10748                Settings.Global.putString(
10749                    resolver, Settings.Global.DEBUG_APP,
10750                    packageName);
10751                Settings.Global.putInt(
10752                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10753                    waitForDebugger ? 1 : 0);
10754            }
10755
10756            synchronized (this) {
10757                if (!persistent) {
10758                    mOrigDebugApp = mDebugApp;
10759                    mOrigWaitForDebugger = mWaitForDebugger;
10760                }
10761                mDebugApp = packageName;
10762                mWaitForDebugger = waitForDebugger;
10763                mDebugTransient = !persistent;
10764                if (packageName != null) {
10765                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10766                            false, UserHandle.USER_ALL, "set debug app");
10767                }
10768            }
10769        } finally {
10770            Binder.restoreCallingIdentity(ident);
10771        }
10772    }
10773
10774    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10775        synchronized (this) {
10776            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10777            if (!isDebuggable) {
10778                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10779                    throw new SecurityException("Process not debuggable: " + app.packageName);
10780                }
10781            }
10782
10783            mTrackAllocationApp = processName;
10784        }
10785    }
10786
10787    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10788        synchronized (this) {
10789            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10790            if (!isDebuggable) {
10791                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10792                    throw new SecurityException("Process not debuggable: " + app.packageName);
10793                }
10794            }
10795            mProfileApp = processName;
10796            mProfileFile = profilerInfo.profileFile;
10797            if (mProfileFd != null) {
10798                try {
10799                    mProfileFd.close();
10800                } catch (IOException e) {
10801                }
10802                mProfileFd = null;
10803            }
10804            mProfileFd = profilerInfo.profileFd;
10805            mSamplingInterval = profilerInfo.samplingInterval;
10806            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10807            mProfileType = 0;
10808        }
10809    }
10810
10811    @Override
10812    public void setAlwaysFinish(boolean enabled) {
10813        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10814                "setAlwaysFinish()");
10815
10816        Settings.Global.putInt(
10817                mContext.getContentResolver(),
10818                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10819
10820        synchronized (this) {
10821            mAlwaysFinishActivities = enabled;
10822        }
10823    }
10824
10825    @Override
10826    public void setActivityController(IActivityController controller) {
10827        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10828                "setActivityController()");
10829        synchronized (this) {
10830            mController = controller;
10831            Watchdog.getInstance().setActivityController(controller);
10832        }
10833    }
10834
10835    @Override
10836    public void setUserIsMonkey(boolean userIsMonkey) {
10837        synchronized (this) {
10838            synchronized (mPidsSelfLocked) {
10839                final int callingPid = Binder.getCallingPid();
10840                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10841                if (precessRecord == null) {
10842                    throw new SecurityException("Unknown process: " + callingPid);
10843                }
10844                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10845                    throw new SecurityException("Only an instrumentation process "
10846                            + "with a UiAutomation can call setUserIsMonkey");
10847                }
10848            }
10849            mUserIsMonkey = userIsMonkey;
10850        }
10851    }
10852
10853    @Override
10854    public boolean isUserAMonkey() {
10855        synchronized (this) {
10856            // If there is a controller also implies the user is a monkey.
10857            return (mUserIsMonkey || mController != null);
10858        }
10859    }
10860
10861    public void requestBugReport() {
10862        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10863        SystemProperties.set("ctl.start", "bugreport");
10864    }
10865
10866    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10867        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10868    }
10869
10870    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10871        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10872            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10873        }
10874        return KEY_DISPATCHING_TIMEOUT;
10875    }
10876
10877    @Override
10878    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10879        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10880                != PackageManager.PERMISSION_GRANTED) {
10881            throw new SecurityException("Requires permission "
10882                    + android.Manifest.permission.FILTER_EVENTS);
10883        }
10884        ProcessRecord proc;
10885        long timeout;
10886        synchronized (this) {
10887            synchronized (mPidsSelfLocked) {
10888                proc = mPidsSelfLocked.get(pid);
10889            }
10890            timeout = getInputDispatchingTimeoutLocked(proc);
10891        }
10892
10893        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10894            return -1;
10895        }
10896
10897        return timeout;
10898    }
10899
10900    /**
10901     * Handle input dispatching timeouts.
10902     * Returns whether input dispatching should be aborted or not.
10903     */
10904    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10905            final ActivityRecord activity, final ActivityRecord parent,
10906            final boolean aboveSystem, String reason) {
10907        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10908                != PackageManager.PERMISSION_GRANTED) {
10909            throw new SecurityException("Requires permission "
10910                    + android.Manifest.permission.FILTER_EVENTS);
10911        }
10912
10913        final String annotation;
10914        if (reason == null) {
10915            annotation = "Input dispatching timed out";
10916        } else {
10917            annotation = "Input dispatching timed out (" + reason + ")";
10918        }
10919
10920        if (proc != null) {
10921            synchronized (this) {
10922                if (proc.debugging) {
10923                    return false;
10924                }
10925
10926                if (mDidDexOpt) {
10927                    // Give more time since we were dexopting.
10928                    mDidDexOpt = false;
10929                    return false;
10930                }
10931
10932                if (proc.instrumentationClass != null) {
10933                    Bundle info = new Bundle();
10934                    info.putString("shortMsg", "keyDispatchingTimedOut");
10935                    info.putString("longMsg", annotation);
10936                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10937                    return true;
10938                }
10939            }
10940            mHandler.post(new Runnable() {
10941                @Override
10942                public void run() {
10943                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10944                }
10945            });
10946        }
10947
10948        return true;
10949    }
10950
10951    @Override
10952    public Bundle getAssistContextExtras(int requestType) {
10953        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10954                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10955        if (pae == null) {
10956            return null;
10957        }
10958        synchronized (pae) {
10959            while (!pae.haveResult) {
10960                try {
10961                    pae.wait();
10962                } catch (InterruptedException e) {
10963                }
10964            }
10965        }
10966        synchronized (this) {
10967            buildAssistBundleLocked(pae, pae.result);
10968            mPendingAssistExtras.remove(pae);
10969            mUiHandler.removeCallbacks(pae);
10970        }
10971        return pae.extras;
10972    }
10973
10974    @Override
10975    public boolean isAssistDataAllowedOnCurrentActivity() {
10976        int userId;
10977        synchronized (this) {
10978            userId = mUserController.mCurrentUserId;
10979            ActivityRecord activity = getFocusedStack().topActivity();
10980            if (activity == null) {
10981                return false;
10982            }
10983            userId = activity.userId;
10984        }
10985        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10986                Context.DEVICE_POLICY_SERVICE);
10987        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10988    }
10989
10990    @Override
10991    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10992        long ident = Binder.clearCallingIdentity();
10993        try {
10994            synchronized (this) {
10995                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10996                ActivityRecord top = getFocusedStack().topActivity();
10997                if (top != caller) {
10998                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10999                            + " is not current top " + top);
11000                    return false;
11001                }
11002                if (!top.nowVisible) {
11003                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11004                            + " is not visible");
11005                    return false;
11006                }
11007            }
11008            AssistUtils utils = new AssistUtils(mContext);
11009            return utils.showSessionForActiveService(args,
11010                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11011        } finally {
11012            Binder.restoreCallingIdentity(ident);
11013        }
11014    }
11015
11016    @Override
11017    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11018            IBinder activityToken) {
11019        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11020                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11021    }
11022
11023    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11024            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11025            long timeout) {
11026        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11027                "enqueueAssistContext()");
11028        synchronized (this) {
11029            ActivityRecord activity = getFocusedStack().topActivity();
11030            if (activity == null) {
11031                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11032                return null;
11033            }
11034            if (activity.app == null || activity.app.thread == null) {
11035                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11036                return null;
11037            }
11038            if (activityToken != null) {
11039                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11040                if (activity != caller) {
11041                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11042                            + " is not current top " + activity);
11043                    return null;
11044                }
11045            }
11046            PendingAssistExtras pae;
11047            Bundle extras = new Bundle();
11048            if (args != null) {
11049                extras.putAll(args);
11050            }
11051            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11052            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11053            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11054            try {
11055                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11056                        requestType);
11057                mPendingAssistExtras.add(pae);
11058                mUiHandler.postDelayed(pae, timeout);
11059            } catch (RemoteException e) {
11060                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11061                return null;
11062            }
11063            return pae;
11064        }
11065    }
11066
11067    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11068        IResultReceiver receiver;
11069        synchronized (this) {
11070            mPendingAssistExtras.remove(pae);
11071            receiver = pae.receiver;
11072        }
11073        if (receiver != null) {
11074            // Caller wants result sent back to them.
11075            try {
11076                pae.receiver.send(0, null);
11077            } catch (RemoteException e) {
11078            }
11079        }
11080    }
11081
11082    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11083        if (result != null) {
11084            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11085        }
11086        if (pae.hint != null) {
11087            pae.extras.putBoolean(pae.hint, true);
11088        }
11089    }
11090
11091    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11092            AssistContent content, Uri referrer) {
11093        PendingAssistExtras pae = (PendingAssistExtras)token;
11094        synchronized (pae) {
11095            pae.result = extras;
11096            pae.structure = structure;
11097            pae.content = content;
11098            if (referrer != null) {
11099                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11100            }
11101            pae.haveResult = true;
11102            pae.notifyAll();
11103            if (pae.intent == null && pae.receiver == null) {
11104                // Caller is just waiting for the result.
11105                return;
11106            }
11107        }
11108
11109        // We are now ready to launch the assist activity.
11110        IResultReceiver sendReceiver = null;
11111        Bundle sendBundle = null;
11112        synchronized (this) {
11113            buildAssistBundleLocked(pae, extras);
11114            boolean exists = mPendingAssistExtras.remove(pae);
11115            mUiHandler.removeCallbacks(pae);
11116            if (!exists) {
11117                // Timed out.
11118                return;
11119            }
11120            if ((sendReceiver=pae.receiver) != null) {
11121                // Caller wants result sent back to them.
11122                sendBundle = new Bundle();
11123                sendBundle.putBundle("data", pae.extras);
11124                sendBundle.putParcelable("structure", pae.structure);
11125                sendBundle.putParcelable("content", pae.content);
11126            }
11127        }
11128        if (sendReceiver != null) {
11129            try {
11130                sendReceiver.send(0, sendBundle);
11131            } catch (RemoteException e) {
11132            }
11133            return;
11134        }
11135
11136        long ident = Binder.clearCallingIdentity();
11137        try {
11138            pae.intent.replaceExtras(pae.extras);
11139            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11140                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11141                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11142            closeSystemDialogs("assist");
11143            try {
11144                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11145            } catch (ActivityNotFoundException e) {
11146                Slog.w(TAG, "No activity to handle assist action.", e);
11147            }
11148        } finally {
11149            Binder.restoreCallingIdentity(ident);
11150        }
11151    }
11152
11153    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11154            Bundle args) {
11155        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11156                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11157    }
11158
11159    public void registerProcessObserver(IProcessObserver observer) {
11160        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11161                "registerProcessObserver()");
11162        synchronized (this) {
11163            mProcessObservers.register(observer);
11164        }
11165    }
11166
11167    @Override
11168    public void unregisterProcessObserver(IProcessObserver observer) {
11169        synchronized (this) {
11170            mProcessObservers.unregister(observer);
11171        }
11172    }
11173
11174    public void registerUidObserver(IUidObserver observer) {
11175        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11176                "registerUidObserver()");
11177        synchronized (this) {
11178            mUidObservers.register(observer);
11179        }
11180    }
11181
11182    @Override
11183    public void unregisterUidObserver(IUidObserver observer) {
11184        synchronized (this) {
11185            mUidObservers.unregister(observer);
11186        }
11187    }
11188
11189    @Override
11190    public boolean convertFromTranslucent(IBinder token) {
11191        final long origId = Binder.clearCallingIdentity();
11192        try {
11193            synchronized (this) {
11194                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11195                if (r == null) {
11196                    return false;
11197                }
11198                final boolean translucentChanged = r.changeWindowTranslucency(true);
11199                if (translucentChanged) {
11200                    r.task.stack.releaseBackgroundResources(r);
11201                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11202                }
11203                mWindowManager.setAppFullscreen(token, true);
11204                return translucentChanged;
11205            }
11206        } finally {
11207            Binder.restoreCallingIdentity(origId);
11208        }
11209    }
11210
11211    @Override
11212    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11213        final long origId = Binder.clearCallingIdentity();
11214        try {
11215            synchronized (this) {
11216                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11217                if (r == null) {
11218                    return false;
11219                }
11220                int index = r.task.mActivities.lastIndexOf(r);
11221                if (index > 0) {
11222                    ActivityRecord under = r.task.mActivities.get(index - 1);
11223                    under.returningOptions = options;
11224                }
11225                final boolean translucentChanged = r.changeWindowTranslucency(false);
11226                if (translucentChanged) {
11227                    r.task.stack.convertActivityToTranslucent(r);
11228                }
11229                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11230                mWindowManager.setAppFullscreen(token, false);
11231                return translucentChanged;
11232            }
11233        } finally {
11234            Binder.restoreCallingIdentity(origId);
11235        }
11236    }
11237
11238    @Override
11239    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11240        final long origId = Binder.clearCallingIdentity();
11241        try {
11242            synchronized (this) {
11243                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11244                if (r != null) {
11245                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11246                }
11247            }
11248            return false;
11249        } finally {
11250            Binder.restoreCallingIdentity(origId);
11251        }
11252    }
11253
11254    @Override
11255    public boolean isBackgroundVisibleBehind(IBinder token) {
11256        final long origId = Binder.clearCallingIdentity();
11257        try {
11258            synchronized (this) {
11259                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11260                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11261                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11262                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11263                return visible;
11264            }
11265        } finally {
11266            Binder.restoreCallingIdentity(origId);
11267        }
11268    }
11269
11270    @Override
11271    public ActivityOptions getActivityOptions(IBinder token) {
11272        final long origId = Binder.clearCallingIdentity();
11273        try {
11274            synchronized (this) {
11275                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11276                if (r != null) {
11277                    final ActivityOptions activityOptions = r.pendingOptions;
11278                    r.pendingOptions = null;
11279                    return activityOptions;
11280                }
11281                return null;
11282            }
11283        } finally {
11284            Binder.restoreCallingIdentity(origId);
11285        }
11286    }
11287
11288    @Override
11289    public void setImmersive(IBinder token, boolean immersive) {
11290        synchronized(this) {
11291            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11292            if (r == null) {
11293                throw new IllegalArgumentException();
11294            }
11295            r.immersive = immersive;
11296
11297            // update associated state if we're frontmost
11298            if (r == mFocusedActivity) {
11299                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11300                applyUpdateLockStateLocked(r);
11301            }
11302        }
11303    }
11304
11305    @Override
11306    public boolean isImmersive(IBinder token) {
11307        synchronized (this) {
11308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11309            if (r == null) {
11310                throw new IllegalArgumentException();
11311            }
11312            return r.immersive;
11313        }
11314    }
11315
11316    public boolean isTopActivityImmersive() {
11317        enforceNotIsolatedCaller("startActivity");
11318        synchronized (this) {
11319            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11320            return (r != null) ? r.immersive : false;
11321        }
11322    }
11323
11324    @Override
11325    public boolean isTopOfTask(IBinder token) {
11326        synchronized (this) {
11327            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11328            if (r == null) {
11329                throw new IllegalArgumentException();
11330            }
11331            return r.task.getTopActivity() == r;
11332        }
11333    }
11334
11335    public final void enterSafeMode() {
11336        synchronized(this) {
11337            // It only makes sense to do this before the system is ready
11338            // and started launching other packages.
11339            if (!mSystemReady) {
11340                try {
11341                    AppGlobals.getPackageManager().enterSafeMode();
11342                } catch (RemoteException e) {
11343                }
11344            }
11345
11346            mSafeMode = true;
11347        }
11348    }
11349
11350    public final void showSafeModeOverlay() {
11351        View v = LayoutInflater.from(mContext).inflate(
11352                com.android.internal.R.layout.safe_mode, null);
11353        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11354        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11355        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11356        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11357        lp.gravity = Gravity.BOTTOM | Gravity.START;
11358        lp.format = v.getBackground().getOpacity();
11359        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11360                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11361        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11362        ((WindowManager)mContext.getSystemService(
11363                Context.WINDOW_SERVICE)).addView(v, lp);
11364    }
11365
11366    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11367        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11368            return;
11369        }
11370        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11371        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11372        synchronized (stats) {
11373            if (mBatteryStatsService.isOnBattery()) {
11374                mBatteryStatsService.enforceCallingPermission();
11375                int MY_UID = Binder.getCallingUid();
11376                final int uid;
11377                if (sender == null) {
11378                    uid = sourceUid;
11379                } else {
11380                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11381                }
11382                BatteryStatsImpl.Uid.Pkg pkg =
11383                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11384                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11385                pkg.noteWakeupAlarmLocked(tag);
11386            }
11387        }
11388    }
11389
11390    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11391        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11392            return;
11393        }
11394        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11395        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11396        synchronized (stats) {
11397            mBatteryStatsService.enforceCallingPermission();
11398            int MY_UID = Binder.getCallingUid();
11399            final int uid;
11400            if (sender == null) {
11401                uid = sourceUid;
11402            } else {
11403                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11404            }
11405            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11406        }
11407    }
11408
11409    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11410        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11411            return;
11412        }
11413        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11414        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11415        synchronized (stats) {
11416            mBatteryStatsService.enforceCallingPermission();
11417            int MY_UID = Binder.getCallingUid();
11418            final int uid;
11419            if (sender == null) {
11420                uid = sourceUid;
11421            } else {
11422                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11423            }
11424            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11425        }
11426    }
11427
11428    public boolean killPids(int[] pids, String pReason, boolean secure) {
11429        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11430            throw new SecurityException("killPids only available to the system");
11431        }
11432        String reason = (pReason == null) ? "Unknown" : pReason;
11433        // XXX Note: don't acquire main activity lock here, because the window
11434        // manager calls in with its locks held.
11435
11436        boolean killed = false;
11437        synchronized (mPidsSelfLocked) {
11438            int[] types = new int[pids.length];
11439            int worstType = 0;
11440            for (int i=0; i<pids.length; i++) {
11441                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11442                if (proc != null) {
11443                    int type = proc.setAdj;
11444                    types[i] = type;
11445                    if (type > worstType) {
11446                        worstType = type;
11447                    }
11448                }
11449            }
11450
11451            // If the worst oom_adj is somewhere in the cached proc LRU range,
11452            // then constrain it so we will kill all cached procs.
11453            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11454                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11455                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11456            }
11457
11458            // If this is not a secure call, don't let it kill processes that
11459            // are important.
11460            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11461                worstType = ProcessList.SERVICE_ADJ;
11462            }
11463
11464            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11465            for (int i=0; i<pids.length; i++) {
11466                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11467                if (proc == null) {
11468                    continue;
11469                }
11470                int adj = proc.setAdj;
11471                if (adj >= worstType && !proc.killedByAm) {
11472                    proc.kill(reason, true);
11473                    killed = true;
11474                }
11475            }
11476        }
11477        return killed;
11478    }
11479
11480    @Override
11481    public void killUid(int appId, int userId, String reason) {
11482        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11483        synchronized (this) {
11484            final long identity = Binder.clearCallingIdentity();
11485            try {
11486                killPackageProcessesLocked(null, appId, userId,
11487                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11488                        reason != null ? reason : "kill uid");
11489            } finally {
11490                Binder.restoreCallingIdentity(identity);
11491            }
11492        }
11493    }
11494
11495    @Override
11496    public boolean killProcessesBelowForeground(String reason) {
11497        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11498            throw new SecurityException("killProcessesBelowForeground() only available to system");
11499        }
11500
11501        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11502    }
11503
11504    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11505        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11506            throw new SecurityException("killProcessesBelowAdj() only available to system");
11507        }
11508
11509        boolean killed = false;
11510        synchronized (mPidsSelfLocked) {
11511            final int size = mPidsSelfLocked.size();
11512            for (int i = 0; i < size; i++) {
11513                final int pid = mPidsSelfLocked.keyAt(i);
11514                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11515                if (proc == null) continue;
11516
11517                final int adj = proc.setAdj;
11518                if (adj > belowAdj && !proc.killedByAm) {
11519                    proc.kill(reason, true);
11520                    killed = true;
11521                }
11522            }
11523        }
11524        return killed;
11525    }
11526
11527    @Override
11528    public void hang(final IBinder who, boolean allowRestart) {
11529        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11530                != PackageManager.PERMISSION_GRANTED) {
11531            throw new SecurityException("Requires permission "
11532                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11533        }
11534
11535        final IBinder.DeathRecipient death = new DeathRecipient() {
11536            @Override
11537            public void binderDied() {
11538                synchronized (this) {
11539                    notifyAll();
11540                }
11541            }
11542        };
11543
11544        try {
11545            who.linkToDeath(death, 0);
11546        } catch (RemoteException e) {
11547            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11548            return;
11549        }
11550
11551        synchronized (this) {
11552            Watchdog.getInstance().setAllowRestart(allowRestart);
11553            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11554            synchronized (death) {
11555                while (who.isBinderAlive()) {
11556                    try {
11557                        death.wait();
11558                    } catch (InterruptedException e) {
11559                    }
11560                }
11561            }
11562            Watchdog.getInstance().setAllowRestart(true);
11563        }
11564    }
11565
11566    @Override
11567    public void restart() {
11568        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11569                != PackageManager.PERMISSION_GRANTED) {
11570            throw new SecurityException("Requires permission "
11571                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11572        }
11573
11574        Log.i(TAG, "Sending shutdown broadcast...");
11575
11576        BroadcastReceiver br = new BroadcastReceiver() {
11577            @Override public void onReceive(Context context, Intent intent) {
11578                // Now the broadcast is done, finish up the low-level shutdown.
11579                Log.i(TAG, "Shutting down activity manager...");
11580                shutdown(10000);
11581                Log.i(TAG, "Shutdown complete, restarting!");
11582                Process.killProcess(Process.myPid());
11583                System.exit(10);
11584            }
11585        };
11586
11587        // First send the high-level shut down broadcast.
11588        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11589        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11590        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11591        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11592        mContext.sendOrderedBroadcastAsUser(intent,
11593                UserHandle.ALL, null, br, mHandler, 0, null, null);
11594        */
11595        br.onReceive(mContext, intent);
11596    }
11597
11598    private long getLowRamTimeSinceIdle(long now) {
11599        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11600    }
11601
11602    @Override
11603    public void performIdleMaintenance() {
11604        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11605                != PackageManager.PERMISSION_GRANTED) {
11606            throw new SecurityException("Requires permission "
11607                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11608        }
11609
11610        synchronized (this) {
11611            final long now = SystemClock.uptimeMillis();
11612            final long timeSinceLastIdle = now - mLastIdleTime;
11613            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11614            mLastIdleTime = now;
11615            mLowRamTimeSinceLastIdle = 0;
11616            if (mLowRamStartTime != 0) {
11617                mLowRamStartTime = now;
11618            }
11619
11620            StringBuilder sb = new StringBuilder(128);
11621            sb.append("Idle maintenance over ");
11622            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11623            sb.append(" low RAM for ");
11624            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11625            Slog.i(TAG, sb.toString());
11626
11627            // If at least 1/3 of our time since the last idle period has been spent
11628            // with RAM low, then we want to kill processes.
11629            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11630
11631            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11632                ProcessRecord proc = mLruProcesses.get(i);
11633                if (proc.notCachedSinceIdle) {
11634                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11635                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11636                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11637                        if (doKilling && proc.initialIdlePss != 0
11638                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11639                            sb = new StringBuilder(128);
11640                            sb.append("Kill");
11641                            sb.append(proc.processName);
11642                            sb.append(" in idle maint: pss=");
11643                            sb.append(proc.lastPss);
11644                            sb.append(", initialPss=");
11645                            sb.append(proc.initialIdlePss);
11646                            sb.append(", period=");
11647                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11648                            sb.append(", lowRamPeriod=");
11649                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11650                            Slog.wtfQuiet(TAG, sb.toString());
11651                            proc.kill("idle maint (pss " + proc.lastPss
11652                                    + " from " + proc.initialIdlePss + ")", true);
11653                        }
11654                    }
11655                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11656                    proc.notCachedSinceIdle = true;
11657                    proc.initialIdlePss = 0;
11658                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11659                            mTestPssMode, isSleeping(), now);
11660                }
11661            }
11662
11663            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11664            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11665        }
11666    }
11667
11668    private void retrieveSettings() {
11669        final ContentResolver resolver = mContext.getContentResolver();
11670        String debugApp = Settings.Global.getString(resolver, Settings.Global.DEBUG_APP);
11671        boolean waitForDebugger = Settings.Global.getInt(
11672            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11673        boolean alwaysFinishActivities = Settings.Global.getInt(
11674            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11675        boolean forceRtl = Settings.Global.getInt(
11676                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11677        int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
11678        boolean forceResizable = Settings.Global.getInt(
11679                resolver, Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
11680                defaultForceResizable) != 0;
11681        // Transfer any global setting for forcing RTL layout, into a System Property
11682        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11683
11684        Configuration configuration = new Configuration();
11685        Settings.System.getConfiguration(resolver, configuration);
11686        if (forceRtl) {
11687            // This will take care of setting the correct layout direction flags
11688            configuration.setLayoutDirection(configuration.locale);
11689        }
11690
11691        synchronized (this) {
11692            mDebugApp = mOrigDebugApp = debugApp;
11693            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11694            mAlwaysFinishActivities = alwaysFinishActivities;
11695            mForceResizableActivites = forceResizable;
11696            // This happens before any activities are started, so we can
11697            // change mConfiguration in-place.
11698            updateConfigurationLocked(configuration, null, true);
11699            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11700                    "Initial config: " + mConfiguration);
11701        }
11702    }
11703
11704    /** Loads resources after the current configuration has been set. */
11705    private void loadResourcesOnSystemReady() {
11706        final Resources res = mContext.getResources();
11707        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11708        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11709        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11710    }
11711
11712    public boolean testIsSystemReady() {
11713        // no need to synchronize(this) just to read & return the value
11714        return mSystemReady;
11715    }
11716
11717    private static File getCalledPreBootReceiversFile() {
11718        File dataDir = Environment.getDataDirectory();
11719        File systemDir = new File(dataDir, "system");
11720        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11721        return fname;
11722    }
11723
11724    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11725        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11726        File file = getCalledPreBootReceiversFile();
11727        FileInputStream fis = null;
11728        try {
11729            fis = new FileInputStream(file);
11730            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11731            int fvers = dis.readInt();
11732            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11733                String vers = dis.readUTF();
11734                String codename = dis.readUTF();
11735                String build = dis.readUTF();
11736                if (android.os.Build.VERSION.RELEASE.equals(vers)
11737                        && android.os.Build.VERSION.CODENAME.equals(codename)
11738                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11739                    int num = dis.readInt();
11740                    while (num > 0) {
11741                        num--;
11742                        String pkg = dis.readUTF();
11743                        String cls = dis.readUTF();
11744                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11745                    }
11746                }
11747            }
11748        } catch (FileNotFoundException e) {
11749        } catch (IOException e) {
11750            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11751        } finally {
11752            if (fis != null) {
11753                try {
11754                    fis.close();
11755                } catch (IOException e) {
11756                }
11757            }
11758        }
11759        return lastDoneReceivers;
11760    }
11761
11762    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11763        File file = getCalledPreBootReceiversFile();
11764        FileOutputStream fos = null;
11765        DataOutputStream dos = null;
11766        try {
11767            fos = new FileOutputStream(file);
11768            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11769            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11770            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11771            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11772            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11773            dos.writeInt(list.size());
11774            for (int i=0; i<list.size(); i++) {
11775                dos.writeUTF(list.get(i).getPackageName());
11776                dos.writeUTF(list.get(i).getClassName());
11777            }
11778        } catch (IOException e) {
11779            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11780            file.delete();
11781        } finally {
11782            FileUtils.sync(fos);
11783            if (dos != null) {
11784                try {
11785                    dos.close();
11786                } catch (IOException e) {
11787                    // TODO Auto-generated catch block
11788                    e.printStackTrace();
11789                }
11790            }
11791        }
11792    }
11793
11794    final class PreBootContinuation extends IIntentReceiver.Stub {
11795        final Intent intent;
11796        final Runnable onFinishCallback;
11797        final ArrayList<ComponentName> doneReceivers;
11798        final List<ResolveInfo> ris;
11799        final int[] users;
11800        int lastRi = -1;
11801        int curRi = 0;
11802        int curUser = 0;
11803
11804        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11805                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11806            intent = _intent;
11807            onFinishCallback = _onFinishCallback;
11808            doneReceivers = _doneReceivers;
11809            ris = _ris;
11810            users = _users;
11811        }
11812
11813        void go() {
11814            if (lastRi != curRi) {
11815                ActivityInfo ai = ris.get(curRi).activityInfo;
11816                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11817                intent.setComponent(comp);
11818                doneReceivers.add(comp);
11819                lastRi = curRi;
11820                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11821                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11822            }
11823            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11824                    + " for user " + users[curUser]);
11825            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11826            broadcastIntentLocked(null, null, intent, null, this,
11827                    0, null, null, null, AppOpsManager.OP_NONE,
11828                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11829        }
11830
11831        public void performReceive(Intent intent, int resultCode,
11832                String data, Bundle extras, boolean ordered,
11833                boolean sticky, int sendingUser) {
11834            curUser++;
11835            if (curUser >= users.length) {
11836                curUser = 0;
11837                curRi++;
11838                if (curRi >= ris.size()) {
11839                    // All done sending broadcasts!
11840                    if (onFinishCallback != null) {
11841                        // The raw IIntentReceiver interface is called
11842                        // with the AM lock held, so redispatch to
11843                        // execute our code without the lock.
11844                        mHandler.post(onFinishCallback);
11845                    }
11846                    return;
11847                }
11848            }
11849            go();
11850        }
11851    }
11852
11853    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11854            ArrayList<ComponentName> doneReceivers) {
11855        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11856        List<ResolveInfo> ris = null;
11857        try {
11858            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11859                    intent, null, 0, UserHandle.USER_SYSTEM);
11860        } catch (RemoteException e) {
11861        }
11862        if (ris == null) {
11863            return false;
11864        }
11865        for (int i=ris.size()-1; i>=0; i--) {
11866            if ((ris.get(i).activityInfo.applicationInfo.flags
11867                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11868                ris.remove(i);
11869            }
11870        }
11871        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11872
11873        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11874        for (int i=0; i<ris.size(); i++) {
11875            ActivityInfo ai = ris.get(i).activityInfo;
11876            ComponentName comp = new ComponentName(ai.packageName, ai.name);
11877            if (lastDoneReceivers.contains(comp)) {
11878                // We already did the pre boot receiver for this app with the current
11879                // platform version, so don't do it again...
11880                ris.remove(i);
11881                i--;
11882                // ...however, do keep it as one that has been done, so we don't
11883                // forget about it when rewriting the file of last done receivers.
11884                doneReceivers.add(comp);
11885            }
11886        }
11887
11888        if (ris.size() <= 0) {
11889            return false;
11890        }
11891
11892        // TODO: can we still do this with per user encryption?
11893        final int[] users = getUsersLocked();
11894        if (users.length <= 0) {
11895            return false;
11896        }
11897
11898        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11899                ris, users);
11900        cont.go();
11901        return true;
11902    }
11903
11904    public void systemReady(final Runnable goingCallback) {
11905        synchronized(this) {
11906            if (mSystemReady) {
11907                // If we're done calling all the receivers, run the next "boot phase" passed in
11908                // by the SystemServer
11909                if (goingCallback != null) {
11910                    goingCallback.run();
11911                }
11912                return;
11913            }
11914
11915            mLocalDeviceIdleController
11916                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11917
11918            // Make sure we have the current profile info, since it is needed for
11919            // security checks.
11920            mUserController.updateCurrentProfileIdsLocked();
11921
11922            mRecentTasks.clear();
11923            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(
11924                    getUserManagerLocked().getUserIds()));
11925            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11926            mTaskPersister.startPersisting();
11927
11928            // Check to see if there are any update receivers to run.
11929            if (!mDidUpdate) {
11930                if (mWaitingUpdate) {
11931                    return;
11932                }
11933                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11934                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11935                    public void run() {
11936                        synchronized (ActivityManagerService.this) {
11937                            mDidUpdate = true;
11938                        }
11939                        showBootMessage(mContext.getText(
11940                                R.string.android_upgrading_complete),
11941                                false);
11942                        writeLastDonePreBootReceivers(doneReceivers);
11943                        systemReady(goingCallback);
11944                    }
11945                }, doneReceivers);
11946
11947                if (mWaitingUpdate) {
11948                    return;
11949                }
11950                mDidUpdate = true;
11951            }
11952
11953            mAppOpsService.systemReady();
11954            mSystemReady = true;
11955        }
11956
11957        ArrayList<ProcessRecord> procsToKill = null;
11958        synchronized(mPidsSelfLocked) {
11959            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11960                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11961                if (!isAllowedWhileBooting(proc.info)){
11962                    if (procsToKill == null) {
11963                        procsToKill = new ArrayList<ProcessRecord>();
11964                    }
11965                    procsToKill.add(proc);
11966                }
11967            }
11968        }
11969
11970        synchronized(this) {
11971            if (procsToKill != null) {
11972                for (int i=procsToKill.size()-1; i>=0; i--) {
11973                    ProcessRecord proc = procsToKill.get(i);
11974                    Slog.i(TAG, "Removing system update proc: " + proc);
11975                    removeProcessLocked(proc, true, false, "system update done");
11976                }
11977            }
11978
11979            // Now that we have cleaned up any update processes, we
11980            // are ready to start launching real processes and know that
11981            // we won't trample on them any more.
11982            mProcessesReady = true;
11983        }
11984
11985        Slog.i(TAG, "System now ready");
11986        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11987            SystemClock.uptimeMillis());
11988
11989        synchronized(this) {
11990            // Make sure we have no pre-ready processes sitting around.
11991
11992            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11993                ResolveInfo ri = mContext.getPackageManager()
11994                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11995                                STOCK_PM_FLAGS);
11996                CharSequence errorMsg = null;
11997                if (ri != null) {
11998                    ActivityInfo ai = ri.activityInfo;
11999                    ApplicationInfo app = ai.applicationInfo;
12000                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12001                        mTopAction = Intent.ACTION_FACTORY_TEST;
12002                        mTopData = null;
12003                        mTopComponent = new ComponentName(app.packageName,
12004                                ai.name);
12005                    } else {
12006                        errorMsg = mContext.getResources().getText(
12007                                com.android.internal.R.string.factorytest_not_system);
12008                    }
12009                } else {
12010                    errorMsg = mContext.getResources().getText(
12011                            com.android.internal.R.string.factorytest_no_action);
12012                }
12013                if (errorMsg != null) {
12014                    mTopAction = null;
12015                    mTopData = null;
12016                    mTopComponent = null;
12017                    Message msg = Message.obtain();
12018                    msg.what = SHOW_FACTORY_ERROR_MSG;
12019                    msg.getData().putCharSequence("msg", errorMsg);
12020                    mUiHandler.sendMessage(msg);
12021                }
12022            }
12023        }
12024
12025        retrieveSettings();
12026        loadResourcesOnSystemReady();
12027        final int currentUserId;
12028        synchronized (this) {
12029            currentUserId = mUserController.mCurrentUserId;
12030            readGrantedUriPermissionsLocked();
12031        }
12032
12033        if (goingCallback != null) goingCallback.run();
12034
12035
12036        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12037                Integer.toString(currentUserId), currentUserId);
12038        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12039                Integer.toString(currentUserId), currentUserId);
12040        mSystemServiceManager.startUser(currentUserId);
12041
12042        synchronized (this) {
12043            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12044                try {
12045                    List apps = AppGlobals.getPackageManager().
12046                        getPersistentApplications(STOCK_PM_FLAGS);
12047                    if (apps != null) {
12048                        int N = apps.size();
12049                        int i;
12050                        for (i=0; i<N; i++) {
12051                            ApplicationInfo info
12052                                = (ApplicationInfo)apps.get(i);
12053                            if (info != null &&
12054                                    !info.packageName.equals("android")) {
12055                                addAppLocked(info, false, null /* ABI override */);
12056                            }
12057                        }
12058                    }
12059                } catch (RemoteException ex) {
12060                    // pm is in same process, this will never happen.
12061                }
12062            }
12063
12064            enableSystemUserApps();
12065
12066            // Start up initial activity.
12067            mBooting = true;
12068            startHomeActivityLocked(currentUserId, "systemReady");
12069
12070            try {
12071                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12072                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12073                            + " data partition or your device will be unstable.");
12074                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
12075                }
12076            } catch (RemoteException e) {
12077            }
12078
12079            if (!Build.isBuildConsistent()) {
12080                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12081                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
12082            }
12083
12084            long ident = Binder.clearCallingIdentity();
12085            try {
12086                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12087                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12088                        | Intent.FLAG_RECEIVER_FOREGROUND);
12089                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12090                broadcastIntentLocked(null, null, intent,
12091                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12092                        null, false, false, MY_PID, Process.SYSTEM_UID,
12093                        currentUserId);
12094                intent = new Intent(Intent.ACTION_USER_STARTING);
12095                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12096                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12097                broadcastIntentLocked(null, null, intent,
12098                        null, new IIntentReceiver.Stub() {
12099                            @Override
12100                            public void performReceive(Intent intent, int resultCode, String data,
12101                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12102                                    throws RemoteException {
12103                            }
12104                        }, 0, null, null,
12105                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12106                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12107            } catch (Throwable t) {
12108                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12109            } finally {
12110                Binder.restoreCallingIdentity(ident);
12111            }
12112            mStackSupervisor.resumeTopActivitiesLocked();
12113            sendUserSwitchBroadcastsLocked(-1, currentUserId);
12114        }
12115    }
12116
12117    private void enableSystemUserApps() {
12118        // For system user, enable apps based on the following conditions:
12119        // - app is whitelisted; or has no launcher icons; or has INTERACT_ACROSS_USERS permission
12120        // - app is not in the blacklist
12121        if (UserManager.isSplitSystemUser()) {
12122            AppsQueryHelper queryHelper = new AppsQueryHelper(mContext);
12123            Set<String> enableApps = new HashSet<>();
12124            enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
12125                            | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
12126                            | AppsQueryHelper.GET_DEFAULT_IMES,
12127                            /* systemAppsOnly */ true, UserHandle.SYSTEM));
12128            ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
12129            enableApps.addAll(wlApps);
12130            ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
12131            enableApps.removeAll(blApps);
12132
12133            List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true,
12134                    UserHandle.SYSTEM);
12135            final int systemAppsSize = systemApps.size();
12136            for (int i = 0; i < systemAppsSize; i++) {
12137                String pName = systemApps.get(i);
12138                boolean enable = enableApps.contains(pName);
12139                try {
12140                    if (enable) {
12141                        AppGlobals.getPackageManager().installExistingPackageAsUser(pName,
12142                                UserHandle.USER_SYSTEM);
12143                    } else {
12144                        AppGlobals.getPackageManager().deletePackageAsUser(pName, null,
12145                                UserHandle.USER_SYSTEM, PackageManager.DELETE_SYSTEM_APP);
12146                    }
12147                } catch (RemoteException e) {
12148                    Slog.e(TAG, "Error occured when processing package " + pName, e);
12149                }
12150            }
12151        }
12152    }
12153
12154    private boolean makeAppCrashingLocked(ProcessRecord app,
12155            String shortMsg, String longMsg, String stackTrace) {
12156        app.crashing = true;
12157        app.crashingReport = generateProcessError(app,
12158                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12159        startAppProblemLocked(app);
12160        app.stopFreezingAllLocked();
12161        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12162    }
12163
12164    private void makeAppNotRespondingLocked(ProcessRecord app,
12165            String activity, String shortMsg, String longMsg) {
12166        app.notResponding = true;
12167        app.notRespondingReport = generateProcessError(app,
12168                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12169                activity, shortMsg, longMsg, null);
12170        startAppProblemLocked(app);
12171        app.stopFreezingAllLocked();
12172    }
12173
12174    /**
12175     * Generate a process error record, suitable for attachment to a ProcessRecord.
12176     *
12177     * @param app The ProcessRecord in which the error occurred.
12178     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12179     *                      ActivityManager.AppErrorStateInfo
12180     * @param activity The activity associated with the crash, if known.
12181     * @param shortMsg Short message describing the crash.
12182     * @param longMsg Long message describing the crash.
12183     * @param stackTrace Full crash stack trace, may be null.
12184     *
12185     * @return Returns a fully-formed AppErrorStateInfo record.
12186     */
12187    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12188            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12189        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12190
12191        report.condition = condition;
12192        report.processName = app.processName;
12193        report.pid = app.pid;
12194        report.uid = app.info.uid;
12195        report.tag = activity;
12196        report.shortMsg = shortMsg;
12197        report.longMsg = longMsg;
12198        report.stackTrace = stackTrace;
12199
12200        return report;
12201    }
12202
12203    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12204        synchronized (this) {
12205            app.crashing = false;
12206            app.crashingReport = null;
12207            app.notResponding = false;
12208            app.notRespondingReport = null;
12209            if (app.anrDialog == fromDialog) {
12210                app.anrDialog = null;
12211            }
12212            if (app.waitDialog == fromDialog) {
12213                app.waitDialog = null;
12214            }
12215            if (app.pid > 0 && app.pid != MY_PID) {
12216                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12217                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12218                app.kill("user request after error", true);
12219            }
12220        }
12221    }
12222
12223    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12224            String shortMsg, String longMsg, String stackTrace) {
12225        long now = SystemClock.uptimeMillis();
12226
12227        Long crashTime;
12228        if (!app.isolated) {
12229            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12230        } else {
12231            crashTime = null;
12232        }
12233        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12234            // This process loses!
12235            Slog.w(TAG, "Process " + app.info.processName
12236                    + " has crashed too many times: killing!");
12237            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12238                    app.userId, app.info.processName, app.uid);
12239            mStackSupervisor.handleAppCrashLocked(app);
12240            if (!app.persistent) {
12241                // We don't want to start this process again until the user
12242                // explicitly does so...  but for persistent process, we really
12243                // need to keep it running.  If a persistent process is actually
12244                // repeatedly crashing, then badness for everyone.
12245                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12246                        app.info.processName);
12247                if (!app.isolated) {
12248                    // XXX We don't have a way to mark isolated processes
12249                    // as bad, since they don't have a peristent identity.
12250                    mBadProcesses.put(app.info.processName, app.uid,
12251                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12252                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12253                }
12254                app.bad = true;
12255                app.removed = true;
12256                // Don't let services in this process be restarted and potentially
12257                // annoy the user repeatedly.  Unless it is persistent, since those
12258                // processes run critical code.
12259                removeProcessLocked(app, false, false, "crash");
12260                mStackSupervisor.resumeTopActivitiesLocked();
12261                return false;
12262            }
12263            mStackSupervisor.resumeTopActivitiesLocked();
12264        } else {
12265            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12266        }
12267
12268        // Bump up the crash count of any services currently running in the proc.
12269        for (int i=app.services.size()-1; i>=0; i--) {
12270            // Any services running in the application need to be placed
12271            // back in the pending list.
12272            ServiceRecord sr = app.services.valueAt(i);
12273            sr.crashCount++;
12274        }
12275
12276        // If the crashing process is what we consider to be the "home process" and it has been
12277        // replaced by a third-party app, clear the package preferred activities from packages
12278        // with a home activity running in the process to prevent a repeatedly crashing app
12279        // from blocking the user to manually clear the list.
12280        final ArrayList<ActivityRecord> activities = app.activities;
12281        if (app == mHomeProcess && activities.size() > 0
12282                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12283            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12284                final ActivityRecord r = activities.get(activityNdx);
12285                if (r.isHomeActivity()) {
12286                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12287                    try {
12288                        ActivityThread.getPackageManager()
12289                                .clearPackagePreferredActivities(r.packageName);
12290                    } catch (RemoteException c) {
12291                        // pm is in same process, this will never happen.
12292                    }
12293                }
12294            }
12295        }
12296
12297        if (!app.isolated) {
12298            // XXX Can't keep track of crash times for isolated processes,
12299            // because they don't have a perisistent identity.
12300            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12301        }
12302
12303        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12304        return true;
12305    }
12306
12307    void startAppProblemLocked(ProcessRecord app) {
12308        // If this app is not running under the current user, then we
12309        // can't give it a report button because that would require
12310        // launching the report UI under a different user.
12311        app.errorReportReceiver = null;
12312
12313        for (int userId : mUserController.mCurrentProfileIds) {
12314            if (app.userId == userId) {
12315                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12316                        mContext, app.info.packageName, app.info.flags);
12317            }
12318        }
12319        skipCurrentReceiverLocked(app);
12320    }
12321
12322    void skipCurrentReceiverLocked(ProcessRecord app) {
12323        for (BroadcastQueue queue : mBroadcastQueues) {
12324            queue.skipCurrentReceiverLocked(app);
12325        }
12326    }
12327
12328    /**
12329     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12330     * The application process will exit immediately after this call returns.
12331     * @param app object of the crashing app, null for the system server
12332     * @param crashInfo describing the exception
12333     */
12334    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12335        ProcessRecord r = findAppProcess(app, "Crash");
12336        final String processName = app == null ? "system_server"
12337                : (r == null ? "unknown" : r.processName);
12338
12339        handleApplicationCrashInner("crash", r, processName, crashInfo);
12340    }
12341
12342    /* Native crash reporting uses this inner version because it needs to be somewhat
12343     * decoupled from the AM-managed cleanup lifecycle
12344     */
12345    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12346            ApplicationErrorReport.CrashInfo crashInfo) {
12347        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12348                UserHandle.getUserId(Binder.getCallingUid()), processName,
12349                r == null ? -1 : r.info.flags,
12350                crashInfo.exceptionClassName,
12351                crashInfo.exceptionMessage,
12352                crashInfo.throwFileName,
12353                crashInfo.throwLineNumber);
12354
12355        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12356
12357        crashApplication(r, crashInfo);
12358    }
12359
12360    public void handleApplicationStrictModeViolation(
12361            IBinder app,
12362            int violationMask,
12363            StrictMode.ViolationInfo info) {
12364        ProcessRecord r = findAppProcess(app, "StrictMode");
12365        if (r == null) {
12366            return;
12367        }
12368
12369        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12370            Integer stackFingerprint = info.hashCode();
12371            boolean logIt = true;
12372            synchronized (mAlreadyLoggedViolatedStacks) {
12373                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12374                    logIt = false;
12375                    // TODO: sub-sample into EventLog for these, with
12376                    // the info.durationMillis?  Then we'd get
12377                    // the relative pain numbers, without logging all
12378                    // the stack traces repeatedly.  We'd want to do
12379                    // likewise in the client code, which also does
12380                    // dup suppression, before the Binder call.
12381                } else {
12382                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12383                        mAlreadyLoggedViolatedStacks.clear();
12384                    }
12385                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12386                }
12387            }
12388            if (logIt) {
12389                logStrictModeViolationToDropBox(r, info);
12390            }
12391        }
12392
12393        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12394            AppErrorResult result = new AppErrorResult();
12395            synchronized (this) {
12396                final long origId = Binder.clearCallingIdentity();
12397
12398                Message msg = Message.obtain();
12399                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12400                HashMap<String, Object> data = new HashMap<String, Object>();
12401                data.put("result", result);
12402                data.put("app", r);
12403                data.put("violationMask", violationMask);
12404                data.put("info", info);
12405                msg.obj = data;
12406                mUiHandler.sendMessage(msg);
12407
12408                Binder.restoreCallingIdentity(origId);
12409            }
12410            int res = result.get();
12411            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12412        }
12413    }
12414
12415    // Depending on the policy in effect, there could be a bunch of
12416    // these in quick succession so we try to batch these together to
12417    // minimize disk writes, number of dropbox entries, and maximize
12418    // compression, by having more fewer, larger records.
12419    private void logStrictModeViolationToDropBox(
12420            ProcessRecord process,
12421            StrictMode.ViolationInfo info) {
12422        if (info == null) {
12423            return;
12424        }
12425        final boolean isSystemApp = process == null ||
12426                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12427                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12428        final String processName = process == null ? "unknown" : process.processName;
12429        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12430        final DropBoxManager dbox = (DropBoxManager)
12431                mContext.getSystemService(Context.DROPBOX_SERVICE);
12432
12433        // Exit early if the dropbox isn't configured to accept this report type.
12434        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12435
12436        boolean bufferWasEmpty;
12437        boolean needsFlush;
12438        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12439        synchronized (sb) {
12440            bufferWasEmpty = sb.length() == 0;
12441            appendDropBoxProcessHeaders(process, processName, sb);
12442            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12443            sb.append("System-App: ").append(isSystemApp).append("\n");
12444            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12445            if (info.violationNumThisLoop != 0) {
12446                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12447            }
12448            if (info.numAnimationsRunning != 0) {
12449                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12450            }
12451            if (info.broadcastIntentAction != null) {
12452                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12453            }
12454            if (info.durationMillis != -1) {
12455                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12456            }
12457            if (info.numInstances != -1) {
12458                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12459            }
12460            if (info.tags != null) {
12461                for (String tag : info.tags) {
12462                    sb.append("Span-Tag: ").append(tag).append("\n");
12463                }
12464            }
12465            sb.append("\n");
12466            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12467                sb.append(info.crashInfo.stackTrace);
12468                sb.append("\n");
12469            }
12470            if (info.message != null) {
12471                sb.append(info.message);
12472                sb.append("\n");
12473            }
12474
12475            // Only buffer up to ~64k.  Various logging bits truncate
12476            // things at 128k.
12477            needsFlush = (sb.length() > 64 * 1024);
12478        }
12479
12480        // Flush immediately if the buffer's grown too large, or this
12481        // is a non-system app.  Non-system apps are isolated with a
12482        // different tag & policy and not batched.
12483        //
12484        // Batching is useful during internal testing with
12485        // StrictMode settings turned up high.  Without batching,
12486        // thousands of separate files could be created on boot.
12487        if (!isSystemApp || needsFlush) {
12488            new Thread("Error dump: " + dropboxTag) {
12489                @Override
12490                public void run() {
12491                    String report;
12492                    synchronized (sb) {
12493                        report = sb.toString();
12494                        sb.delete(0, sb.length());
12495                        sb.trimToSize();
12496                    }
12497                    if (report.length() != 0) {
12498                        dbox.addText(dropboxTag, report);
12499                    }
12500                }
12501            }.start();
12502            return;
12503        }
12504
12505        // System app batching:
12506        if (!bufferWasEmpty) {
12507            // An existing dropbox-writing thread is outstanding, so
12508            // we don't need to start it up.  The existing thread will
12509            // catch the buffer appends we just did.
12510            return;
12511        }
12512
12513        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12514        // (After this point, we shouldn't access AMS internal data structures.)
12515        new Thread("Error dump: " + dropboxTag) {
12516            @Override
12517            public void run() {
12518                // 5 second sleep to let stacks arrive and be batched together
12519                try {
12520                    Thread.sleep(5000);  // 5 seconds
12521                } catch (InterruptedException e) {}
12522
12523                String errorReport;
12524                synchronized (mStrictModeBuffer) {
12525                    errorReport = mStrictModeBuffer.toString();
12526                    if (errorReport.length() == 0) {
12527                        return;
12528                    }
12529                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12530                    mStrictModeBuffer.trimToSize();
12531                }
12532                dbox.addText(dropboxTag, errorReport);
12533            }
12534        }.start();
12535    }
12536
12537    /**
12538     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12539     * @param app object of the crashing app, null for the system server
12540     * @param tag reported by the caller
12541     * @param system whether this wtf is coming from the system
12542     * @param crashInfo describing the context of the error
12543     * @return true if the process should exit immediately (WTF is fatal)
12544     */
12545    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12546            final ApplicationErrorReport.CrashInfo crashInfo) {
12547        final int callingUid = Binder.getCallingUid();
12548        final int callingPid = Binder.getCallingPid();
12549
12550        if (system) {
12551            // If this is coming from the system, we could very well have low-level
12552            // system locks held, so we want to do this all asynchronously.  And we
12553            // never want this to become fatal, so there is that too.
12554            mHandler.post(new Runnable() {
12555                @Override public void run() {
12556                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12557                }
12558            });
12559            return false;
12560        }
12561
12562        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12563                crashInfo);
12564
12565        if (r != null && r.pid != Process.myPid() &&
12566                Settings.Global.getInt(mContext.getContentResolver(),
12567                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12568            crashApplication(r, crashInfo);
12569            return true;
12570        } else {
12571            return false;
12572        }
12573    }
12574
12575    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12576            final ApplicationErrorReport.CrashInfo crashInfo) {
12577        final ProcessRecord r = findAppProcess(app, "WTF");
12578        final String processName = app == null ? "system_server"
12579                : (r == null ? "unknown" : r.processName);
12580
12581        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12582                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12583
12584        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12585
12586        return r;
12587    }
12588
12589    /**
12590     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12591     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12592     */
12593    private ProcessRecord findAppProcess(IBinder app, String reason) {
12594        if (app == null) {
12595            return null;
12596        }
12597
12598        synchronized (this) {
12599            final int NP = mProcessNames.getMap().size();
12600            for (int ip=0; ip<NP; ip++) {
12601                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12602                final int NA = apps.size();
12603                for (int ia=0; ia<NA; ia++) {
12604                    ProcessRecord p = apps.valueAt(ia);
12605                    if (p.thread != null && p.thread.asBinder() == app) {
12606                        return p;
12607                    }
12608                }
12609            }
12610
12611            Slog.w(TAG, "Can't find mystery application for " + reason
12612                    + " from pid=" + Binder.getCallingPid()
12613                    + " uid=" + Binder.getCallingUid() + ": " + app);
12614            return null;
12615        }
12616    }
12617
12618    /**
12619     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12620     * to append various headers to the dropbox log text.
12621     */
12622    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12623            StringBuilder sb) {
12624        // Watchdog thread ends up invoking this function (with
12625        // a null ProcessRecord) to add the stack file to dropbox.
12626        // Do not acquire a lock on this (am) in such cases, as it
12627        // could cause a potential deadlock, if and when watchdog
12628        // is invoked due to unavailability of lock on am and it
12629        // would prevent watchdog from killing system_server.
12630        if (process == null) {
12631            sb.append("Process: ").append(processName).append("\n");
12632            return;
12633        }
12634        // Note: ProcessRecord 'process' is guarded by the service
12635        // instance.  (notably process.pkgList, which could otherwise change
12636        // concurrently during execution of this method)
12637        synchronized (this) {
12638            sb.append("Process: ").append(processName).append("\n");
12639            int flags = process.info.flags;
12640            IPackageManager pm = AppGlobals.getPackageManager();
12641            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12642            for (int ip=0; ip<process.pkgList.size(); ip++) {
12643                String pkg = process.pkgList.keyAt(ip);
12644                sb.append("Package: ").append(pkg);
12645                try {
12646                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12647                    if (pi != null) {
12648                        sb.append(" v").append(pi.versionCode);
12649                        if (pi.versionName != null) {
12650                            sb.append(" (").append(pi.versionName).append(")");
12651                        }
12652                    }
12653                } catch (RemoteException e) {
12654                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12655                }
12656                sb.append("\n");
12657            }
12658        }
12659    }
12660
12661    private static String processClass(ProcessRecord process) {
12662        if (process == null || process.pid == MY_PID) {
12663            return "system_server";
12664        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12665            return "system_app";
12666        } else {
12667            return "data_app";
12668        }
12669    }
12670
12671    /**
12672     * Write a description of an error (crash, WTF, ANR) to the drop box.
12673     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12674     * @param process which caused the error, null means the system server
12675     * @param activity which triggered the error, null if unknown
12676     * @param parent activity related to the error, null if unknown
12677     * @param subject line related to the error, null if absent
12678     * @param report in long form describing the error, null if absent
12679     * @param logFile to include in the report, null if none
12680     * @param crashInfo giving an application stack trace, null if absent
12681     */
12682    public void addErrorToDropBox(String eventType,
12683            ProcessRecord process, String processName, ActivityRecord activity,
12684            ActivityRecord parent, String subject,
12685            final String report, final File logFile,
12686            final ApplicationErrorReport.CrashInfo crashInfo) {
12687        // NOTE -- this must never acquire the ActivityManagerService lock,
12688        // otherwise the watchdog may be prevented from resetting the system.
12689
12690        final String dropboxTag = processClass(process) + "_" + eventType;
12691        final DropBoxManager dbox = (DropBoxManager)
12692                mContext.getSystemService(Context.DROPBOX_SERVICE);
12693
12694        // Exit early if the dropbox isn't configured to accept this report type.
12695        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12696
12697        final StringBuilder sb = new StringBuilder(1024);
12698        appendDropBoxProcessHeaders(process, processName, sb);
12699        if (activity != null) {
12700            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12701        }
12702        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12703            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12704        }
12705        if (parent != null && parent != activity) {
12706            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12707        }
12708        if (subject != null) {
12709            sb.append("Subject: ").append(subject).append("\n");
12710        }
12711        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12712        if (Debug.isDebuggerConnected()) {
12713            sb.append("Debugger: Connected\n");
12714        }
12715        sb.append("\n");
12716
12717        // Do the rest in a worker thread to avoid blocking the caller on I/O
12718        // (After this point, we shouldn't access AMS internal data structures.)
12719        Thread worker = new Thread("Error dump: " + dropboxTag) {
12720            @Override
12721            public void run() {
12722                if (report != null) {
12723                    sb.append(report);
12724                }
12725                if (logFile != null) {
12726                    try {
12727                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12728                                    "\n\n[[TRUNCATED]]"));
12729                    } catch (IOException e) {
12730                        Slog.e(TAG, "Error reading " + logFile, e);
12731                    }
12732                }
12733                if (crashInfo != null && crashInfo.stackTrace != null) {
12734                    sb.append(crashInfo.stackTrace);
12735                }
12736
12737                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12738                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12739                if (lines > 0) {
12740                    sb.append("\n");
12741
12742                    // Merge several logcat streams, and take the last N lines
12743                    InputStreamReader input = null;
12744                    try {
12745                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12746                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12747                                "-b", "crash",
12748                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12749
12750                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12751                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12752                        input = new InputStreamReader(logcat.getInputStream());
12753
12754                        int num;
12755                        char[] buf = new char[8192];
12756                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12757                    } catch (IOException e) {
12758                        Slog.e(TAG, "Error running logcat", e);
12759                    } finally {
12760                        if (input != null) try { input.close(); } catch (IOException e) {}
12761                    }
12762                }
12763
12764                dbox.addText(dropboxTag, sb.toString());
12765            }
12766        };
12767
12768        if (process == null) {
12769            // If process is null, we are being called from some internal code
12770            // and may be about to die -- run this synchronously.
12771            worker.run();
12772        } else {
12773            worker.start();
12774        }
12775    }
12776
12777    /**
12778     * Bring up the "unexpected error" dialog box for a crashing app.
12779     * Deal with edge cases (intercepts from instrumented applications,
12780     * ActivityController, error intent receivers, that sort of thing).
12781     * @param r the application crashing
12782     * @param crashInfo describing the failure
12783     */
12784    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12785        long timeMillis = System.currentTimeMillis();
12786        String shortMsg = crashInfo.exceptionClassName;
12787        String longMsg = crashInfo.exceptionMessage;
12788        String stackTrace = crashInfo.stackTrace;
12789        if (shortMsg != null && longMsg != null) {
12790            longMsg = shortMsg + ": " + longMsg;
12791        } else if (shortMsg != null) {
12792            longMsg = shortMsg;
12793        }
12794
12795        AppErrorResult result = new AppErrorResult();
12796        synchronized (this) {
12797            if (mController != null) {
12798                try {
12799                    String name = r != null ? r.processName : null;
12800                    int pid = r != null ? r.pid : Binder.getCallingPid();
12801                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12802                    if (!mController.appCrashed(name, pid,
12803                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12804                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12805                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12806                            Slog.w(TAG, "Skip killing native crashed app " + name
12807                                    + "(" + pid + ") during testing");
12808                        } else {
12809                            Slog.w(TAG, "Force-killing crashed app " + name
12810                                    + " at watcher's request");
12811                            if (r != null) {
12812                                r.kill("crash", true);
12813                            } else {
12814                                // Huh.
12815                                Process.killProcess(pid);
12816                                killProcessGroup(uid, pid);
12817                            }
12818                        }
12819                        return;
12820                    }
12821                } catch (RemoteException e) {
12822                    mController = null;
12823                    Watchdog.getInstance().setActivityController(null);
12824                }
12825            }
12826
12827            final long origId = Binder.clearCallingIdentity();
12828
12829            // If this process is running instrumentation, finish it.
12830            if (r != null && r.instrumentationClass != null) {
12831                Slog.w(TAG, "Error in app " + r.processName
12832                      + " running instrumentation " + r.instrumentationClass + ":");
12833                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12834                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12835                Bundle info = new Bundle();
12836                info.putString("shortMsg", shortMsg);
12837                info.putString("longMsg", longMsg);
12838                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12839                Binder.restoreCallingIdentity(origId);
12840                return;
12841            }
12842
12843            // Log crash in battery stats.
12844            if (r != null) {
12845                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12846            }
12847
12848            // If we can't identify the process or it's already exceeded its crash quota,
12849            // quit right away without showing a crash dialog.
12850            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12851                Binder.restoreCallingIdentity(origId);
12852                return;
12853            }
12854
12855            Message msg = Message.obtain();
12856            msg.what = SHOW_ERROR_MSG;
12857            HashMap data = new HashMap();
12858            data.put("result", result);
12859            data.put("app", r);
12860            msg.obj = data;
12861            mUiHandler.sendMessage(msg);
12862
12863            Binder.restoreCallingIdentity(origId);
12864        }
12865
12866        int res = result.get();
12867
12868        Intent appErrorIntent = null;
12869        synchronized (this) {
12870            if (r != null && !r.isolated) {
12871                // XXX Can't keep track of crash time for isolated processes,
12872                // since they don't have a persistent identity.
12873                mProcessCrashTimes.put(r.info.processName, r.uid,
12874                        SystemClock.uptimeMillis());
12875            }
12876            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12877                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12878            }
12879        }
12880
12881        if (appErrorIntent != null) {
12882            try {
12883                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12884            } catch (ActivityNotFoundException e) {
12885                Slog.w(TAG, "bug report receiver dissappeared", e);
12886            }
12887        }
12888    }
12889
12890    Intent createAppErrorIntentLocked(ProcessRecord r,
12891            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12892        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12893        if (report == null) {
12894            return null;
12895        }
12896        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12897        result.setComponent(r.errorReportReceiver);
12898        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12899        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12900        return result;
12901    }
12902
12903    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12904            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12905        if (r.errorReportReceiver == null) {
12906            return null;
12907        }
12908
12909        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12910            return null;
12911        }
12912
12913        ApplicationErrorReport report = new ApplicationErrorReport();
12914        report.packageName = r.info.packageName;
12915        report.installerPackageName = r.errorReportReceiver.getPackageName();
12916        report.processName = r.processName;
12917        report.time = timeMillis;
12918        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12919
12920        if (r.crashing || r.forceCrashReport) {
12921            report.type = ApplicationErrorReport.TYPE_CRASH;
12922            report.crashInfo = crashInfo;
12923        } else if (r.notResponding) {
12924            report.type = ApplicationErrorReport.TYPE_ANR;
12925            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12926
12927            report.anrInfo.activity = r.notRespondingReport.tag;
12928            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12929            report.anrInfo.info = r.notRespondingReport.longMsg;
12930        }
12931
12932        return report;
12933    }
12934
12935    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12936        enforceNotIsolatedCaller("getProcessesInErrorState");
12937        // assume our apps are happy - lazy create the list
12938        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12939
12940        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12941                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12942        int userId = UserHandle.getUserId(Binder.getCallingUid());
12943
12944        synchronized (this) {
12945
12946            // iterate across all processes
12947            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12948                ProcessRecord app = mLruProcesses.get(i);
12949                if (!allUsers && app.userId != userId) {
12950                    continue;
12951                }
12952                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12953                    // This one's in trouble, so we'll generate a report for it
12954                    // crashes are higher priority (in case there's a crash *and* an anr)
12955                    ActivityManager.ProcessErrorStateInfo report = null;
12956                    if (app.crashing) {
12957                        report = app.crashingReport;
12958                    } else if (app.notResponding) {
12959                        report = app.notRespondingReport;
12960                    }
12961
12962                    if (report != null) {
12963                        if (errList == null) {
12964                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12965                        }
12966                        errList.add(report);
12967                    } else {
12968                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12969                                " crashing = " + app.crashing +
12970                                " notResponding = " + app.notResponding);
12971                    }
12972                }
12973            }
12974        }
12975
12976        return errList;
12977    }
12978
12979    static int procStateToImportance(int procState, int memAdj,
12980            ActivityManager.RunningAppProcessInfo currApp) {
12981        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12982        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12983            currApp.lru = memAdj;
12984        } else {
12985            currApp.lru = 0;
12986        }
12987        return imp;
12988    }
12989
12990    private void fillInProcMemInfo(ProcessRecord app,
12991            ActivityManager.RunningAppProcessInfo outInfo) {
12992        outInfo.pid = app.pid;
12993        outInfo.uid = app.info.uid;
12994        if (mHeavyWeightProcess == app) {
12995            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12996        }
12997        if (app.persistent) {
12998            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12999        }
13000        if (app.activities.size() > 0) {
13001            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13002        }
13003        outInfo.lastTrimLevel = app.trimMemoryLevel;
13004        int adj = app.curAdj;
13005        int procState = app.curProcState;
13006        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13007        outInfo.importanceReasonCode = app.adjTypeCode;
13008        outInfo.processState = app.curProcState;
13009    }
13010
13011    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13012        enforceNotIsolatedCaller("getRunningAppProcesses");
13013
13014        final int callingUid = Binder.getCallingUid();
13015
13016        // Lazy instantiation of list
13017        List<ActivityManager.RunningAppProcessInfo> runList = null;
13018        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13019                callingUid) == PackageManager.PERMISSION_GRANTED;
13020        final int userId = UserHandle.getUserId(callingUid);
13021        final boolean allUids = isGetTasksAllowed(
13022                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13023
13024        synchronized (this) {
13025            // Iterate across all processes
13026            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13027                ProcessRecord app = mLruProcesses.get(i);
13028                if ((!allUsers && app.userId != userId)
13029                        || (!allUids && app.uid != callingUid)) {
13030                    continue;
13031                }
13032                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13033                    // Generate process state info for running application
13034                    ActivityManager.RunningAppProcessInfo currApp =
13035                        new ActivityManager.RunningAppProcessInfo(app.processName,
13036                                app.pid, app.getPackageList());
13037                    fillInProcMemInfo(app, currApp);
13038                    if (app.adjSource instanceof ProcessRecord) {
13039                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13040                        currApp.importanceReasonImportance =
13041                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13042                                        app.adjSourceProcState);
13043                    } else if (app.adjSource instanceof ActivityRecord) {
13044                        ActivityRecord r = (ActivityRecord)app.adjSource;
13045                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13046                    }
13047                    if (app.adjTarget instanceof ComponentName) {
13048                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13049                    }
13050                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13051                    //        + " lru=" + currApp.lru);
13052                    if (runList == null) {
13053                        runList = new ArrayList<>();
13054                    }
13055                    runList.add(currApp);
13056                }
13057            }
13058        }
13059        return runList;
13060    }
13061
13062    public List<ApplicationInfo> getRunningExternalApplications() {
13063        enforceNotIsolatedCaller("getRunningExternalApplications");
13064        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13065        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13066        if (runningApps != null && runningApps.size() > 0) {
13067            Set<String> extList = new HashSet<String>();
13068            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13069                if (app.pkgList != null) {
13070                    for (String pkg : app.pkgList) {
13071                        extList.add(pkg);
13072                    }
13073                }
13074            }
13075            IPackageManager pm = AppGlobals.getPackageManager();
13076            for (String pkg : extList) {
13077                try {
13078                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13079                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13080                        retList.add(info);
13081                    }
13082                } catch (RemoteException e) {
13083                }
13084            }
13085        }
13086        return retList;
13087    }
13088
13089    @Override
13090    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13091        enforceNotIsolatedCaller("getMyMemoryState");
13092        synchronized (this) {
13093            ProcessRecord proc;
13094            synchronized (mPidsSelfLocked) {
13095                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13096            }
13097            fillInProcMemInfo(proc, outInfo);
13098        }
13099    }
13100
13101    @Override
13102    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13103            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13104        (new ActivityManagerShellCommand(this, false)).exec(
13105                this, in, out, err, args, resultReceiver);
13106    }
13107
13108    @Override
13109    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13110        if (checkCallingPermission(android.Manifest.permission.DUMP)
13111                != PackageManager.PERMISSION_GRANTED) {
13112            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13113                    + Binder.getCallingPid()
13114                    + ", uid=" + Binder.getCallingUid()
13115                    + " without permission "
13116                    + android.Manifest.permission.DUMP);
13117            return;
13118        }
13119
13120        boolean dumpAll = false;
13121        boolean dumpClient = false;
13122        String dumpPackage = null;
13123
13124        int opti = 0;
13125        while (opti < args.length) {
13126            String opt = args[opti];
13127            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13128                break;
13129            }
13130            opti++;
13131            if ("-a".equals(opt)) {
13132                dumpAll = true;
13133            } else if ("-c".equals(opt)) {
13134                dumpClient = true;
13135            } else if ("-p".equals(opt)) {
13136                if (opti < args.length) {
13137                    dumpPackage = args[opti];
13138                    opti++;
13139                } else {
13140                    pw.println("Error: -p option requires package argument");
13141                    return;
13142                }
13143                dumpClient = true;
13144            } else if ("-h".equals(opt)) {
13145                ActivityManagerShellCommand.dumpHelp(pw, true);
13146                return;
13147            } else {
13148                pw.println("Unknown argument: " + opt + "; use -h for help");
13149            }
13150        }
13151
13152        long origId = Binder.clearCallingIdentity();
13153        boolean more = false;
13154        // Is the caller requesting to dump a particular piece of data?
13155        if (opti < args.length) {
13156            String cmd = args[opti];
13157            opti++;
13158            if ("activities".equals(cmd) || "a".equals(cmd)) {
13159                synchronized (this) {
13160                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13161                }
13162            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13163                synchronized (this) {
13164                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13165                }
13166            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13167                String[] newArgs;
13168                String name;
13169                if (opti >= args.length) {
13170                    name = null;
13171                    newArgs = EMPTY_STRING_ARRAY;
13172                } else {
13173                    dumpPackage = args[opti];
13174                    opti++;
13175                    newArgs = new String[args.length - opti];
13176                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13177                            args.length - opti);
13178                }
13179                synchronized (this) {
13180                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13181                }
13182            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13183                String[] newArgs;
13184                String name;
13185                if (opti >= args.length) {
13186                    name = null;
13187                    newArgs = EMPTY_STRING_ARRAY;
13188                } else {
13189                    dumpPackage = args[opti];
13190                    opti++;
13191                    newArgs = new String[args.length - opti];
13192                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13193                            args.length - opti);
13194                }
13195                synchronized (this) {
13196                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13197                }
13198            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13199                String[] newArgs;
13200                String name;
13201                if (opti >= args.length) {
13202                    name = null;
13203                    newArgs = EMPTY_STRING_ARRAY;
13204                } else {
13205                    dumpPackage = args[opti];
13206                    opti++;
13207                    newArgs = new String[args.length - opti];
13208                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13209                            args.length - opti);
13210                }
13211                synchronized (this) {
13212                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13213                }
13214            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13215                synchronized (this) {
13216                    dumpOomLocked(fd, pw, args, opti, true);
13217                }
13218            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13219                synchronized (this) {
13220                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13221                }
13222            } else if ("provider".equals(cmd)) {
13223                String[] newArgs;
13224                String name;
13225                if (opti >= args.length) {
13226                    name = null;
13227                    newArgs = EMPTY_STRING_ARRAY;
13228                } else {
13229                    name = args[opti];
13230                    opti++;
13231                    newArgs = new String[args.length - opti];
13232                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13233                }
13234                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13235                    pw.println("No providers match: " + name);
13236                    pw.println("Use -h for help.");
13237                }
13238            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13239                synchronized (this) {
13240                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13241                }
13242            } else if ("service".equals(cmd)) {
13243                String[] newArgs;
13244                String name;
13245                if (opti >= args.length) {
13246                    name = null;
13247                    newArgs = EMPTY_STRING_ARRAY;
13248                } else {
13249                    name = args[opti];
13250                    opti++;
13251                    newArgs = new String[args.length - opti];
13252                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13253                            args.length - opti);
13254                }
13255                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13256                    pw.println("No services match: " + name);
13257                    pw.println("Use -h for help.");
13258                }
13259            } else if ("package".equals(cmd)) {
13260                String[] newArgs;
13261                if (opti >= args.length) {
13262                    pw.println("package: no package name specified");
13263                    pw.println("Use -h for help.");
13264                } else {
13265                    dumpPackage = args[opti];
13266                    opti++;
13267                    newArgs = new String[args.length - opti];
13268                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13269                            args.length - opti);
13270                    args = newArgs;
13271                    opti = 0;
13272                    more = true;
13273                }
13274            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13275                synchronized (this) {
13276                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13277                }
13278            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13279                synchronized (this) {
13280                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13281                }
13282            } else {
13283                // Dumping a single activity?
13284                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13285                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13286                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13287                    if (res < 0) {
13288                        pw.println("Bad activity command, or no activities match: " + cmd);
13289                        pw.println("Use -h for help.");
13290                    }
13291                }
13292            }
13293            if (!more) {
13294                Binder.restoreCallingIdentity(origId);
13295                return;
13296            }
13297        }
13298
13299        // No piece of data specified, dump everything.
13300        synchronized (this) {
13301            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13302            pw.println();
13303            if (dumpAll) {
13304                pw.println("-------------------------------------------------------------------------------");
13305            }
13306            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13307            pw.println();
13308            if (dumpAll) {
13309                pw.println("-------------------------------------------------------------------------------");
13310            }
13311            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13312            pw.println();
13313            if (dumpAll) {
13314                pw.println("-------------------------------------------------------------------------------");
13315            }
13316            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13317            pw.println();
13318            if (dumpAll) {
13319                pw.println("-------------------------------------------------------------------------------");
13320            }
13321            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13322            pw.println();
13323            if (dumpAll) {
13324                pw.println("-------------------------------------------------------------------------------");
13325            }
13326            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13327            pw.println();
13328            if (dumpAll) {
13329                pw.println("-------------------------------------------------------------------------------");
13330            }
13331            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13332            if (mAssociations.size() > 0) {
13333                pw.println();
13334                if (dumpAll) {
13335                    pw.println("-------------------------------------------------------------------------------");
13336                }
13337                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13338            }
13339            pw.println();
13340            if (dumpAll) {
13341                pw.println("-------------------------------------------------------------------------------");
13342            }
13343            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13344        }
13345        Binder.restoreCallingIdentity(origId);
13346    }
13347
13348    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13349            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13350        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13351
13352        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13353                dumpPackage);
13354        boolean needSep = printedAnything;
13355
13356        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13357                dumpPackage, needSep, "  mFocusedActivity: ");
13358        if (printed) {
13359            printedAnything = true;
13360            needSep = false;
13361        }
13362
13363        if (dumpPackage == null) {
13364            if (needSep) {
13365                pw.println();
13366            }
13367            needSep = true;
13368            printedAnything = true;
13369            mStackSupervisor.dump(pw, "  ");
13370        }
13371
13372        if (!printedAnything) {
13373            pw.println("  (nothing)");
13374        }
13375    }
13376
13377    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13378            int opti, boolean dumpAll, String dumpPackage) {
13379        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13380
13381        boolean printedAnything = false;
13382
13383        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13384            boolean printedHeader = false;
13385
13386            final int N = mRecentTasks.size();
13387            for (int i=0; i<N; i++) {
13388                TaskRecord tr = mRecentTasks.get(i);
13389                if (dumpPackage != null) {
13390                    if (tr.realActivity == null ||
13391                            !dumpPackage.equals(tr.realActivity)) {
13392                        continue;
13393                    }
13394                }
13395                if (!printedHeader) {
13396                    pw.println("  Recent tasks:");
13397                    printedHeader = true;
13398                    printedAnything = true;
13399                }
13400                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13401                        pw.println(tr);
13402                if (dumpAll) {
13403                    mRecentTasks.get(i).dump(pw, "    ");
13404                }
13405            }
13406        }
13407
13408        if (!printedAnything) {
13409            pw.println("  (nothing)");
13410        }
13411    }
13412
13413    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13414            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13415        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13416
13417        int dumpUid = 0;
13418        if (dumpPackage != null) {
13419            IPackageManager pm = AppGlobals.getPackageManager();
13420            try {
13421                dumpUid = pm.getPackageUid(dumpPackage, 0);
13422            } catch (RemoteException e) {
13423            }
13424        }
13425
13426        boolean printedAnything = false;
13427
13428        final long now = SystemClock.uptimeMillis();
13429
13430        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13431            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13432                    = mAssociations.valueAt(i1);
13433            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13434                SparseArray<ArrayMap<String, Association>> sourceUids
13435                        = targetComponents.valueAt(i2);
13436                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13437                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13438                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13439                        Association ass = sourceProcesses.valueAt(i4);
13440                        if (dumpPackage != null) {
13441                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13442                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13443                                continue;
13444                            }
13445                        }
13446                        printedAnything = true;
13447                        pw.print("  ");
13448                        pw.print(ass.mTargetProcess);
13449                        pw.print("/");
13450                        UserHandle.formatUid(pw, ass.mTargetUid);
13451                        pw.print(" <- ");
13452                        pw.print(ass.mSourceProcess);
13453                        pw.print("/");
13454                        UserHandle.formatUid(pw, ass.mSourceUid);
13455                        pw.println();
13456                        pw.print("    via ");
13457                        pw.print(ass.mTargetComponent.flattenToShortString());
13458                        pw.println();
13459                        pw.print("    ");
13460                        long dur = ass.mTime;
13461                        if (ass.mNesting > 0) {
13462                            dur += now - ass.mStartTime;
13463                        }
13464                        TimeUtils.formatDuration(dur, pw);
13465                        pw.print(" (");
13466                        pw.print(ass.mCount);
13467                        pw.println(" times)");
13468                        if (ass.mNesting > 0) {
13469                            pw.print("    ");
13470                            pw.print(" Currently active: ");
13471                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13472                            pw.println();
13473                        }
13474                    }
13475                }
13476            }
13477
13478        }
13479
13480        if (!printedAnything) {
13481            pw.println("  (nothing)");
13482        }
13483    }
13484
13485    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13486            int opti, boolean dumpAll, String dumpPackage) {
13487        boolean needSep = false;
13488        boolean printedAnything = false;
13489        int numPers = 0;
13490
13491        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13492
13493        if (dumpAll) {
13494            final int NP = mProcessNames.getMap().size();
13495            for (int ip=0; ip<NP; ip++) {
13496                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13497                final int NA = procs.size();
13498                for (int ia=0; ia<NA; ia++) {
13499                    ProcessRecord r = procs.valueAt(ia);
13500                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13501                        continue;
13502                    }
13503                    if (!needSep) {
13504                        pw.println("  All known processes:");
13505                        needSep = true;
13506                        printedAnything = true;
13507                    }
13508                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13509                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13510                        pw.print(" "); pw.println(r);
13511                    r.dump(pw, "    ");
13512                    if (r.persistent) {
13513                        numPers++;
13514                    }
13515                }
13516            }
13517        }
13518
13519        if (mIsolatedProcesses.size() > 0) {
13520            boolean printed = false;
13521            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13522                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13523                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13524                    continue;
13525                }
13526                if (!printed) {
13527                    if (needSep) {
13528                        pw.println();
13529                    }
13530                    pw.println("  Isolated process list (sorted by uid):");
13531                    printedAnything = true;
13532                    printed = true;
13533                    needSep = true;
13534                }
13535                pw.println(String.format("%sIsolated #%2d: %s",
13536                        "    ", i, r.toString()));
13537            }
13538        }
13539
13540        if (mActiveUids.size() > 0) {
13541            boolean printed = false;
13542            int whichAppId = -1;
13543            if (dumpPackage != null) {
13544                try {
13545                    ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13546                            dumpPackage, 0);
13547                    whichAppId = UserHandle.getAppId(info.uid);
13548                } catch (NameNotFoundException e) {
13549                    e.printStackTrace();
13550                }
13551            }
13552            for (int i=0; i<mActiveUids.size(); i++) {
13553                UidRecord uidRec = mActiveUids.valueAt(i);
13554                if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13555                    continue;
13556                }
13557                if (!printed) {
13558                    printed = true;
13559                    if (needSep) {
13560                        pw.println();
13561                    }
13562                    pw.println("  UID states:");
13563                    needSep = true;
13564                    printedAnything = true;
13565                }
13566                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13567                pw.print(": "); pw.println(uidRec);
13568            }
13569        }
13570
13571        if (mLruProcesses.size() > 0) {
13572            if (needSep) {
13573                pw.println();
13574            }
13575            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13576                    pw.print(" total, non-act at ");
13577                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13578                    pw.print(", non-svc at ");
13579                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13580                    pw.println("):");
13581            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13582            needSep = true;
13583            printedAnything = true;
13584        }
13585
13586        if (dumpAll || dumpPackage != null) {
13587            synchronized (mPidsSelfLocked) {
13588                boolean printed = false;
13589                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13590                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13591                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13592                        continue;
13593                    }
13594                    if (!printed) {
13595                        if (needSep) pw.println();
13596                        needSep = true;
13597                        pw.println("  PID mappings:");
13598                        printed = true;
13599                        printedAnything = true;
13600                    }
13601                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13602                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13603                }
13604            }
13605        }
13606
13607        if (mForegroundProcesses.size() > 0) {
13608            synchronized (mPidsSelfLocked) {
13609                boolean printed = false;
13610                for (int i=0; i<mForegroundProcesses.size(); i++) {
13611                    ProcessRecord r = mPidsSelfLocked.get(
13612                            mForegroundProcesses.valueAt(i).pid);
13613                    if (dumpPackage != null && (r == null
13614                            || !r.pkgList.containsKey(dumpPackage))) {
13615                        continue;
13616                    }
13617                    if (!printed) {
13618                        if (needSep) pw.println();
13619                        needSep = true;
13620                        pw.println("  Foreground Processes:");
13621                        printed = true;
13622                        printedAnything = true;
13623                    }
13624                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13625                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13626                }
13627            }
13628        }
13629
13630        if (mPersistentStartingProcesses.size() > 0) {
13631            if (needSep) pw.println();
13632            needSep = true;
13633            printedAnything = true;
13634            pw.println("  Persisent processes that are starting:");
13635            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13636                    "Starting Norm", "Restarting PERS", dumpPackage);
13637        }
13638
13639        if (mRemovedProcesses.size() > 0) {
13640            if (needSep) pw.println();
13641            needSep = true;
13642            printedAnything = true;
13643            pw.println("  Processes that are being removed:");
13644            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13645                    "Removed Norm", "Removed PERS", dumpPackage);
13646        }
13647
13648        if (mProcessesOnHold.size() > 0) {
13649            if (needSep) pw.println();
13650            needSep = true;
13651            printedAnything = true;
13652            pw.println("  Processes that are on old until the system is ready:");
13653            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13654                    "OnHold Norm", "OnHold PERS", dumpPackage);
13655        }
13656
13657        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13658
13659        if (mProcessCrashTimes.getMap().size() > 0) {
13660            boolean printed = false;
13661            long now = SystemClock.uptimeMillis();
13662            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13663            final int NP = pmap.size();
13664            for (int ip=0; ip<NP; ip++) {
13665                String pname = pmap.keyAt(ip);
13666                SparseArray<Long> uids = pmap.valueAt(ip);
13667                final int N = uids.size();
13668                for (int i=0; i<N; i++) {
13669                    int puid = uids.keyAt(i);
13670                    ProcessRecord r = mProcessNames.get(pname, puid);
13671                    if (dumpPackage != null && (r == null
13672                            || !r.pkgList.containsKey(dumpPackage))) {
13673                        continue;
13674                    }
13675                    if (!printed) {
13676                        if (needSep) pw.println();
13677                        needSep = true;
13678                        pw.println("  Time since processes crashed:");
13679                        printed = true;
13680                        printedAnything = true;
13681                    }
13682                    pw.print("    Process "); pw.print(pname);
13683                            pw.print(" uid "); pw.print(puid);
13684                            pw.print(": last crashed ");
13685                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13686                            pw.println(" ago");
13687                }
13688            }
13689        }
13690
13691        if (mBadProcesses.getMap().size() > 0) {
13692            boolean printed = false;
13693            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13694            final int NP = pmap.size();
13695            for (int ip=0; ip<NP; ip++) {
13696                String pname = pmap.keyAt(ip);
13697                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13698                final int N = uids.size();
13699                for (int i=0; i<N; i++) {
13700                    int puid = uids.keyAt(i);
13701                    ProcessRecord r = mProcessNames.get(pname, puid);
13702                    if (dumpPackage != null && (r == null
13703                            || !r.pkgList.containsKey(dumpPackage))) {
13704                        continue;
13705                    }
13706                    if (!printed) {
13707                        if (needSep) pw.println();
13708                        needSep = true;
13709                        pw.println("  Bad processes:");
13710                        printedAnything = true;
13711                    }
13712                    BadProcessInfo info = uids.valueAt(i);
13713                    pw.print("    Bad process "); pw.print(pname);
13714                            pw.print(" uid "); pw.print(puid);
13715                            pw.print(": crashed at time "); pw.println(info.time);
13716                    if (info.shortMsg != null) {
13717                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13718                    }
13719                    if (info.longMsg != null) {
13720                        pw.print("      Long msg: "); pw.println(info.longMsg);
13721                    }
13722                    if (info.stack != null) {
13723                        pw.println("      Stack:");
13724                        int lastPos = 0;
13725                        for (int pos=0; pos<info.stack.length(); pos++) {
13726                            if (info.stack.charAt(pos) == '\n') {
13727                                pw.print("        ");
13728                                pw.write(info.stack, lastPos, pos-lastPos);
13729                                pw.println();
13730                                lastPos = pos+1;
13731                            }
13732                        }
13733                        if (lastPos < info.stack.length()) {
13734                            pw.print("        ");
13735                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13736                            pw.println();
13737                        }
13738                    }
13739                }
13740            }
13741        }
13742
13743        if (dumpPackage == null) {
13744            pw.println();
13745            needSep = false;
13746            mUserController.dump(pw, dumpAll);
13747        }
13748        if (mHomeProcess != null && (dumpPackage == null
13749                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13750            if (needSep) {
13751                pw.println();
13752                needSep = false;
13753            }
13754            pw.println("  mHomeProcess: " + mHomeProcess);
13755        }
13756        if (mPreviousProcess != null && (dumpPackage == null
13757                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13758            if (needSep) {
13759                pw.println();
13760                needSep = false;
13761            }
13762            pw.println("  mPreviousProcess: " + mPreviousProcess);
13763        }
13764        if (dumpAll) {
13765            StringBuilder sb = new StringBuilder(128);
13766            sb.append("  mPreviousProcessVisibleTime: ");
13767            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13768            pw.println(sb);
13769        }
13770        if (mHeavyWeightProcess != null && (dumpPackage == null
13771                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13772            if (needSep) {
13773                pw.println();
13774                needSep = false;
13775            }
13776            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13777        }
13778        if (dumpPackage == null) {
13779            pw.println("  mConfiguration: " + mConfiguration);
13780        }
13781        if (dumpAll) {
13782            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13783            if (mCompatModePackages.getPackages().size() > 0) {
13784                boolean printed = false;
13785                for (Map.Entry<String, Integer> entry
13786                        : mCompatModePackages.getPackages().entrySet()) {
13787                    String pkg = entry.getKey();
13788                    int mode = entry.getValue();
13789                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13790                        continue;
13791                    }
13792                    if (!printed) {
13793                        pw.println("  mScreenCompatPackages:");
13794                        printed = true;
13795                    }
13796                    pw.print("    "); pw.print(pkg); pw.print(": ");
13797                            pw.print(mode); pw.println();
13798                }
13799            }
13800        }
13801        if (dumpPackage == null) {
13802            pw.println("  mWakefulness="
13803                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13804            pw.println("  mSleepTokens=" + mSleepTokens);
13805            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13806                    + lockScreenShownToString());
13807            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13808            if (mRunningVoice != null) {
13809                pw.println("  mRunningVoice=" + mRunningVoice);
13810                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13811            }
13812        }
13813        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13814                || mOrigWaitForDebugger) {
13815            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13816                    || dumpPackage.equals(mOrigDebugApp)) {
13817                if (needSep) {
13818                    pw.println();
13819                    needSep = false;
13820                }
13821                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13822                        + " mDebugTransient=" + mDebugTransient
13823                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13824            }
13825        }
13826        if (mCurAppTimeTracker != null) {
13827            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13828        }
13829        if (mMemWatchProcesses.getMap().size() > 0) {
13830            pw.println("  Mem watch processes:");
13831            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13832                    = mMemWatchProcesses.getMap();
13833            for (int i=0; i<procs.size(); i++) {
13834                final String proc = procs.keyAt(i);
13835                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13836                for (int j=0; j<uids.size(); j++) {
13837                    if (needSep) {
13838                        pw.println();
13839                        needSep = false;
13840                    }
13841                    StringBuilder sb = new StringBuilder();
13842                    sb.append("    ").append(proc).append('/');
13843                    UserHandle.formatUid(sb, uids.keyAt(j));
13844                    Pair<Long, String> val = uids.valueAt(j);
13845                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13846                    if (val.second != null) {
13847                        sb.append(", report to ").append(val.second);
13848                    }
13849                    pw.println(sb.toString());
13850                }
13851            }
13852            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13853            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13854            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13855                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13856        }
13857        if (mTrackAllocationApp != null) {
13858            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13859                if (needSep) {
13860                    pw.println();
13861                    needSep = false;
13862                }
13863                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13864            }
13865        }
13866        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13867                || mProfileFd != null) {
13868            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13869                if (needSep) {
13870                    pw.println();
13871                    needSep = false;
13872                }
13873                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13874                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13875                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13876                        + mAutoStopProfiler);
13877                pw.println("  mProfileType=" + mProfileType);
13878            }
13879        }
13880        if (dumpPackage == null) {
13881            if (mAlwaysFinishActivities || mController != null) {
13882                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13883                        + " mController=" + mController);
13884            }
13885            if (dumpAll) {
13886                pw.println("  Total persistent processes: " + numPers);
13887                pw.println("  mProcessesReady=" + mProcessesReady
13888                        + " mSystemReady=" + mSystemReady
13889                        + " mBooted=" + mBooted
13890                        + " mFactoryTest=" + mFactoryTest);
13891                pw.println("  mBooting=" + mBooting
13892                        + " mCallFinishBooting=" + mCallFinishBooting
13893                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13894                pw.print("  mLastPowerCheckRealtime=");
13895                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13896                        pw.println("");
13897                pw.print("  mLastPowerCheckUptime=");
13898                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13899                        pw.println("");
13900                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13901                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13902                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13903                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13904                        + " (" + mLruProcesses.size() + " total)"
13905                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13906                        + " mNumServiceProcs=" + mNumServiceProcs
13907                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13908                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13909                        + " mLastMemoryLevel" + mLastMemoryLevel
13910                        + " mLastNumProcesses" + mLastNumProcesses);
13911                long now = SystemClock.uptimeMillis();
13912                pw.print("  mLastIdleTime=");
13913                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13914                        pw.print(" mLowRamSinceLastIdle=");
13915                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13916                        pw.println();
13917            }
13918        }
13919
13920        if (!printedAnything) {
13921            pw.println("  (nothing)");
13922        }
13923    }
13924
13925    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13926            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13927        if (mProcessesToGc.size() > 0) {
13928            boolean printed = false;
13929            long now = SystemClock.uptimeMillis();
13930            for (int i=0; i<mProcessesToGc.size(); i++) {
13931                ProcessRecord proc = mProcessesToGc.get(i);
13932                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13933                    continue;
13934                }
13935                if (!printed) {
13936                    if (needSep) pw.println();
13937                    needSep = true;
13938                    pw.println("  Processes that are waiting to GC:");
13939                    printed = true;
13940                }
13941                pw.print("    Process "); pw.println(proc);
13942                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13943                        pw.print(", last gced=");
13944                        pw.print(now-proc.lastRequestedGc);
13945                        pw.print(" ms ago, last lowMem=");
13946                        pw.print(now-proc.lastLowMemory);
13947                        pw.println(" ms ago");
13948
13949            }
13950        }
13951        return needSep;
13952    }
13953
13954    void printOomLevel(PrintWriter pw, String name, int adj) {
13955        pw.print("    ");
13956        if (adj >= 0) {
13957            pw.print(' ');
13958            if (adj < 10) pw.print(' ');
13959        } else {
13960            if (adj > -10) pw.print(' ');
13961        }
13962        pw.print(adj);
13963        pw.print(": ");
13964        pw.print(name);
13965        pw.print(" (");
13966        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
13967        pw.println(")");
13968    }
13969
13970    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13971            int opti, boolean dumpAll) {
13972        boolean needSep = false;
13973
13974        if (mLruProcesses.size() > 0) {
13975            if (needSep) pw.println();
13976            needSep = true;
13977            pw.println("  OOM levels:");
13978            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13979            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13980            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13981            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13982            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13983            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13984            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13985            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13986            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13987            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13988            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13989            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13990            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13991            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13992
13993            if (needSep) pw.println();
13994            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13995                    pw.print(" total, non-act at ");
13996                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13997                    pw.print(", non-svc at ");
13998                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13999                    pw.println("):");
14000            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14001            needSep = true;
14002        }
14003
14004        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14005
14006        pw.println();
14007        pw.println("  mHomeProcess: " + mHomeProcess);
14008        pw.println("  mPreviousProcess: " + mPreviousProcess);
14009        if (mHeavyWeightProcess != null) {
14010            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14011        }
14012
14013        return true;
14014    }
14015
14016    /**
14017     * There are three ways to call this:
14018     *  - no provider specified: dump all the providers
14019     *  - a flattened component name that matched an existing provider was specified as the
14020     *    first arg: dump that one provider
14021     *  - the first arg isn't the flattened component name of an existing provider:
14022     *    dump all providers whose component contains the first arg as a substring
14023     */
14024    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14025            int opti, boolean dumpAll) {
14026        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14027    }
14028
14029    static class ItemMatcher {
14030        ArrayList<ComponentName> components;
14031        ArrayList<String> strings;
14032        ArrayList<Integer> objects;
14033        boolean all;
14034
14035        ItemMatcher() {
14036            all = true;
14037        }
14038
14039        void build(String name) {
14040            ComponentName componentName = ComponentName.unflattenFromString(name);
14041            if (componentName != null) {
14042                if (components == null) {
14043                    components = new ArrayList<ComponentName>();
14044                }
14045                components.add(componentName);
14046                all = false;
14047            } else {
14048                int objectId = 0;
14049                // Not a '/' separated full component name; maybe an object ID?
14050                try {
14051                    objectId = Integer.parseInt(name, 16);
14052                    if (objects == null) {
14053                        objects = new ArrayList<Integer>();
14054                    }
14055                    objects.add(objectId);
14056                    all = false;
14057                } catch (RuntimeException e) {
14058                    // Not an integer; just do string match.
14059                    if (strings == null) {
14060                        strings = new ArrayList<String>();
14061                    }
14062                    strings.add(name);
14063                    all = false;
14064                }
14065            }
14066        }
14067
14068        int build(String[] args, int opti) {
14069            for (; opti<args.length; opti++) {
14070                String name = args[opti];
14071                if ("--".equals(name)) {
14072                    return opti+1;
14073                }
14074                build(name);
14075            }
14076            return opti;
14077        }
14078
14079        boolean match(Object object, ComponentName comp) {
14080            if (all) {
14081                return true;
14082            }
14083            if (components != null) {
14084                for (int i=0; i<components.size(); i++) {
14085                    if (components.get(i).equals(comp)) {
14086                        return true;
14087                    }
14088                }
14089            }
14090            if (objects != null) {
14091                for (int i=0; i<objects.size(); i++) {
14092                    if (System.identityHashCode(object) == objects.get(i)) {
14093                        return true;
14094                    }
14095                }
14096            }
14097            if (strings != null) {
14098                String flat = comp.flattenToString();
14099                for (int i=0; i<strings.size(); i++) {
14100                    if (flat.contains(strings.get(i))) {
14101                        return true;
14102                    }
14103                }
14104            }
14105            return false;
14106        }
14107    }
14108
14109    /**
14110     * There are three things that cmd can be:
14111     *  - a flattened component name that matches an existing activity
14112     *  - the cmd arg isn't the flattened component name of an existing activity:
14113     *    dump all activity whose component contains the cmd as a substring
14114     *  - A hex number of the ActivityRecord object instance.
14115     */
14116    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14117            int opti, boolean dumpAll) {
14118        ArrayList<ActivityRecord> activities;
14119
14120        synchronized (this) {
14121            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14122        }
14123
14124        if (activities.size() <= 0) {
14125            return false;
14126        }
14127
14128        String[] newArgs = new String[args.length - opti];
14129        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14130
14131        TaskRecord lastTask = null;
14132        boolean needSep = false;
14133        for (int i=activities.size()-1; i>=0; i--) {
14134            ActivityRecord r = activities.get(i);
14135            if (needSep) {
14136                pw.println();
14137            }
14138            needSep = true;
14139            synchronized (this) {
14140                if (lastTask != r.task) {
14141                    lastTask = r.task;
14142                    pw.print("TASK "); pw.print(lastTask.affinity);
14143                            pw.print(" id="); pw.println(lastTask.taskId);
14144                    if (dumpAll) {
14145                        lastTask.dump(pw, "  ");
14146                    }
14147                }
14148            }
14149            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14150        }
14151        return true;
14152    }
14153
14154    /**
14155     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14156     * there is a thread associated with the activity.
14157     */
14158    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14159            final ActivityRecord r, String[] args, boolean dumpAll) {
14160        String innerPrefix = prefix + "  ";
14161        synchronized (this) {
14162            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14163                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14164                    pw.print(" pid=");
14165                    if (r.app != null) pw.println(r.app.pid);
14166                    else pw.println("(not running)");
14167            if (dumpAll) {
14168                r.dump(pw, innerPrefix);
14169            }
14170        }
14171        if (r.app != null && r.app.thread != null) {
14172            // flush anything that is already in the PrintWriter since the thread is going
14173            // to write to the file descriptor directly
14174            pw.flush();
14175            try {
14176                TransferPipe tp = new TransferPipe();
14177                try {
14178                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14179                            r.appToken, innerPrefix, args);
14180                    tp.go(fd);
14181                } finally {
14182                    tp.kill();
14183                }
14184            } catch (IOException e) {
14185                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14186            } catch (RemoteException e) {
14187                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14188            }
14189        }
14190    }
14191
14192    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14193            int opti, boolean dumpAll, String dumpPackage) {
14194        boolean needSep = false;
14195        boolean onlyHistory = false;
14196        boolean printedAnything = false;
14197
14198        if ("history".equals(dumpPackage)) {
14199            if (opti < args.length && "-s".equals(args[opti])) {
14200                dumpAll = false;
14201            }
14202            onlyHistory = true;
14203            dumpPackage = null;
14204        }
14205
14206        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14207        if (!onlyHistory && dumpAll) {
14208            if (mRegisteredReceivers.size() > 0) {
14209                boolean printed = false;
14210                Iterator it = mRegisteredReceivers.values().iterator();
14211                while (it.hasNext()) {
14212                    ReceiverList r = (ReceiverList)it.next();
14213                    if (dumpPackage != null && (r.app == null ||
14214                            !dumpPackage.equals(r.app.info.packageName))) {
14215                        continue;
14216                    }
14217                    if (!printed) {
14218                        pw.println("  Registered Receivers:");
14219                        needSep = true;
14220                        printed = true;
14221                        printedAnything = true;
14222                    }
14223                    pw.print("  * "); pw.println(r);
14224                    r.dump(pw, "    ");
14225                }
14226            }
14227
14228            if (mReceiverResolver.dump(pw, needSep ?
14229                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14230                    "    ", dumpPackage, false, false)) {
14231                needSep = true;
14232                printedAnything = true;
14233            }
14234        }
14235
14236        for (BroadcastQueue q : mBroadcastQueues) {
14237            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14238            printedAnything |= needSep;
14239        }
14240
14241        needSep = true;
14242
14243        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14244            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14245                if (needSep) {
14246                    pw.println();
14247                }
14248                needSep = true;
14249                printedAnything = true;
14250                pw.print("  Sticky broadcasts for user ");
14251                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14252                StringBuilder sb = new StringBuilder(128);
14253                for (Map.Entry<String, ArrayList<Intent>> ent
14254                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14255                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14256                    if (dumpAll) {
14257                        pw.println(":");
14258                        ArrayList<Intent> intents = ent.getValue();
14259                        final int N = intents.size();
14260                        for (int i=0; i<N; i++) {
14261                            sb.setLength(0);
14262                            sb.append("    Intent: ");
14263                            intents.get(i).toShortString(sb, false, true, false, false);
14264                            pw.println(sb.toString());
14265                            Bundle bundle = intents.get(i).getExtras();
14266                            if (bundle != null) {
14267                                pw.print("      ");
14268                                pw.println(bundle.toString());
14269                            }
14270                        }
14271                    } else {
14272                        pw.println("");
14273                    }
14274                }
14275            }
14276        }
14277
14278        if (!onlyHistory && dumpAll) {
14279            pw.println();
14280            for (BroadcastQueue queue : mBroadcastQueues) {
14281                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14282                        + queue.mBroadcastsScheduled);
14283            }
14284            pw.println("  mHandler:");
14285            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14286            needSep = true;
14287            printedAnything = true;
14288        }
14289
14290        if (!printedAnything) {
14291            pw.println("  (nothing)");
14292        }
14293    }
14294
14295    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14296            int opti, boolean dumpAll, String dumpPackage) {
14297        boolean needSep;
14298        boolean printedAnything = false;
14299
14300        ItemMatcher matcher = new ItemMatcher();
14301        matcher.build(args, opti);
14302
14303        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14304
14305        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14306        printedAnything |= needSep;
14307
14308        if (mLaunchingProviders.size() > 0) {
14309            boolean printed = false;
14310            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14311                ContentProviderRecord r = mLaunchingProviders.get(i);
14312                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14313                    continue;
14314                }
14315                if (!printed) {
14316                    if (needSep) pw.println();
14317                    needSep = true;
14318                    pw.println("  Launching content providers:");
14319                    printed = true;
14320                    printedAnything = true;
14321                }
14322                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14323                        pw.println(r);
14324            }
14325        }
14326
14327        if (!printedAnything) {
14328            pw.println("  (nothing)");
14329        }
14330    }
14331
14332    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14333            int opti, boolean dumpAll, String dumpPackage) {
14334        boolean needSep = false;
14335        boolean printedAnything = false;
14336
14337        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14338
14339        if (mGrantedUriPermissions.size() > 0) {
14340            boolean printed = false;
14341            int dumpUid = -2;
14342            if (dumpPackage != null) {
14343                try {
14344                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14345                } catch (NameNotFoundException e) {
14346                    dumpUid = -1;
14347                }
14348            }
14349            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14350                int uid = mGrantedUriPermissions.keyAt(i);
14351                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14352                    continue;
14353                }
14354                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14355                if (!printed) {
14356                    if (needSep) pw.println();
14357                    needSep = true;
14358                    pw.println("  Granted Uri Permissions:");
14359                    printed = true;
14360                    printedAnything = true;
14361                }
14362                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14363                for (UriPermission perm : perms.values()) {
14364                    pw.print("    "); pw.println(perm);
14365                    if (dumpAll) {
14366                        perm.dump(pw, "      ");
14367                    }
14368                }
14369            }
14370        }
14371
14372        if (!printedAnything) {
14373            pw.println("  (nothing)");
14374        }
14375    }
14376
14377    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14378            int opti, boolean dumpAll, String dumpPackage) {
14379        boolean printed = false;
14380
14381        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14382
14383        if (mIntentSenderRecords.size() > 0) {
14384            Iterator<WeakReference<PendingIntentRecord>> it
14385                    = mIntentSenderRecords.values().iterator();
14386            while (it.hasNext()) {
14387                WeakReference<PendingIntentRecord> ref = it.next();
14388                PendingIntentRecord rec = ref != null ? ref.get(): null;
14389                if (dumpPackage != null && (rec == null
14390                        || !dumpPackage.equals(rec.key.packageName))) {
14391                    continue;
14392                }
14393                printed = true;
14394                if (rec != null) {
14395                    pw.print("  * "); pw.println(rec);
14396                    if (dumpAll) {
14397                        rec.dump(pw, "    ");
14398                    }
14399                } else {
14400                    pw.print("  * "); pw.println(ref);
14401                }
14402            }
14403        }
14404
14405        if (!printed) {
14406            pw.println("  (nothing)");
14407        }
14408    }
14409
14410    private static final int dumpProcessList(PrintWriter pw,
14411            ActivityManagerService service, List list,
14412            String prefix, String normalLabel, String persistentLabel,
14413            String dumpPackage) {
14414        int numPers = 0;
14415        final int N = list.size()-1;
14416        for (int i=N; i>=0; i--) {
14417            ProcessRecord r = (ProcessRecord)list.get(i);
14418            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14419                continue;
14420            }
14421            pw.println(String.format("%s%s #%2d: %s",
14422                    prefix, (r.persistent ? persistentLabel : normalLabel),
14423                    i, r.toString()));
14424            if (r.persistent) {
14425                numPers++;
14426            }
14427        }
14428        return numPers;
14429    }
14430
14431    private static final boolean dumpProcessOomList(PrintWriter pw,
14432            ActivityManagerService service, List<ProcessRecord> origList,
14433            String prefix, String normalLabel, String persistentLabel,
14434            boolean inclDetails, String dumpPackage) {
14435
14436        ArrayList<Pair<ProcessRecord, Integer>> list
14437                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14438        for (int i=0; i<origList.size(); i++) {
14439            ProcessRecord r = origList.get(i);
14440            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14441                continue;
14442            }
14443            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14444        }
14445
14446        if (list.size() <= 0) {
14447            return false;
14448        }
14449
14450        Comparator<Pair<ProcessRecord, Integer>> comparator
14451                = new Comparator<Pair<ProcessRecord, Integer>>() {
14452            @Override
14453            public int compare(Pair<ProcessRecord, Integer> object1,
14454                    Pair<ProcessRecord, Integer> object2) {
14455                if (object1.first.setAdj != object2.first.setAdj) {
14456                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14457                }
14458                if (object1.second.intValue() != object2.second.intValue()) {
14459                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14460                }
14461                return 0;
14462            }
14463        };
14464
14465        Collections.sort(list, comparator);
14466
14467        final long curRealtime = SystemClock.elapsedRealtime();
14468        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14469        final long curUptime = SystemClock.uptimeMillis();
14470        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14471
14472        for (int i=list.size()-1; i>=0; i--) {
14473            ProcessRecord r = list.get(i).first;
14474            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14475            char schedGroup;
14476            switch (r.setSchedGroup) {
14477                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14478                    schedGroup = 'B';
14479                    break;
14480                case Process.THREAD_GROUP_DEFAULT:
14481                    schedGroup = 'F';
14482                    break;
14483                default:
14484                    schedGroup = '?';
14485                    break;
14486            }
14487            char foreground;
14488            if (r.foregroundActivities) {
14489                foreground = 'A';
14490            } else if (r.foregroundServices) {
14491                foreground = 'S';
14492            } else {
14493                foreground = ' ';
14494            }
14495            String procState = ProcessList.makeProcStateString(r.curProcState);
14496            pw.print(prefix);
14497            pw.print(r.persistent ? persistentLabel : normalLabel);
14498            pw.print(" #");
14499            int num = (origList.size()-1)-list.get(i).second;
14500            if (num < 10) pw.print(' ');
14501            pw.print(num);
14502            pw.print(": ");
14503            pw.print(oomAdj);
14504            pw.print(' ');
14505            pw.print(schedGroup);
14506            pw.print('/');
14507            pw.print(foreground);
14508            pw.print('/');
14509            pw.print(procState);
14510            pw.print(" trm:");
14511            if (r.trimMemoryLevel < 10) pw.print(' ');
14512            pw.print(r.trimMemoryLevel);
14513            pw.print(' ');
14514            pw.print(r.toShortString());
14515            pw.print(" (");
14516            pw.print(r.adjType);
14517            pw.println(')');
14518            if (r.adjSource != null || r.adjTarget != null) {
14519                pw.print(prefix);
14520                pw.print("    ");
14521                if (r.adjTarget instanceof ComponentName) {
14522                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14523                } else if (r.adjTarget != null) {
14524                    pw.print(r.adjTarget.toString());
14525                } else {
14526                    pw.print("{null}");
14527                }
14528                pw.print("<=");
14529                if (r.adjSource instanceof ProcessRecord) {
14530                    pw.print("Proc{");
14531                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14532                    pw.println("}");
14533                } else if (r.adjSource != null) {
14534                    pw.println(r.adjSource.toString());
14535                } else {
14536                    pw.println("{null}");
14537                }
14538            }
14539            if (inclDetails) {
14540                pw.print(prefix);
14541                pw.print("    ");
14542                pw.print("oom: max="); pw.print(r.maxAdj);
14543                pw.print(" curRaw="); pw.print(r.curRawAdj);
14544                pw.print(" setRaw="); pw.print(r.setRawAdj);
14545                pw.print(" cur="); pw.print(r.curAdj);
14546                pw.print(" set="); pw.println(r.setAdj);
14547                pw.print(prefix);
14548                pw.print("    ");
14549                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14550                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14551                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14552                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14553                pw.println();
14554                pw.print(prefix);
14555                pw.print("    ");
14556                pw.print("cached="); pw.print(r.cached);
14557                pw.print(" empty="); pw.print(r.empty);
14558                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14559
14560                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14561                    if (r.lastWakeTime != 0) {
14562                        long wtime;
14563                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14564                        synchronized (stats) {
14565                            wtime = stats.getProcessWakeTime(r.info.uid,
14566                                    r.pid, curRealtime);
14567                        }
14568                        long timeUsed = wtime - r.lastWakeTime;
14569                        pw.print(prefix);
14570                        pw.print("    ");
14571                        pw.print("keep awake over ");
14572                        TimeUtils.formatDuration(realtimeSince, pw);
14573                        pw.print(" used ");
14574                        TimeUtils.formatDuration(timeUsed, pw);
14575                        pw.print(" (");
14576                        pw.print((timeUsed*100)/realtimeSince);
14577                        pw.println("%)");
14578                    }
14579                    if (r.lastCpuTime != 0) {
14580                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14581                        pw.print(prefix);
14582                        pw.print("    ");
14583                        pw.print("run cpu over ");
14584                        TimeUtils.formatDuration(uptimeSince, pw);
14585                        pw.print(" used ");
14586                        TimeUtils.formatDuration(timeUsed, pw);
14587                        pw.print(" (");
14588                        pw.print((timeUsed*100)/uptimeSince);
14589                        pw.println("%)");
14590                    }
14591                }
14592            }
14593        }
14594        return true;
14595    }
14596
14597    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14598            String[] args) {
14599        ArrayList<ProcessRecord> procs;
14600        synchronized (this) {
14601            if (args != null && args.length > start
14602                    && args[start].charAt(0) != '-') {
14603                procs = new ArrayList<ProcessRecord>();
14604                int pid = -1;
14605                try {
14606                    pid = Integer.parseInt(args[start]);
14607                } catch (NumberFormatException e) {
14608                }
14609                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14610                    ProcessRecord proc = mLruProcesses.get(i);
14611                    if (proc.pid == pid) {
14612                        procs.add(proc);
14613                    } else if (allPkgs && proc.pkgList != null
14614                            && proc.pkgList.containsKey(args[start])) {
14615                        procs.add(proc);
14616                    } else if (proc.processName.equals(args[start])) {
14617                        procs.add(proc);
14618                    }
14619                }
14620                if (procs.size() <= 0) {
14621                    return null;
14622                }
14623            } else {
14624                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14625            }
14626        }
14627        return procs;
14628    }
14629
14630    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14631            PrintWriter pw, String[] args) {
14632        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14633        if (procs == null) {
14634            pw.println("No process found for: " + args[0]);
14635            return;
14636        }
14637
14638        long uptime = SystemClock.uptimeMillis();
14639        long realtime = SystemClock.elapsedRealtime();
14640        pw.println("Applications Graphics Acceleration Info:");
14641        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14642
14643        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14644            ProcessRecord r = procs.get(i);
14645            if (r.thread != null) {
14646                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14647                pw.flush();
14648                try {
14649                    TransferPipe tp = new TransferPipe();
14650                    try {
14651                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14652                        tp.go(fd);
14653                    } finally {
14654                        tp.kill();
14655                    }
14656                } catch (IOException e) {
14657                    pw.println("Failure while dumping the app: " + r);
14658                    pw.flush();
14659                } catch (RemoteException e) {
14660                    pw.println("Got a RemoteException while dumping the app " + r);
14661                    pw.flush();
14662                }
14663            }
14664        }
14665    }
14666
14667    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14668        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14669        if (procs == null) {
14670            pw.println("No process found for: " + args[0]);
14671            return;
14672        }
14673
14674        pw.println("Applications Database Info:");
14675
14676        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14677            ProcessRecord r = procs.get(i);
14678            if (r.thread != null) {
14679                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14680                pw.flush();
14681                try {
14682                    TransferPipe tp = new TransferPipe();
14683                    try {
14684                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14685                        tp.go(fd);
14686                    } finally {
14687                        tp.kill();
14688                    }
14689                } catch (IOException e) {
14690                    pw.println("Failure while dumping the app: " + r);
14691                    pw.flush();
14692                } catch (RemoteException e) {
14693                    pw.println("Got a RemoteException while dumping the app " + r);
14694                    pw.flush();
14695                }
14696            }
14697        }
14698    }
14699
14700    final static class MemItem {
14701        final boolean isProc;
14702        final String label;
14703        final String shortLabel;
14704        final long pss;
14705        final int id;
14706        final boolean hasActivities;
14707        ArrayList<MemItem> subitems;
14708
14709        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14710                boolean _hasActivities) {
14711            isProc = true;
14712            label = _label;
14713            shortLabel = _shortLabel;
14714            pss = _pss;
14715            id = _id;
14716            hasActivities = _hasActivities;
14717        }
14718
14719        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14720            isProc = false;
14721            label = _label;
14722            shortLabel = _shortLabel;
14723            pss = _pss;
14724            id = _id;
14725            hasActivities = false;
14726        }
14727    }
14728
14729    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14730            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14731        if (sort && !isCompact) {
14732            Collections.sort(items, new Comparator<MemItem>() {
14733                @Override
14734                public int compare(MemItem lhs, MemItem rhs) {
14735                    if (lhs.pss < rhs.pss) {
14736                        return 1;
14737                    } else if (lhs.pss > rhs.pss) {
14738                        return -1;
14739                    }
14740                    return 0;
14741                }
14742            });
14743        }
14744
14745        for (int i=0; i<items.size(); i++) {
14746            MemItem mi = items.get(i);
14747            if (!isCompact) {
14748                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14749            } else if (mi.isProc) {
14750                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14751                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14752                pw.println(mi.hasActivities ? ",a" : ",e");
14753            } else {
14754                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14755                pw.println(mi.pss);
14756            }
14757            if (mi.subitems != null) {
14758                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14759                        true, isCompact);
14760            }
14761        }
14762    }
14763
14764    // These are in KB.
14765    static final long[] DUMP_MEM_BUCKETS = new long[] {
14766        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14767        120*1024, 160*1024, 200*1024,
14768        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14769        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14770    };
14771
14772    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14773            boolean stackLike) {
14774        int start = label.lastIndexOf('.');
14775        if (start >= 0) start++;
14776        else start = 0;
14777        int end = label.length();
14778        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14779            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14780                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14781                out.append(bucket);
14782                out.append(stackLike ? "MB." : "MB ");
14783                out.append(label, start, end);
14784                return;
14785            }
14786        }
14787        out.append(memKB/1024);
14788        out.append(stackLike ? "MB." : "MB ");
14789        out.append(label, start, end);
14790    }
14791
14792    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14793            ProcessList.NATIVE_ADJ,
14794            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14795            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14796            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14797            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14798            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14799            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14800    };
14801    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14802            "Native",
14803            "System", "Persistent", "Persistent Service", "Foreground",
14804            "Visible", "Perceptible",
14805            "Heavy Weight", "Backup",
14806            "A Services", "Home",
14807            "Previous", "B Services", "Cached"
14808    };
14809    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14810            "native",
14811            "sys", "pers", "persvc", "fore",
14812            "vis", "percept",
14813            "heavy", "backup",
14814            "servicea", "home",
14815            "prev", "serviceb", "cached"
14816    };
14817
14818    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14819            long realtime, boolean isCheckinRequest, boolean isCompact) {
14820        if (isCheckinRequest || isCompact) {
14821            // short checkin version
14822            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14823        } else {
14824            pw.println("Applications Memory Usage (in Kilobytes):");
14825            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14826        }
14827    }
14828
14829    private static final int KSM_SHARED = 0;
14830    private static final int KSM_SHARING = 1;
14831    private static final int KSM_UNSHARED = 2;
14832    private static final int KSM_VOLATILE = 3;
14833
14834    private final long[] getKsmInfo() {
14835        long[] longOut = new long[4];
14836        final int[] SINGLE_LONG_FORMAT = new int[] {
14837            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14838        };
14839        long[] longTmp = new long[1];
14840        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14841                SINGLE_LONG_FORMAT, null, longTmp, null);
14842        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14843        longTmp[0] = 0;
14844        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14845                SINGLE_LONG_FORMAT, null, longTmp, null);
14846        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14847        longTmp[0] = 0;
14848        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14849                SINGLE_LONG_FORMAT, null, longTmp, null);
14850        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14851        longTmp[0] = 0;
14852        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14853                SINGLE_LONG_FORMAT, null, longTmp, null);
14854        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14855        return longOut;
14856    }
14857
14858    private static String stringifySize(long size, int order) {
14859        Locale locale = Locale.US;
14860        switch (order) {
14861            case 1:
14862                return String.format(locale, "%,13d", size);
14863            case 1024:
14864                return String.format(locale, "%,9dK", size / 1024);
14865            case 1024 * 1024:
14866                return String.format(locale, "%,5dM", size / 1024 / 1024);
14867            case 1024 * 1024 * 1024:
14868                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
14869            default:
14870                throw new IllegalArgumentException("Invalid size order");
14871        }
14872    }
14873
14874    private static String stringifyKBSize(long size) {
14875        return stringifySize(size * 1024, 1024);
14876    }
14877
14878    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14879            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14880        boolean dumpDetails = false;
14881        boolean dumpFullDetails = false;
14882        boolean dumpDalvik = false;
14883        boolean dumpSummaryOnly = false;
14884        boolean oomOnly = false;
14885        boolean isCompact = false;
14886        boolean localOnly = false;
14887        boolean packages = false;
14888
14889        int opti = 0;
14890        while (opti < args.length) {
14891            String opt = args[opti];
14892            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14893                break;
14894            }
14895            opti++;
14896            if ("-a".equals(opt)) {
14897                dumpDetails = true;
14898                dumpFullDetails = true;
14899                dumpDalvik = true;
14900            } else if ("-d".equals(opt)) {
14901                dumpDalvik = true;
14902            } else if ("-c".equals(opt)) {
14903                isCompact = true;
14904            } else if ("-s".equals(opt)) {
14905                dumpDetails = true;
14906                dumpSummaryOnly = true;
14907            } else if ("--oom".equals(opt)) {
14908                oomOnly = true;
14909            } else if ("--local".equals(opt)) {
14910                localOnly = true;
14911            } else if ("--package".equals(opt)) {
14912                packages = true;
14913            } else if ("-h".equals(opt)) {
14914                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14915                pw.println("  -a: include all available information for each process.");
14916                pw.println("  -d: include dalvik details.");
14917                pw.println("  -c: dump in a compact machine-parseable representation.");
14918                pw.println("  -s: dump only summary of application memory usage.");
14919                pw.println("  --oom: only show processes organized by oom adj.");
14920                pw.println("  --local: only collect details locally, don't call process.");
14921                pw.println("  --package: interpret process arg as package, dumping all");
14922                pw.println("             processes that have loaded that package.");
14923                pw.println("If [process] is specified it can be the name or ");
14924                pw.println("pid of a specific process to dump.");
14925                return;
14926            } else {
14927                pw.println("Unknown argument: " + opt + "; use -h for help");
14928            }
14929        }
14930
14931        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14932        long uptime = SystemClock.uptimeMillis();
14933        long realtime = SystemClock.elapsedRealtime();
14934        final long[] tmpLong = new long[1];
14935
14936        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14937        if (procs == null) {
14938            // No Java processes.  Maybe they want to print a native process.
14939            if (args != null && args.length > opti
14940                    && args[opti].charAt(0) != '-') {
14941                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14942                        = new ArrayList<ProcessCpuTracker.Stats>();
14943                updateCpuStatsNow();
14944                int findPid = -1;
14945                try {
14946                    findPid = Integer.parseInt(args[opti]);
14947                } catch (NumberFormatException e) {
14948                }
14949                synchronized (mProcessCpuTracker) {
14950                    final int N = mProcessCpuTracker.countStats();
14951                    for (int i=0; i<N; i++) {
14952                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14953                        if (st.pid == findPid || (st.baseName != null
14954                                && st.baseName.equals(args[opti]))) {
14955                            nativeProcs.add(st);
14956                        }
14957                    }
14958                }
14959                if (nativeProcs.size() > 0) {
14960                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14961                            isCompact);
14962                    Debug.MemoryInfo mi = null;
14963                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14964                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14965                        final int pid = r.pid;
14966                        if (!isCheckinRequest && dumpDetails) {
14967                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14968                        }
14969                        if (mi == null) {
14970                            mi = new Debug.MemoryInfo();
14971                        }
14972                        if (dumpDetails || (!brief && !oomOnly)) {
14973                            Debug.getMemoryInfo(pid, mi);
14974                        } else {
14975                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14976                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14977                        }
14978                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14979                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14980                        if (isCheckinRequest) {
14981                            pw.println();
14982                        }
14983                    }
14984                    return;
14985                }
14986            }
14987            pw.println("No process found for: " + args[opti]);
14988            return;
14989        }
14990
14991        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14992            dumpDetails = true;
14993        }
14994
14995        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14996
14997        String[] innerArgs = new String[args.length-opti];
14998        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14999
15000        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15001        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15002        long nativePss = 0;
15003        long dalvikPss = 0;
15004        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15005                EmptyArray.LONG;
15006        long otherPss = 0;
15007        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15008
15009        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15010        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15011                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15012
15013        long totalPss = 0;
15014        long cachedPss = 0;
15015
15016        Debug.MemoryInfo mi = null;
15017        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15018            final ProcessRecord r = procs.get(i);
15019            final IApplicationThread thread;
15020            final int pid;
15021            final int oomAdj;
15022            final boolean hasActivities;
15023            synchronized (this) {
15024                thread = r.thread;
15025                pid = r.pid;
15026                oomAdj = r.getSetAdjWithServices();
15027                hasActivities = r.activities.size() > 0;
15028            }
15029            if (thread != null) {
15030                if (!isCheckinRequest && dumpDetails) {
15031                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15032                }
15033                if (mi == null) {
15034                    mi = new Debug.MemoryInfo();
15035                }
15036                if (dumpDetails || (!brief && !oomOnly)) {
15037                    Debug.getMemoryInfo(pid, mi);
15038                } else {
15039                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15040                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15041                }
15042                if (dumpDetails) {
15043                    if (localOnly) {
15044                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15045                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15046                        if (isCheckinRequest) {
15047                            pw.println();
15048                        }
15049                    } else {
15050                        try {
15051                            pw.flush();
15052                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15053                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15054                        } catch (RemoteException e) {
15055                            if (!isCheckinRequest) {
15056                                pw.println("Got RemoteException!");
15057                                pw.flush();
15058                            }
15059                        }
15060                    }
15061                }
15062
15063                final long myTotalPss = mi.getTotalPss();
15064                final long myTotalUss = mi.getTotalUss();
15065
15066                synchronized (this) {
15067                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15068                        // Record this for posterity if the process has been stable.
15069                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15070                    }
15071                }
15072
15073                if (!isCheckinRequest && mi != null) {
15074                    totalPss += myTotalPss;
15075                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15076                            (hasActivities ? " / activities)" : ")"),
15077                            r.processName, myTotalPss, pid, hasActivities);
15078                    procMems.add(pssItem);
15079                    procMemsMap.put(pid, pssItem);
15080
15081                    nativePss += mi.nativePss;
15082                    dalvikPss += mi.dalvikPss;
15083                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15084                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15085                    }
15086                    otherPss += mi.otherPss;
15087                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15088                        long mem = mi.getOtherPss(j);
15089                        miscPss[j] += mem;
15090                        otherPss -= mem;
15091                    }
15092
15093                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15094                        cachedPss += myTotalPss;
15095                    }
15096
15097                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15098                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15099                                || oomIndex == (oomPss.length-1)) {
15100                            oomPss[oomIndex] += myTotalPss;
15101                            if (oomProcs[oomIndex] == null) {
15102                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15103                            }
15104                            oomProcs[oomIndex].add(pssItem);
15105                            break;
15106                        }
15107                    }
15108                }
15109            }
15110        }
15111
15112        long nativeProcTotalPss = 0;
15113
15114        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15115            // If we are showing aggregations, also look for native processes to
15116            // include so that our aggregations are more accurate.
15117            updateCpuStatsNow();
15118            mi = null;
15119            synchronized (mProcessCpuTracker) {
15120                final int N = mProcessCpuTracker.countStats();
15121                for (int i=0; i<N; i++) {
15122                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15123                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15124                        if (mi == null) {
15125                            mi = new Debug.MemoryInfo();
15126                        }
15127                        if (!brief && !oomOnly) {
15128                            Debug.getMemoryInfo(st.pid, mi);
15129                        } else {
15130                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15131                            mi.nativePrivateDirty = (int)tmpLong[0];
15132                        }
15133
15134                        final long myTotalPss = mi.getTotalPss();
15135                        totalPss += myTotalPss;
15136                        nativeProcTotalPss += myTotalPss;
15137
15138                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15139                                st.name, myTotalPss, st.pid, false);
15140                        procMems.add(pssItem);
15141
15142                        nativePss += mi.nativePss;
15143                        dalvikPss += mi.dalvikPss;
15144                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15145                            dalvikSubitemPss[j] += mi.getOtherPss(
15146                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15147                        }
15148                        otherPss += mi.otherPss;
15149                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15150                            long mem = mi.getOtherPss(j);
15151                            miscPss[j] += mem;
15152                            otherPss -= mem;
15153                        }
15154                        oomPss[0] += myTotalPss;
15155                        if (oomProcs[0] == null) {
15156                            oomProcs[0] = new ArrayList<MemItem>();
15157                        }
15158                        oomProcs[0].add(pssItem);
15159                    }
15160                }
15161            }
15162
15163            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15164
15165            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15166            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15167            if (dalvikSubitemPss.length > 0) {
15168                dalvikItem.subitems = new ArrayList<MemItem>();
15169                for (int j=0; j<dalvikSubitemPss.length; j++) {
15170                    final String name = Debug.MemoryInfo.getOtherLabel(
15171                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15172                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15173                }
15174            }
15175            catMems.add(dalvikItem);
15176            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15177            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15178                String label = Debug.MemoryInfo.getOtherLabel(j);
15179                catMems.add(new MemItem(label, label, miscPss[j], j));
15180            }
15181
15182            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15183            for (int j=0; j<oomPss.length; j++) {
15184                if (oomPss[j] != 0) {
15185                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15186                            : DUMP_MEM_OOM_LABEL[j];
15187                    MemItem item = new MemItem(label, label, oomPss[j],
15188                            DUMP_MEM_OOM_ADJ[j]);
15189                    item.subitems = oomProcs[j];
15190                    oomMems.add(item);
15191                }
15192            }
15193
15194            if (!brief && !oomOnly && !isCompact) {
15195                pw.println();
15196                pw.println("Total PSS by process:");
15197                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15198                pw.println();
15199            }
15200            if (!isCompact) {
15201                pw.println("Total PSS by OOM adjustment:");
15202            }
15203            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15204            if (!brief && !oomOnly) {
15205                PrintWriter out = categoryPw != null ? categoryPw : pw;
15206                if (!isCompact) {
15207                    out.println();
15208                    out.println("Total PSS by category:");
15209                }
15210                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15211            }
15212            if (!isCompact) {
15213                pw.println();
15214            }
15215            MemInfoReader memInfo = new MemInfoReader();
15216            memInfo.readMemInfo();
15217            if (nativeProcTotalPss > 0) {
15218                synchronized (this) {
15219                    final long cachedKb = memInfo.getCachedSizeKb();
15220                    final long freeKb = memInfo.getFreeSizeKb();
15221                    final long zramKb = memInfo.getZramTotalSizeKb();
15222                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15223                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15224                            kernelKb*1024, nativeProcTotalPss*1024);
15225                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15226                            nativeProcTotalPss);
15227                }
15228            }
15229            if (!brief) {
15230                if (!isCompact) {
15231                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15232                    pw.print(" (status ");
15233                    switch (mLastMemoryLevel) {
15234                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15235                            pw.println("normal)");
15236                            break;
15237                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15238                            pw.println("moderate)");
15239                            break;
15240                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15241                            pw.println("low)");
15242                            break;
15243                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15244                            pw.println("critical)");
15245                            break;
15246                        default:
15247                            pw.print(mLastMemoryLevel);
15248                            pw.println(")");
15249                            break;
15250                    }
15251                    pw.print(" Free RAM: ");
15252                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15253                            + memInfo.getFreeSizeKb()));
15254                    pw.print(" (");
15255                    pw.print(stringifyKBSize(cachedPss));
15256                    pw.print(" cached pss + ");
15257                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15258                    pw.print(" cached kernel + ");
15259                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15260                    pw.println(" free)");
15261                } else {
15262                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15263                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15264                            + memInfo.getFreeSizeKb()); pw.print(",");
15265                    pw.println(totalPss - cachedPss);
15266                }
15267            }
15268            if (!isCompact) {
15269                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15270                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15271                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15272                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15273                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15274                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15275                        - memInfo.getKernelUsedSizeKb()));
15276            }
15277            if (!brief) {
15278                if (memInfo.getZramTotalSizeKb() != 0) {
15279                    if (!isCompact) {
15280                        pw.print("     ZRAM: ");
15281                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15282                                pw.print(" physical used for ");
15283                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15284                                        - memInfo.getSwapFreeSizeKb()));
15285                                pw.print(" in swap (");
15286                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15287                                pw.println(" total swap)");
15288                    } else {
15289                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15290                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15291                                pw.println(memInfo.getSwapFreeSizeKb());
15292                    }
15293                }
15294                final long[] ksm = getKsmInfo();
15295                if (!isCompact) {
15296                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15297                            || ksm[KSM_VOLATILE] != 0) {
15298                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15299                                pw.print(" saved from shared ");
15300                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15301                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15302                                pw.print(" unshared; ");
15303                                pw.print(stringifyKBSize(
15304                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15305                    }
15306                    pw.print("   Tuning: ");
15307                    pw.print(ActivityManager.staticGetMemoryClass());
15308                    pw.print(" (large ");
15309                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15310                    pw.print("), oom ");
15311                    pw.print(stringifySize(
15312                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15313                    pw.print(", restore limit ");
15314                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15315                    if (ActivityManager.isLowRamDeviceStatic()) {
15316                        pw.print(" (low-ram)");
15317                    }
15318                    if (ActivityManager.isHighEndGfx()) {
15319                        pw.print(" (high-end-gfx)");
15320                    }
15321                    pw.println();
15322                } else {
15323                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15324                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15325                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15326                    pw.print("tuning,");
15327                    pw.print(ActivityManager.staticGetMemoryClass());
15328                    pw.print(',');
15329                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15330                    pw.print(',');
15331                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15332                    if (ActivityManager.isLowRamDeviceStatic()) {
15333                        pw.print(",low-ram");
15334                    }
15335                    if (ActivityManager.isHighEndGfx()) {
15336                        pw.print(",high-end-gfx");
15337                    }
15338                    pw.println();
15339                }
15340            }
15341        }
15342    }
15343
15344    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15345            long memtrack, String name) {
15346        sb.append("  ");
15347        sb.append(ProcessList.makeOomAdjString(oomAdj));
15348        sb.append(' ');
15349        sb.append(ProcessList.makeProcStateString(procState));
15350        sb.append(' ');
15351        ProcessList.appendRamKb(sb, pss);
15352        sb.append(": ");
15353        sb.append(name);
15354        if (memtrack > 0) {
15355            sb.append(" (");
15356            sb.append(stringifyKBSize(memtrack));
15357            sb.append(" memtrack)");
15358        }
15359    }
15360
15361    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15362        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15363        sb.append(" (pid ");
15364        sb.append(mi.pid);
15365        sb.append(") ");
15366        sb.append(mi.adjType);
15367        sb.append('\n');
15368        if (mi.adjReason != null) {
15369            sb.append("                      ");
15370            sb.append(mi.adjReason);
15371            sb.append('\n');
15372        }
15373    }
15374
15375    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15376        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15377        for (int i=0, N=memInfos.size(); i<N; i++) {
15378            ProcessMemInfo mi = memInfos.get(i);
15379            infoMap.put(mi.pid, mi);
15380        }
15381        updateCpuStatsNow();
15382        long[] memtrackTmp = new long[1];
15383        synchronized (mProcessCpuTracker) {
15384            final int N = mProcessCpuTracker.countStats();
15385            for (int i=0; i<N; i++) {
15386                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15387                if (st.vsize > 0) {
15388                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15389                    if (pss > 0) {
15390                        if (infoMap.indexOfKey(st.pid) < 0) {
15391                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15392                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15393                            mi.pss = pss;
15394                            mi.memtrack = memtrackTmp[0];
15395                            memInfos.add(mi);
15396                        }
15397                    }
15398                }
15399            }
15400        }
15401
15402        long totalPss = 0;
15403        long totalMemtrack = 0;
15404        for (int i=0, N=memInfos.size(); i<N; i++) {
15405            ProcessMemInfo mi = memInfos.get(i);
15406            if (mi.pss == 0) {
15407                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15408                mi.memtrack = memtrackTmp[0];
15409            }
15410            totalPss += mi.pss;
15411            totalMemtrack += mi.memtrack;
15412        }
15413        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15414            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15415                if (lhs.oomAdj != rhs.oomAdj) {
15416                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15417                }
15418                if (lhs.pss != rhs.pss) {
15419                    return lhs.pss < rhs.pss ? 1 : -1;
15420                }
15421                return 0;
15422            }
15423        });
15424
15425        StringBuilder tag = new StringBuilder(128);
15426        StringBuilder stack = new StringBuilder(128);
15427        tag.append("Low on memory -- ");
15428        appendMemBucket(tag, totalPss, "total", false);
15429        appendMemBucket(stack, totalPss, "total", true);
15430
15431        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15432        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15433        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15434
15435        boolean firstLine = true;
15436        int lastOomAdj = Integer.MIN_VALUE;
15437        long extraNativeRam = 0;
15438        long extraNativeMemtrack = 0;
15439        long cachedPss = 0;
15440        for (int i=0, N=memInfos.size(); i<N; i++) {
15441            ProcessMemInfo mi = memInfos.get(i);
15442
15443            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15444                cachedPss += mi.pss;
15445            }
15446
15447            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15448                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15449                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15450                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15451                if (lastOomAdj != mi.oomAdj) {
15452                    lastOomAdj = mi.oomAdj;
15453                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15454                        tag.append(" / ");
15455                    }
15456                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15457                        if (firstLine) {
15458                            stack.append(":");
15459                            firstLine = false;
15460                        }
15461                        stack.append("\n\t at ");
15462                    } else {
15463                        stack.append("$");
15464                    }
15465                } else {
15466                    tag.append(" ");
15467                    stack.append("$");
15468                }
15469                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15470                    appendMemBucket(tag, mi.pss, mi.name, false);
15471                }
15472                appendMemBucket(stack, mi.pss, mi.name, true);
15473                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15474                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15475                    stack.append("(");
15476                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15477                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15478                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15479                            stack.append(":");
15480                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15481                        }
15482                    }
15483                    stack.append(")");
15484                }
15485            }
15486
15487            appendMemInfo(fullNativeBuilder, mi);
15488            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15489                // The short form only has native processes that are >= 512K.
15490                if (mi.pss >= 512) {
15491                    appendMemInfo(shortNativeBuilder, mi);
15492                } else {
15493                    extraNativeRam += mi.pss;
15494                    extraNativeMemtrack += mi.memtrack;
15495                }
15496            } else {
15497                // Short form has all other details, but if we have collected RAM
15498                // from smaller native processes let's dump a summary of that.
15499                if (extraNativeRam > 0) {
15500                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15501                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15502                    shortNativeBuilder.append('\n');
15503                    extraNativeRam = 0;
15504                }
15505                appendMemInfo(fullJavaBuilder, mi);
15506            }
15507        }
15508
15509        fullJavaBuilder.append("           ");
15510        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15511        fullJavaBuilder.append(": TOTAL");
15512        if (totalMemtrack > 0) {
15513            fullJavaBuilder.append(" (");
15514            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15515            fullJavaBuilder.append(" memtrack)");
15516        } else {
15517        }
15518        fullJavaBuilder.append("\n");
15519
15520        MemInfoReader memInfo = new MemInfoReader();
15521        memInfo.readMemInfo();
15522        final long[] infos = memInfo.getRawInfo();
15523
15524        StringBuilder memInfoBuilder = new StringBuilder(1024);
15525        Debug.getMemInfo(infos);
15526        memInfoBuilder.append("  MemInfo: ");
15527        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15528        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15529        memInfoBuilder.append(stringifyKBSize(
15530                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15531        memInfoBuilder.append(stringifyKBSize(
15532                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15533        memInfoBuilder.append(stringifyKBSize(
15534                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15535        memInfoBuilder.append("           ");
15536        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15537        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15538        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15539        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15540        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15541            memInfoBuilder.append("  ZRAM: ");
15542            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15543            memInfoBuilder.append(" RAM, ");
15544            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15545            memInfoBuilder.append(" swap total, ");
15546            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15547            memInfoBuilder.append(" swap free\n");
15548        }
15549        final long[] ksm = getKsmInfo();
15550        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15551                || ksm[KSM_VOLATILE] != 0) {
15552            memInfoBuilder.append("  KSM: ");
15553            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15554            memInfoBuilder.append(" saved from shared ");
15555            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15556            memInfoBuilder.append("\n       ");
15557            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15558            memInfoBuilder.append(" unshared; ");
15559            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15560            memInfoBuilder.append(" volatile\n");
15561        }
15562        memInfoBuilder.append("  Free RAM: ");
15563        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15564                + memInfo.getFreeSizeKb()));
15565        memInfoBuilder.append("\n");
15566        memInfoBuilder.append("  Used RAM: ");
15567        memInfoBuilder.append(stringifyKBSize(
15568                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15569        memInfoBuilder.append("\n");
15570        memInfoBuilder.append("  Lost RAM: ");
15571        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15572                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15573                - memInfo.getKernelUsedSizeKb()));
15574        memInfoBuilder.append("\n");
15575        Slog.i(TAG, "Low on memory:");
15576        Slog.i(TAG, shortNativeBuilder.toString());
15577        Slog.i(TAG, fullJavaBuilder.toString());
15578        Slog.i(TAG, memInfoBuilder.toString());
15579
15580        StringBuilder dropBuilder = new StringBuilder(1024);
15581        /*
15582        StringWriter oomSw = new StringWriter();
15583        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15584        StringWriter catSw = new StringWriter();
15585        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15586        String[] emptyArgs = new String[] { };
15587        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15588        oomPw.flush();
15589        String oomString = oomSw.toString();
15590        */
15591        dropBuilder.append("Low on memory:");
15592        dropBuilder.append(stack);
15593        dropBuilder.append('\n');
15594        dropBuilder.append(fullNativeBuilder);
15595        dropBuilder.append(fullJavaBuilder);
15596        dropBuilder.append('\n');
15597        dropBuilder.append(memInfoBuilder);
15598        dropBuilder.append('\n');
15599        /*
15600        dropBuilder.append(oomString);
15601        dropBuilder.append('\n');
15602        */
15603        StringWriter catSw = new StringWriter();
15604        synchronized (ActivityManagerService.this) {
15605            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15606            String[] emptyArgs = new String[] { };
15607            catPw.println();
15608            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15609            catPw.println();
15610            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15611                    false, false, null);
15612            catPw.println();
15613            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15614            catPw.flush();
15615        }
15616        dropBuilder.append(catSw.toString());
15617        addErrorToDropBox("lowmem", null, "system_server", null,
15618                null, tag.toString(), dropBuilder.toString(), null, null);
15619        //Slog.i(TAG, "Sent to dropbox:");
15620        //Slog.i(TAG, dropBuilder.toString());
15621        synchronized (ActivityManagerService.this) {
15622            long now = SystemClock.uptimeMillis();
15623            if (mLastMemUsageReportTime < now) {
15624                mLastMemUsageReportTime = now;
15625            }
15626        }
15627    }
15628
15629    /**
15630     * Searches array of arguments for the specified string
15631     * @param args array of argument strings
15632     * @param value value to search for
15633     * @return true if the value is contained in the array
15634     */
15635    private static boolean scanArgs(String[] args, String value) {
15636        if (args != null) {
15637            for (String arg : args) {
15638                if (value.equals(arg)) {
15639                    return true;
15640                }
15641            }
15642        }
15643        return false;
15644    }
15645
15646    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15647            ContentProviderRecord cpr, boolean always) {
15648        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15649
15650        if (!inLaunching || always) {
15651            synchronized (cpr) {
15652                cpr.launchingApp = null;
15653                cpr.notifyAll();
15654            }
15655            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15656            String names[] = cpr.info.authority.split(";");
15657            for (int j = 0; j < names.length; j++) {
15658                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15659            }
15660        }
15661
15662        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15663            ContentProviderConnection conn = cpr.connections.get(i);
15664            if (conn.waiting) {
15665                // If this connection is waiting for the provider, then we don't
15666                // need to mess with its process unless we are always removing
15667                // or for some reason the provider is not currently launching.
15668                if (inLaunching && !always) {
15669                    continue;
15670                }
15671            }
15672            ProcessRecord capp = conn.client;
15673            conn.dead = true;
15674            if (conn.stableCount > 0) {
15675                if (!capp.persistent && capp.thread != null
15676                        && capp.pid != 0
15677                        && capp.pid != MY_PID) {
15678                    capp.kill("depends on provider "
15679                            + cpr.name.flattenToShortString()
15680                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15681                }
15682            } else if (capp.thread != null && conn.provider.provider != null) {
15683                try {
15684                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15685                } catch (RemoteException e) {
15686                }
15687                // In the protocol here, we don't expect the client to correctly
15688                // clean up this connection, we'll just remove it.
15689                cpr.connections.remove(i);
15690                if (conn.client.conProviders.remove(conn)) {
15691                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15692                }
15693            }
15694        }
15695
15696        if (inLaunching && always) {
15697            mLaunchingProviders.remove(cpr);
15698        }
15699        return inLaunching;
15700    }
15701
15702    /**
15703     * Main code for cleaning up a process when it has gone away.  This is
15704     * called both as a result of the process dying, or directly when stopping
15705     * a process when running in single process mode.
15706     *
15707     * @return Returns true if the given process has been restarted, so the
15708     * app that was passed in must remain on the process lists.
15709     */
15710    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15711            boolean restarting, boolean allowRestart, int index) {
15712        if (index >= 0) {
15713            removeLruProcessLocked(app);
15714            ProcessList.remove(app.pid);
15715        }
15716
15717        mProcessesToGc.remove(app);
15718        mPendingPssProcesses.remove(app);
15719
15720        // Dismiss any open dialogs.
15721        if (app.crashDialog != null && !app.forceCrashReport) {
15722            app.crashDialog.dismiss();
15723            app.crashDialog = null;
15724        }
15725        if (app.anrDialog != null) {
15726            app.anrDialog.dismiss();
15727            app.anrDialog = null;
15728        }
15729        if (app.waitDialog != null) {
15730            app.waitDialog.dismiss();
15731            app.waitDialog = null;
15732        }
15733
15734        app.crashing = false;
15735        app.notResponding = false;
15736
15737        app.resetPackageList(mProcessStats);
15738        app.unlinkDeathRecipient();
15739        app.makeInactive(mProcessStats);
15740        app.waitingToKill = null;
15741        app.forcingToForeground = null;
15742        updateProcessForegroundLocked(app, false, false);
15743        app.foregroundActivities = false;
15744        app.hasShownUi = false;
15745        app.treatLikeActivity = false;
15746        app.hasAboveClient = false;
15747        app.hasClientActivities = false;
15748
15749        mServices.killServicesLocked(app, allowRestart);
15750
15751        boolean restart = false;
15752
15753        // Remove published content providers.
15754        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15755            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15756            final boolean always = app.bad || !allowRestart;
15757            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15758            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15759                // We left the provider in the launching list, need to
15760                // restart it.
15761                restart = true;
15762            }
15763
15764            cpr.provider = null;
15765            cpr.proc = null;
15766        }
15767        app.pubProviders.clear();
15768
15769        // Take care of any launching providers waiting for this process.
15770        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15771            restart = true;
15772        }
15773
15774        // Unregister from connected content providers.
15775        if (!app.conProviders.isEmpty()) {
15776            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15777                ContentProviderConnection conn = app.conProviders.get(i);
15778                conn.provider.connections.remove(conn);
15779                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15780                        conn.provider.name);
15781            }
15782            app.conProviders.clear();
15783        }
15784
15785        // At this point there may be remaining entries in mLaunchingProviders
15786        // where we were the only one waiting, so they are no longer of use.
15787        // Look for these and clean up if found.
15788        // XXX Commented out for now.  Trying to figure out a way to reproduce
15789        // the actual situation to identify what is actually going on.
15790        if (false) {
15791            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15792                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15793                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15794                    synchronized (cpr) {
15795                        cpr.launchingApp = null;
15796                        cpr.notifyAll();
15797                    }
15798                }
15799            }
15800        }
15801
15802        skipCurrentReceiverLocked(app);
15803
15804        // Unregister any receivers.
15805        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15806            removeReceiverLocked(app.receivers.valueAt(i));
15807        }
15808        app.receivers.clear();
15809
15810        // If the app is undergoing backup, tell the backup manager about it
15811        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15812            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15813                    + mBackupTarget.appInfo + " died during backup");
15814            try {
15815                IBackupManager bm = IBackupManager.Stub.asInterface(
15816                        ServiceManager.getService(Context.BACKUP_SERVICE));
15817                bm.agentDisconnected(app.info.packageName);
15818            } catch (RemoteException e) {
15819                // can't happen; backup manager is local
15820            }
15821        }
15822
15823        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15824            ProcessChangeItem item = mPendingProcessChanges.get(i);
15825            if (item.pid == app.pid) {
15826                mPendingProcessChanges.remove(i);
15827                mAvailProcessChanges.add(item);
15828            }
15829        }
15830        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15831
15832        // If the caller is restarting this app, then leave it in its
15833        // current lists and let the caller take care of it.
15834        if (restarting) {
15835            return false;
15836        }
15837
15838        if (!app.persistent || app.isolated) {
15839            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15840                    "Removing non-persistent process during cleanup: " + app);
15841            removeProcessNameLocked(app.processName, app.uid);
15842            if (mHeavyWeightProcess == app) {
15843                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15844                        mHeavyWeightProcess.userId, 0));
15845                mHeavyWeightProcess = null;
15846            }
15847        } else if (!app.removed) {
15848            // This app is persistent, so we need to keep its record around.
15849            // If it is not already on the pending app list, add it there
15850            // and start a new process for it.
15851            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15852                mPersistentStartingProcesses.add(app);
15853                restart = true;
15854            }
15855        }
15856        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15857                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15858        mProcessesOnHold.remove(app);
15859
15860        if (app == mHomeProcess) {
15861            mHomeProcess = null;
15862        }
15863        if (app == mPreviousProcess) {
15864            mPreviousProcess = null;
15865        }
15866
15867        if (restart && !app.isolated) {
15868            // We have components that still need to be running in the
15869            // process, so re-launch it.
15870            if (index < 0) {
15871                ProcessList.remove(app.pid);
15872            }
15873            addProcessNameLocked(app);
15874            startProcessLocked(app, "restart", app.processName);
15875            return true;
15876        } else if (app.pid > 0 && app.pid != MY_PID) {
15877            // Goodbye!
15878            boolean removed;
15879            synchronized (mPidsSelfLocked) {
15880                mPidsSelfLocked.remove(app.pid);
15881                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15882            }
15883            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15884            if (app.isolated) {
15885                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15886            }
15887            app.setPid(0);
15888        }
15889        return false;
15890    }
15891
15892    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15893        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15894            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15895            if (cpr.launchingApp == app) {
15896                return true;
15897            }
15898        }
15899        return false;
15900    }
15901
15902    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15903        // Look through the content providers we are waiting to have launched,
15904        // and if any run in this process then either schedule a restart of
15905        // the process or kill the client waiting for it if this process has
15906        // gone bad.
15907        boolean restart = false;
15908        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15909            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15910            if (cpr.launchingApp == app) {
15911                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15912                    restart = true;
15913                } else {
15914                    removeDyingProviderLocked(app, cpr, true);
15915                }
15916            }
15917        }
15918        return restart;
15919    }
15920
15921    // =========================================================
15922    // SERVICES
15923    // =========================================================
15924
15925    @Override
15926    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15927            int flags) {
15928        enforceNotIsolatedCaller("getServices");
15929        synchronized (this) {
15930            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15931        }
15932    }
15933
15934    @Override
15935    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15936        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15937        synchronized (this) {
15938            return mServices.getRunningServiceControlPanelLocked(name);
15939        }
15940    }
15941
15942    @Override
15943    public ComponentName startService(IApplicationThread caller, Intent service,
15944            String resolvedType, String callingPackage, int userId)
15945            throws TransactionTooLargeException {
15946        enforceNotIsolatedCaller("startService");
15947        // Refuse possible leaked file descriptors
15948        if (service != null && service.hasFileDescriptors() == true) {
15949            throw new IllegalArgumentException("File descriptors passed in Intent");
15950        }
15951
15952        if (callingPackage == null) {
15953            throw new IllegalArgumentException("callingPackage cannot be null");
15954        }
15955
15956        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15957                "startService: " + service + " type=" + resolvedType);
15958        synchronized(this) {
15959            final int callingPid = Binder.getCallingPid();
15960            final int callingUid = Binder.getCallingUid();
15961            final long origId = Binder.clearCallingIdentity();
15962            ComponentName res = mServices.startServiceLocked(caller, service,
15963                    resolvedType, callingPid, callingUid, callingPackage, userId);
15964            Binder.restoreCallingIdentity(origId);
15965            return res;
15966        }
15967    }
15968
15969    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15970            String callingPackage, int userId)
15971            throws TransactionTooLargeException {
15972        synchronized(this) {
15973            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15974                    "startServiceInPackage: " + service + " type=" + resolvedType);
15975            final long origId = Binder.clearCallingIdentity();
15976            ComponentName res = mServices.startServiceLocked(null, service,
15977                    resolvedType, -1, uid, callingPackage, userId);
15978            Binder.restoreCallingIdentity(origId);
15979            return res;
15980        }
15981    }
15982
15983    @Override
15984    public int stopService(IApplicationThread caller, Intent service,
15985            String resolvedType, int userId) {
15986        enforceNotIsolatedCaller("stopService");
15987        // Refuse possible leaked file descriptors
15988        if (service != null && service.hasFileDescriptors() == true) {
15989            throw new IllegalArgumentException("File descriptors passed in Intent");
15990        }
15991
15992        synchronized(this) {
15993            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15994        }
15995    }
15996
15997    @Override
15998    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15999        enforceNotIsolatedCaller("peekService");
16000        // Refuse possible leaked file descriptors
16001        if (service != null && service.hasFileDescriptors() == true) {
16002            throw new IllegalArgumentException("File descriptors passed in Intent");
16003        }
16004
16005        if (callingPackage == null) {
16006            throw new IllegalArgumentException("callingPackage cannot be null");
16007        }
16008
16009        synchronized(this) {
16010            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16011        }
16012    }
16013
16014    @Override
16015    public boolean stopServiceToken(ComponentName className, IBinder token,
16016            int startId) {
16017        synchronized(this) {
16018            return mServices.stopServiceTokenLocked(className, token, startId);
16019        }
16020    }
16021
16022    @Override
16023    public void setServiceForeground(ComponentName className, IBinder token,
16024            int id, Notification notification, boolean removeNotification) {
16025        synchronized(this) {
16026            mServices.setServiceForegroundLocked(className, token, id, notification,
16027                    removeNotification);
16028        }
16029    }
16030
16031    @Override
16032    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16033            boolean requireFull, String name, String callerPackage) {
16034        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
16035                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16036    }
16037
16038    int unsafeConvertIncomingUserLocked(int userId) {
16039        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
16040                ? mUserController.mCurrentUserId : userId;
16041    }
16042
16043    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16044            int allowMode, String name, String callerPackage) {
16045        final int callingUserId = UserHandle.getUserId(callingUid);
16046        if (callingUserId == userId) {
16047            return userId;
16048        }
16049
16050        // Note that we may be accessing mCurrentUserId outside of a lock...
16051        // shouldn't be a big deal, if this is being called outside
16052        // of a locked context there is intrinsically a race with
16053        // the value the caller will receive and someone else changing it.
16054        // We assume that USER_CURRENT_OR_SELF will use the current user; later
16055        // we will switch to the calling user if access to the current user fails.
16056        int targetUserId = unsafeConvertIncomingUserLocked(userId);
16057
16058        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
16059            final boolean allow;
16060            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
16061                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
16062                // If the caller has this permission, they always pass go.  And collect $200.
16063                allow = true;
16064            } else if (allowMode == ALLOW_FULL_ONLY) {
16065                // We require full access, sucks to be you.
16066                allow = false;
16067            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
16068                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
16069                // If the caller does not have either permission, they are always doomed.
16070                allow = false;
16071            } else if (allowMode == ALLOW_NON_FULL) {
16072                // We are blanket allowing non-full access, you lucky caller!
16073                allow = true;
16074            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
16075                // We may or may not allow this depending on whether the two users are
16076                // in the same profile.
16077                allow = mUserController.isSameProfileGroup(callingUserId, targetUserId);
16078            } else {
16079                throw new IllegalArgumentException("Unknown mode: " + allowMode);
16080            }
16081            if (!allow) {
16082                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
16083                    // In this case, they would like to just execute as their
16084                    // owner user instead of failing.
16085                    targetUserId = callingUserId;
16086                } else {
16087                    StringBuilder builder = new StringBuilder(128);
16088                    builder.append("Permission Denial: ");
16089                    builder.append(name);
16090                    if (callerPackage != null) {
16091                        builder.append(" from ");
16092                        builder.append(callerPackage);
16093                    }
16094                    builder.append(" asks to run as user ");
16095                    builder.append(userId);
16096                    builder.append(" but is calling from user ");
16097                    builder.append(UserHandle.getUserId(callingUid));
16098                    builder.append("; this requires ");
16099                    builder.append(INTERACT_ACROSS_USERS_FULL);
16100                    if (allowMode != ALLOW_FULL_ONLY) {
16101                        builder.append(" or ");
16102                        builder.append(INTERACT_ACROSS_USERS);
16103                    }
16104                    String msg = builder.toString();
16105                    Slog.w(TAG, msg);
16106                    throw new SecurityException(msg);
16107                }
16108            }
16109        }
16110        if (!allowAll && targetUserId < 0) {
16111            throw new IllegalArgumentException(
16112                    "Call does not support special user #" + targetUserId);
16113        }
16114        // Check shell permission
16115        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_SYSTEM) {
16116            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
16117                    targetUserId)) {
16118                throw new SecurityException("Shell does not have permission to access user "
16119                        + targetUserId + "\n " + Debug.getCallers(3));
16120            }
16121        }
16122        return targetUserId;
16123    }
16124
16125    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16126            String className, int flags) {
16127        boolean result = false;
16128        // For apps that don't have pre-defined UIDs, check for permission
16129        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16130            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16131                if (ActivityManager.checkUidPermission(
16132                        INTERACT_ACROSS_USERS,
16133                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16134                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16135                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16136                            + " requests FLAG_SINGLE_USER, but app does not hold "
16137                            + INTERACT_ACROSS_USERS;
16138                    Slog.w(TAG, msg);
16139                    throw new SecurityException(msg);
16140                }
16141                // Permission passed
16142                result = true;
16143            }
16144        } else if ("system".equals(componentProcessName)) {
16145            result = true;
16146        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16147            // Phone app and persistent apps are allowed to export singleuser providers.
16148            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16149                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16150        }
16151        if (DEBUG_MU) Slog.v(TAG_MU,
16152                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16153                + Integer.toHexString(flags) + ") = " + result);
16154        return result;
16155    }
16156
16157    /**
16158     * Checks to see if the caller is in the same app as the singleton
16159     * component, or the component is in a special app. It allows special apps
16160     * to export singleton components but prevents exporting singleton
16161     * components for regular apps.
16162     */
16163    boolean isValidSingletonCall(int callingUid, int componentUid) {
16164        int componentAppId = UserHandle.getAppId(componentUid);
16165        return UserHandle.isSameApp(callingUid, componentUid)
16166                || componentAppId == Process.SYSTEM_UID
16167                || componentAppId == Process.PHONE_UID
16168                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16169                        == PackageManager.PERMISSION_GRANTED;
16170    }
16171
16172    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16173            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16174            int userId) throws TransactionTooLargeException {
16175        enforceNotIsolatedCaller("bindService");
16176
16177        // Refuse possible leaked file descriptors
16178        if (service != null && service.hasFileDescriptors() == true) {
16179            throw new IllegalArgumentException("File descriptors passed in Intent");
16180        }
16181
16182        if (callingPackage == null) {
16183            throw new IllegalArgumentException("callingPackage cannot be null");
16184        }
16185
16186        synchronized(this) {
16187            return mServices.bindServiceLocked(caller, token, service,
16188                    resolvedType, connection, flags, callingPackage, userId);
16189        }
16190    }
16191
16192    public boolean unbindService(IServiceConnection connection) {
16193        synchronized (this) {
16194            return mServices.unbindServiceLocked(connection);
16195        }
16196    }
16197
16198    public void publishService(IBinder token, Intent intent, IBinder service) {
16199        // Refuse possible leaked file descriptors
16200        if (intent != null && intent.hasFileDescriptors() == true) {
16201            throw new IllegalArgumentException("File descriptors passed in Intent");
16202        }
16203
16204        synchronized(this) {
16205            if (!(token instanceof ServiceRecord)) {
16206                throw new IllegalArgumentException("Invalid service token");
16207            }
16208            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16209        }
16210    }
16211
16212    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16213        // Refuse possible leaked file descriptors
16214        if (intent != null && intent.hasFileDescriptors() == true) {
16215            throw new IllegalArgumentException("File descriptors passed in Intent");
16216        }
16217
16218        synchronized(this) {
16219            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16220        }
16221    }
16222
16223    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16224        synchronized(this) {
16225            if (!(token instanceof ServiceRecord)) {
16226                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16227                throw new IllegalArgumentException("Invalid service token");
16228            }
16229            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16230        }
16231    }
16232
16233    // =========================================================
16234    // BACKUP AND RESTORE
16235    // =========================================================
16236
16237    // Cause the target app to be launched if necessary and its backup agent
16238    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16239    // activity manager to announce its creation.
16240    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16241        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16242                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16243        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16244
16245        synchronized(this) {
16246            // !!! TODO: currently no check here that we're already bound
16247            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16248            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16249            synchronized (stats) {
16250                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16251            }
16252
16253            // Backup agent is now in use, its package can't be stopped.
16254            try {
16255                AppGlobals.getPackageManager().setPackageStoppedState(
16256                        app.packageName, false, UserHandle.getUserId(app.uid));
16257            } catch (RemoteException e) {
16258            } catch (IllegalArgumentException e) {
16259                Slog.w(TAG, "Failed trying to unstop package "
16260                        + app.packageName + ": " + e);
16261            }
16262
16263            BackupRecord r = new BackupRecord(ss, app, backupMode);
16264            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16265                    ? new ComponentName(app.packageName, app.backupAgentName)
16266                    : new ComponentName("android", "FullBackupAgent");
16267            // startProcessLocked() returns existing proc's record if it's already running
16268            ProcessRecord proc = startProcessLocked(app.processName, app,
16269                    false, 0, "backup", hostingName, false, false, false);
16270            if (proc == null) {
16271                Slog.e(TAG, "Unable to start backup agent process " + r);
16272                return false;
16273            }
16274
16275            r.app = proc;
16276            mBackupTarget = r;
16277            mBackupAppName = app.packageName;
16278
16279            // Try not to kill the process during backup
16280            updateOomAdjLocked(proc);
16281
16282            // If the process is already attached, schedule the creation of the backup agent now.
16283            // If it is not yet live, this will be done when it attaches to the framework.
16284            if (proc.thread != null) {
16285                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16286                try {
16287                    proc.thread.scheduleCreateBackupAgent(app,
16288                            compatibilityInfoForPackageLocked(app), backupMode);
16289                } catch (RemoteException e) {
16290                    // Will time out on the backup manager side
16291                }
16292            } else {
16293                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16294            }
16295            // Invariants: at this point, the target app process exists and the application
16296            // is either already running or in the process of coming up.  mBackupTarget and
16297            // mBackupAppName describe the app, so that when it binds back to the AM we
16298            // know that it's scheduled for a backup-agent operation.
16299        }
16300
16301        return true;
16302    }
16303
16304    @Override
16305    public void clearPendingBackup() {
16306        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16307        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16308
16309        synchronized (this) {
16310            mBackupTarget = null;
16311            mBackupAppName = null;
16312        }
16313    }
16314
16315    // A backup agent has just come up
16316    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16317        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16318                + " = " + agent);
16319
16320        synchronized(this) {
16321            if (!agentPackageName.equals(mBackupAppName)) {
16322                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16323                return;
16324            }
16325        }
16326
16327        long oldIdent = Binder.clearCallingIdentity();
16328        try {
16329            IBackupManager bm = IBackupManager.Stub.asInterface(
16330                    ServiceManager.getService(Context.BACKUP_SERVICE));
16331            bm.agentConnected(agentPackageName, agent);
16332        } catch (RemoteException e) {
16333            // can't happen; the backup manager service is local
16334        } catch (Exception e) {
16335            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16336            e.printStackTrace();
16337        } finally {
16338            Binder.restoreCallingIdentity(oldIdent);
16339        }
16340    }
16341
16342    // done with this agent
16343    public void unbindBackupAgent(ApplicationInfo appInfo) {
16344        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16345        if (appInfo == null) {
16346            Slog.w(TAG, "unbind backup agent for null app");
16347            return;
16348        }
16349
16350        synchronized(this) {
16351            try {
16352                if (mBackupAppName == null) {
16353                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16354                    return;
16355                }
16356
16357                if (!mBackupAppName.equals(appInfo.packageName)) {
16358                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16359                    return;
16360                }
16361
16362                // Not backing this app up any more; reset its OOM adjustment
16363                final ProcessRecord proc = mBackupTarget.app;
16364                updateOomAdjLocked(proc);
16365
16366                // If the app crashed during backup, 'thread' will be null here
16367                if (proc.thread != null) {
16368                    try {
16369                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16370                                compatibilityInfoForPackageLocked(appInfo));
16371                    } catch (Exception e) {
16372                        Slog.e(TAG, "Exception when unbinding backup agent:");
16373                        e.printStackTrace();
16374                    }
16375                }
16376            } finally {
16377                mBackupTarget = null;
16378                mBackupAppName = null;
16379            }
16380        }
16381    }
16382    // =========================================================
16383    // BROADCASTS
16384    // =========================================================
16385
16386    boolean isPendingBroadcastProcessLocked(int pid) {
16387        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16388                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16389    }
16390
16391    void skipPendingBroadcastLocked(int pid) {
16392            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16393            for (BroadcastQueue queue : mBroadcastQueues) {
16394                queue.skipPendingBroadcastLocked(pid);
16395            }
16396    }
16397
16398    // The app just attached; send any pending broadcasts that it should receive
16399    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16400        boolean didSomething = false;
16401        for (BroadcastQueue queue : mBroadcastQueues) {
16402            didSomething |= queue.sendPendingBroadcastsLocked(app);
16403        }
16404        return didSomething;
16405    }
16406
16407    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16408            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16409        enforceNotIsolatedCaller("registerReceiver");
16410        ArrayList<Intent> stickyIntents = null;
16411        ProcessRecord callerApp = null;
16412        int callingUid;
16413        int callingPid;
16414        synchronized(this) {
16415            if (caller != null) {
16416                callerApp = getRecordForAppLocked(caller);
16417                if (callerApp == null) {
16418                    throw new SecurityException(
16419                            "Unable to find app for caller " + caller
16420                            + " (pid=" + Binder.getCallingPid()
16421                            + ") when registering receiver " + receiver);
16422                }
16423                if (callerApp.info.uid != Process.SYSTEM_UID &&
16424                        !callerApp.pkgList.containsKey(callerPackage) &&
16425                        !"android".equals(callerPackage)) {
16426                    throw new SecurityException("Given caller package " + callerPackage
16427                            + " is not running in process " + callerApp);
16428                }
16429                callingUid = callerApp.info.uid;
16430                callingPid = callerApp.pid;
16431            } else {
16432                callerPackage = null;
16433                callingUid = Binder.getCallingUid();
16434                callingPid = Binder.getCallingPid();
16435            }
16436
16437            userId = handleIncomingUser(callingPid, callingUid, userId,
16438                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16439
16440            Iterator<String> actions = filter.actionsIterator();
16441            if (actions == null) {
16442                ArrayList<String> noAction = new ArrayList<String>(1);
16443                noAction.add(null);
16444                actions = noAction.iterator();
16445            }
16446
16447            // Collect stickies of users
16448            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16449            while (actions.hasNext()) {
16450                String action = actions.next();
16451                for (int id : userIds) {
16452                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16453                    if (stickies != null) {
16454                        ArrayList<Intent> intents = stickies.get(action);
16455                        if (intents != null) {
16456                            if (stickyIntents == null) {
16457                                stickyIntents = new ArrayList<Intent>();
16458                            }
16459                            stickyIntents.addAll(intents);
16460                        }
16461                    }
16462                }
16463            }
16464        }
16465
16466        ArrayList<Intent> allSticky = null;
16467        if (stickyIntents != null) {
16468            final ContentResolver resolver = mContext.getContentResolver();
16469            // Look for any matching sticky broadcasts...
16470            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16471                Intent intent = stickyIntents.get(i);
16472                // If intent has scheme "content", it will need to acccess
16473                // provider that needs to lock mProviderMap in ActivityThread
16474                // and also it may need to wait application response, so we
16475                // cannot lock ActivityManagerService here.
16476                if (filter.match(resolver, intent, true, TAG) >= 0) {
16477                    if (allSticky == null) {
16478                        allSticky = new ArrayList<Intent>();
16479                    }
16480                    allSticky.add(intent);
16481                }
16482            }
16483        }
16484
16485        // The first sticky in the list is returned directly back to the client.
16486        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16487        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16488        if (receiver == null) {
16489            return sticky;
16490        }
16491
16492        synchronized (this) {
16493            if (callerApp != null && (callerApp.thread == null
16494                    || callerApp.thread.asBinder() != caller.asBinder())) {
16495                // Original caller already died
16496                return null;
16497            }
16498            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16499            if (rl == null) {
16500                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16501                        userId, receiver);
16502                if (rl.app != null) {
16503                    rl.app.receivers.add(rl);
16504                } else {
16505                    try {
16506                        receiver.asBinder().linkToDeath(rl, 0);
16507                    } catch (RemoteException e) {
16508                        return sticky;
16509                    }
16510                    rl.linkedToDeath = true;
16511                }
16512                mRegisteredReceivers.put(receiver.asBinder(), rl);
16513            } else if (rl.uid != callingUid) {
16514                throw new IllegalArgumentException(
16515                        "Receiver requested to register for uid " + callingUid
16516                        + " was previously registered for uid " + rl.uid);
16517            } else if (rl.pid != callingPid) {
16518                throw new IllegalArgumentException(
16519                        "Receiver requested to register for pid " + callingPid
16520                        + " was previously registered for pid " + rl.pid);
16521            } else if (rl.userId != userId) {
16522                throw new IllegalArgumentException(
16523                        "Receiver requested to register for user " + userId
16524                        + " was previously registered for user " + rl.userId);
16525            }
16526            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16527                    permission, callingUid, userId);
16528            rl.add(bf);
16529            if (!bf.debugCheck()) {
16530                Slog.w(TAG, "==> For Dynamic broadcast");
16531            }
16532            mReceiverResolver.addFilter(bf);
16533
16534            // Enqueue broadcasts for all existing stickies that match
16535            // this filter.
16536            if (allSticky != null) {
16537                ArrayList receivers = new ArrayList();
16538                receivers.add(bf);
16539
16540                final int stickyCount = allSticky.size();
16541                for (int i = 0; i < stickyCount; i++) {
16542                    Intent intent = allSticky.get(i);
16543                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16544                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16545                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16546                            null, 0, null, null, false, true, true, -1);
16547                    queue.enqueueParallelBroadcastLocked(r);
16548                    queue.scheduleBroadcastsLocked();
16549                }
16550            }
16551
16552            return sticky;
16553        }
16554    }
16555
16556    public void unregisterReceiver(IIntentReceiver receiver) {
16557        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16558
16559        final long origId = Binder.clearCallingIdentity();
16560        try {
16561            boolean doTrim = false;
16562
16563            synchronized(this) {
16564                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16565                if (rl != null) {
16566                    final BroadcastRecord r = rl.curBroadcast;
16567                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16568                        final boolean doNext = r.queue.finishReceiverLocked(
16569                                r, r.resultCode, r.resultData, r.resultExtras,
16570                                r.resultAbort, false);
16571                        if (doNext) {
16572                            doTrim = true;
16573                            r.queue.processNextBroadcast(false);
16574                        }
16575                    }
16576
16577                    if (rl.app != null) {
16578                        rl.app.receivers.remove(rl);
16579                    }
16580                    removeReceiverLocked(rl);
16581                    if (rl.linkedToDeath) {
16582                        rl.linkedToDeath = false;
16583                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16584                    }
16585                }
16586            }
16587
16588            // If we actually concluded any broadcasts, we might now be able
16589            // to trim the recipients' apps from our working set
16590            if (doTrim) {
16591                trimApplications();
16592                return;
16593            }
16594
16595        } finally {
16596            Binder.restoreCallingIdentity(origId);
16597        }
16598    }
16599
16600    void removeReceiverLocked(ReceiverList rl) {
16601        mRegisteredReceivers.remove(rl.receiver.asBinder());
16602        for (int i = rl.size() - 1; i >= 0; i--) {
16603            mReceiverResolver.removeFilter(rl.get(i));
16604        }
16605    }
16606
16607    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16608        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16609            ProcessRecord r = mLruProcesses.get(i);
16610            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16611                try {
16612                    r.thread.dispatchPackageBroadcast(cmd, packages);
16613                } catch (RemoteException ex) {
16614                }
16615            }
16616        }
16617    }
16618
16619    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16620            int callingUid, int[] users) {
16621        List<ResolveInfo> receivers = null;
16622        try {
16623            HashSet<ComponentName> singleUserReceivers = null;
16624            boolean scannedFirstReceivers = false;
16625            for (int user : users) {
16626                // Skip users that have Shell restrictions
16627                if (callingUid == Process.SHELL_UID
16628                        && getUserManagerLocked().hasUserRestriction(
16629                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16630                    continue;
16631                }
16632                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16633                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16634                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16635                    // If this is not the system user, we need to check for
16636                    // any receivers that should be filtered out.
16637                    for (int i=0; i<newReceivers.size(); i++) {
16638                        ResolveInfo ri = newReceivers.get(i);
16639                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16640                            newReceivers.remove(i);
16641                            i--;
16642                        }
16643                    }
16644                }
16645                if (newReceivers != null && newReceivers.size() == 0) {
16646                    newReceivers = null;
16647                }
16648                if (receivers == null) {
16649                    receivers = newReceivers;
16650                } else if (newReceivers != null) {
16651                    // We need to concatenate the additional receivers
16652                    // found with what we have do far.  This would be easy,
16653                    // but we also need to de-dup any receivers that are
16654                    // singleUser.
16655                    if (!scannedFirstReceivers) {
16656                        // Collect any single user receivers we had already retrieved.
16657                        scannedFirstReceivers = true;
16658                        for (int i=0; i<receivers.size(); i++) {
16659                            ResolveInfo ri = receivers.get(i);
16660                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16661                                ComponentName cn = new ComponentName(
16662                                        ri.activityInfo.packageName, ri.activityInfo.name);
16663                                if (singleUserReceivers == null) {
16664                                    singleUserReceivers = new HashSet<ComponentName>();
16665                                }
16666                                singleUserReceivers.add(cn);
16667                            }
16668                        }
16669                    }
16670                    // Add the new results to the existing results, tracking
16671                    // and de-dupping single user receivers.
16672                    for (int i=0; i<newReceivers.size(); i++) {
16673                        ResolveInfo ri = newReceivers.get(i);
16674                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16675                            ComponentName cn = new ComponentName(
16676                                    ri.activityInfo.packageName, ri.activityInfo.name);
16677                            if (singleUserReceivers == null) {
16678                                singleUserReceivers = new HashSet<ComponentName>();
16679                            }
16680                            if (!singleUserReceivers.contains(cn)) {
16681                                singleUserReceivers.add(cn);
16682                                receivers.add(ri);
16683                            }
16684                        } else {
16685                            receivers.add(ri);
16686                        }
16687                    }
16688                }
16689            }
16690        } catch (RemoteException ex) {
16691            // pm is in same process, this will never happen.
16692        }
16693        return receivers;
16694    }
16695
16696    final int broadcastIntentLocked(ProcessRecord callerApp,
16697            String callerPackage, Intent intent, String resolvedType,
16698            IIntentReceiver resultTo, int resultCode, String resultData,
16699            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16700            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16701        intent = new Intent(intent);
16702
16703        // By default broadcasts do not go to stopped apps.
16704        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16705
16706        // If we have not finished booting, don't allow this to launch new processes.
16707        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16708            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16709        }
16710
16711        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16712                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16713                + " ordered=" + ordered + " userid=" + userId);
16714        if ((resultTo != null) && !ordered) {
16715            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16716        }
16717
16718        userId = handleIncomingUser(callingPid, callingUid, userId,
16719                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16720
16721        // Make sure that the user who is receiving this broadcast is running.
16722        // If not, we will just skip it. Make an exception for shutdown broadcasts
16723        // and upgrade steps.
16724
16725        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16726            if ((callingUid != Process.SYSTEM_UID
16727                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16728                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16729                Slog.w(TAG, "Skipping broadcast of " + intent
16730                        + ": user " + userId + " is stopped");
16731                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16732            }
16733        }
16734
16735        BroadcastOptions brOptions = null;
16736        if (options != null) {
16737            brOptions = new BroadcastOptions(options);
16738            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16739                // See if the caller is allowed to do this.  Note we are checking against
16740                // the actual real caller (not whoever provided the operation as say a
16741                // PendingIntent), because that who is actually supplied the arguments.
16742                if (checkComponentPermission(
16743                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16744                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16745                        != PackageManager.PERMISSION_GRANTED) {
16746                    String msg = "Permission Denial: " + intent.getAction()
16747                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16748                            + ", uid=" + callingUid + ")"
16749                            + " requires "
16750                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16751                    Slog.w(TAG, msg);
16752                    throw new SecurityException(msg);
16753                }
16754            }
16755        }
16756
16757        /*
16758         * Prevent non-system code (defined here to be non-persistent
16759         * processes) from sending protected broadcasts.
16760         */
16761        int callingAppId = UserHandle.getAppId(callingUid);
16762        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16763            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16764            || callingAppId == Process.NFC_UID || callingUid == 0) {
16765            // Always okay.
16766        } else if (callerApp == null || !callerApp.persistent) {
16767            try {
16768                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16769                        intent.getAction())) {
16770                    String msg = "Permission Denial: not allowed to send broadcast "
16771                            + intent.getAction() + " from pid="
16772                            + callingPid + ", uid=" + callingUid;
16773                    Slog.w(TAG, msg);
16774                    throw new SecurityException(msg);
16775                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16776                    // Special case for compatibility: we don't want apps to send this,
16777                    // but historically it has not been protected and apps may be using it
16778                    // to poke their own app widget.  So, instead of making it protected,
16779                    // just limit it to the caller.
16780                    if (callerApp == null) {
16781                        String msg = "Permission Denial: not allowed to send broadcast "
16782                                + intent.getAction() + " from unknown caller.";
16783                        Slog.w(TAG, msg);
16784                        throw new SecurityException(msg);
16785                    } else if (intent.getComponent() != null) {
16786                        // They are good enough to send to an explicit component...  verify
16787                        // it is being sent to the calling app.
16788                        if (!intent.getComponent().getPackageName().equals(
16789                                callerApp.info.packageName)) {
16790                            String msg = "Permission Denial: not allowed to send broadcast "
16791                                    + intent.getAction() + " to "
16792                                    + intent.getComponent().getPackageName() + " from "
16793                                    + callerApp.info.packageName;
16794                            Slog.w(TAG, msg);
16795                            throw new SecurityException(msg);
16796                        }
16797                    } else {
16798                        // Limit broadcast to their own package.
16799                        intent.setPackage(callerApp.info.packageName);
16800                    }
16801                }
16802            } catch (RemoteException e) {
16803                Slog.w(TAG, "Remote exception", e);
16804                return ActivityManager.BROADCAST_SUCCESS;
16805            }
16806        }
16807
16808        final String action = intent.getAction();
16809        if (action != null) {
16810            switch (action) {
16811                case Intent.ACTION_UID_REMOVED:
16812                case Intent.ACTION_PACKAGE_REMOVED:
16813                case Intent.ACTION_PACKAGE_CHANGED:
16814                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16815                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16816                    // Handle special intents: if this broadcast is from the package
16817                    // manager about a package being removed, we need to remove all of
16818                    // its activities from the history stack.
16819                    if (checkComponentPermission(
16820                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16821                            callingPid, callingUid, -1, true)
16822                            != PackageManager.PERMISSION_GRANTED) {
16823                        String msg = "Permission Denial: " + intent.getAction()
16824                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16825                                + ", uid=" + callingUid + ")"
16826                                + " requires "
16827                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16828                        Slog.w(TAG, msg);
16829                        throw new SecurityException(msg);
16830                    }
16831                    switch (action) {
16832                        case Intent.ACTION_UID_REMOVED:
16833                            final Bundle intentExtras = intent.getExtras();
16834                            final int uid = intentExtras != null
16835                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16836                            if (uid >= 0) {
16837                                mBatteryStatsService.removeUid(uid);
16838                                mAppOpsService.uidRemoved(uid);
16839                            }
16840                            break;
16841                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16842                            // If resources are unavailable just force stop all those packages
16843                            // and flush the attribute cache as well.
16844                            String list[] =
16845                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16846                            if (list != null && list.length > 0) {
16847                                for (int i = 0; i < list.length; i++) {
16848                                    forceStopPackageLocked(list[i], -1, false, true, true,
16849                                            false, false, userId, "storage unmount");
16850                                }
16851                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16852                                sendPackageBroadcastLocked(
16853                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16854                                        userId);
16855                            }
16856                            break;
16857                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16858                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16859                            break;
16860                        case Intent.ACTION_PACKAGE_REMOVED:
16861                        case Intent.ACTION_PACKAGE_CHANGED:
16862                            Uri data = intent.getData();
16863                            String ssp;
16864                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16865                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16866                                boolean fullUninstall = removed &&
16867                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16868                                final boolean killProcess =
16869                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16870                                if (killProcess) {
16871                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16872                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16873                                            false, true, true, false, fullUninstall, userId,
16874                                            removed ? "pkg removed" : "pkg changed");
16875                                }
16876                                if (removed) {
16877                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16878                                            new String[] {ssp}, userId);
16879                                    if (fullUninstall) {
16880                                        mAppOpsService.packageRemoved(
16881                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16882
16883                                        // Remove all permissions granted from/to this package
16884                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16885
16886                                        removeTasksByPackageNameLocked(ssp, userId);
16887                                        mBatteryStatsService.notePackageUninstalled(ssp);
16888                                    }
16889                                } else {
16890                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16891                                            intent.getStringArrayExtra(
16892                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16893                                }
16894                            }
16895                            break;
16896                    }
16897                    break;
16898                case Intent.ACTION_PACKAGE_ADDED:
16899                    // Special case for adding a package: by default turn on compatibility mode.
16900                    Uri data = intent.getData();
16901                    String ssp;
16902                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16903                        final boolean replacing =
16904                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16905                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16906
16907                        try {
16908                            ApplicationInfo ai = AppGlobals.getPackageManager().
16909                                    getApplicationInfo(ssp, 0, 0);
16910                            mBatteryStatsService.notePackageInstalled(ssp,
16911                                    ai != null ? ai.versionCode : 0);
16912                        } catch (RemoteException e) {
16913                        }
16914                    }
16915                    break;
16916                case Intent.ACTION_TIMEZONE_CHANGED:
16917                    // If this is the time zone changed action, queue up a message that will reset
16918                    // the timezone of all currently running processes. This message will get
16919                    // queued up before the broadcast happens.
16920                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16921                    break;
16922                case Intent.ACTION_TIME_CHANGED:
16923                    // If the user set the time, let all running processes know.
16924                    final int is24Hour =
16925                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16926                                    : 0;
16927                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16928                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16929                    synchronized (stats) {
16930                        stats.noteCurrentTimeChangedLocked();
16931                    }
16932                    break;
16933                case Intent.ACTION_CLEAR_DNS_CACHE:
16934                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16935                    break;
16936                case Proxy.PROXY_CHANGE_ACTION:
16937                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16938                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16939                    break;
16940            }
16941        }
16942
16943        // Add to the sticky list if requested.
16944        if (sticky) {
16945            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16946                    callingPid, callingUid)
16947                    != PackageManager.PERMISSION_GRANTED) {
16948                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16949                        + callingPid + ", uid=" + callingUid
16950                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16951                Slog.w(TAG, msg);
16952                throw new SecurityException(msg);
16953            }
16954            if (requiredPermissions != null && requiredPermissions.length > 0) {
16955                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16956                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16957                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16958            }
16959            if (intent.getComponent() != null) {
16960                throw new SecurityException(
16961                        "Sticky broadcasts can't target a specific component");
16962            }
16963            // We use userId directly here, since the "all" target is maintained
16964            // as a separate set of sticky broadcasts.
16965            if (userId != UserHandle.USER_ALL) {
16966                // But first, if this is not a broadcast to all users, then
16967                // make sure it doesn't conflict with an existing broadcast to
16968                // all users.
16969                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16970                        UserHandle.USER_ALL);
16971                if (stickies != null) {
16972                    ArrayList<Intent> list = stickies.get(intent.getAction());
16973                    if (list != null) {
16974                        int N = list.size();
16975                        int i;
16976                        for (i=0; i<N; i++) {
16977                            if (intent.filterEquals(list.get(i))) {
16978                                throw new IllegalArgumentException(
16979                                        "Sticky broadcast " + intent + " for user "
16980                                        + userId + " conflicts with existing global broadcast");
16981                            }
16982                        }
16983                    }
16984                }
16985            }
16986            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16987            if (stickies == null) {
16988                stickies = new ArrayMap<>();
16989                mStickyBroadcasts.put(userId, stickies);
16990            }
16991            ArrayList<Intent> list = stickies.get(intent.getAction());
16992            if (list == null) {
16993                list = new ArrayList<>();
16994                stickies.put(intent.getAction(), list);
16995            }
16996            final int stickiesCount = list.size();
16997            int i;
16998            for (i = 0; i < stickiesCount; i++) {
16999                if (intent.filterEquals(list.get(i))) {
17000                    // This sticky already exists, replace it.
17001                    list.set(i, new Intent(intent));
17002                    break;
17003                }
17004            }
17005            if (i >= stickiesCount) {
17006                list.add(new Intent(intent));
17007            }
17008        }
17009
17010        int[] users;
17011        if (userId == UserHandle.USER_ALL) {
17012            // Caller wants broadcast to go to all started users.
17013            users = mUserController.getStartedUserArrayLocked();
17014        } else {
17015            // Caller wants broadcast to go to one specific user.
17016            users = new int[] {userId};
17017        }
17018
17019        // Figure out who all will receive this broadcast.
17020        List receivers = null;
17021        List<BroadcastFilter> registeredReceivers = null;
17022        // Need to resolve the intent to interested receivers...
17023        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17024                 == 0) {
17025            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17026        }
17027        if (intent.getComponent() == null) {
17028            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17029                // Query one target user at a time, excluding shell-restricted users
17030                UserManagerService ums = getUserManagerLocked();
17031                for (int i = 0; i < users.length; i++) {
17032                    if (ums.hasUserRestriction(
17033                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17034                        continue;
17035                    }
17036                    List<BroadcastFilter> registeredReceiversForUser =
17037                            mReceiverResolver.queryIntent(intent,
17038                                    resolvedType, false, users[i]);
17039                    if (registeredReceivers == null) {
17040                        registeredReceivers = registeredReceiversForUser;
17041                    } else if (registeredReceiversForUser != null) {
17042                        registeredReceivers.addAll(registeredReceiversForUser);
17043                    }
17044                }
17045            } else {
17046                registeredReceivers = mReceiverResolver.queryIntent(intent,
17047                        resolvedType, false, userId);
17048            }
17049        }
17050
17051        final boolean replacePending =
17052                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17053
17054        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17055                + " replacePending=" + replacePending);
17056
17057        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17058        if (!ordered && NR > 0) {
17059            // If we are not serializing this broadcast, then send the
17060            // registered receivers separately so they don't wait for the
17061            // components to be launched.
17062            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17063            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17064                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17065                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17066                    resultExtras, ordered, sticky, false, userId);
17067            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17068            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17069            if (!replaced) {
17070                queue.enqueueParallelBroadcastLocked(r);
17071                queue.scheduleBroadcastsLocked();
17072            }
17073            registeredReceivers = null;
17074            NR = 0;
17075        }
17076
17077        // Merge into one list.
17078        int ir = 0;
17079        if (receivers != null) {
17080            // A special case for PACKAGE_ADDED: do not allow the package
17081            // being added to see this broadcast.  This prevents them from
17082            // using this as a back door to get run as soon as they are
17083            // installed.  Maybe in the future we want to have a special install
17084            // broadcast or such for apps, but we'd like to deliberately make
17085            // this decision.
17086            String skipPackages[] = null;
17087            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17088                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17089                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17090                Uri data = intent.getData();
17091                if (data != null) {
17092                    String pkgName = data.getSchemeSpecificPart();
17093                    if (pkgName != null) {
17094                        skipPackages = new String[] { pkgName };
17095                    }
17096                }
17097            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17098                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17099            }
17100            if (skipPackages != null && (skipPackages.length > 0)) {
17101                for (String skipPackage : skipPackages) {
17102                    if (skipPackage != null) {
17103                        int NT = receivers.size();
17104                        for (int it=0; it<NT; it++) {
17105                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17106                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17107                                receivers.remove(it);
17108                                it--;
17109                                NT--;
17110                            }
17111                        }
17112                    }
17113                }
17114            }
17115
17116            int NT = receivers != null ? receivers.size() : 0;
17117            int it = 0;
17118            ResolveInfo curt = null;
17119            BroadcastFilter curr = null;
17120            while (it < NT && ir < NR) {
17121                if (curt == null) {
17122                    curt = (ResolveInfo)receivers.get(it);
17123                }
17124                if (curr == null) {
17125                    curr = registeredReceivers.get(ir);
17126                }
17127                if (curr.getPriority() >= curt.priority) {
17128                    // Insert this broadcast record into the final list.
17129                    receivers.add(it, curr);
17130                    ir++;
17131                    curr = null;
17132                    it++;
17133                    NT++;
17134                } else {
17135                    // Skip to the next ResolveInfo in the final list.
17136                    it++;
17137                    curt = null;
17138                }
17139            }
17140        }
17141        while (ir < NR) {
17142            if (receivers == null) {
17143                receivers = new ArrayList();
17144            }
17145            receivers.add(registeredReceivers.get(ir));
17146            ir++;
17147        }
17148
17149        if ((receivers != null && receivers.size() > 0)
17150                || resultTo != null) {
17151            BroadcastQueue queue = broadcastQueueForIntent(intent);
17152            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17153                    callerPackage, callingPid, callingUid, resolvedType,
17154                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17155                    resultData, resultExtras, ordered, sticky, false, userId);
17156
17157            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17158                    + ": prev had " + queue.mOrderedBroadcasts.size());
17159            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17160                    "Enqueueing broadcast " + r.intent.getAction());
17161
17162            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17163            if (!replaced) {
17164                queue.enqueueOrderedBroadcastLocked(r);
17165                queue.scheduleBroadcastsLocked();
17166            }
17167        }
17168
17169        return ActivityManager.BROADCAST_SUCCESS;
17170    }
17171
17172    final Intent verifyBroadcastLocked(Intent intent) {
17173        // Refuse possible leaked file descriptors
17174        if (intent != null && intent.hasFileDescriptors() == true) {
17175            throw new IllegalArgumentException("File descriptors passed in Intent");
17176        }
17177
17178        int flags = intent.getFlags();
17179
17180        if (!mProcessesReady) {
17181            // if the caller really truly claims to know what they're doing, go
17182            // ahead and allow the broadcast without launching any receivers
17183            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17184                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17185            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17186                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17187                        + " before boot completion");
17188                throw new IllegalStateException("Cannot broadcast before boot completed");
17189            }
17190        }
17191
17192        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17193            throw new IllegalArgumentException(
17194                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17195        }
17196
17197        return intent;
17198    }
17199
17200    public final int broadcastIntent(IApplicationThread caller,
17201            Intent intent, String resolvedType, IIntentReceiver resultTo,
17202            int resultCode, String resultData, Bundle resultExtras,
17203            String[] requiredPermissions, int appOp, Bundle options,
17204            boolean serialized, boolean sticky, int userId) {
17205        enforceNotIsolatedCaller("broadcastIntent");
17206        synchronized(this) {
17207            intent = verifyBroadcastLocked(intent);
17208
17209            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17210            final int callingPid = Binder.getCallingPid();
17211            final int callingUid = Binder.getCallingUid();
17212            final long origId = Binder.clearCallingIdentity();
17213            int res = broadcastIntentLocked(callerApp,
17214                    callerApp != null ? callerApp.info.packageName : null,
17215                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17216                    requiredPermissions, appOp, null, serialized, sticky,
17217                    callingPid, callingUid, userId);
17218            Binder.restoreCallingIdentity(origId);
17219            return res;
17220        }
17221    }
17222
17223
17224    int broadcastIntentInPackage(String packageName, int uid,
17225            Intent intent, String resolvedType, IIntentReceiver resultTo,
17226            int resultCode, String resultData, Bundle resultExtras,
17227            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17228            int userId) {
17229        synchronized(this) {
17230            intent = verifyBroadcastLocked(intent);
17231
17232            final long origId = Binder.clearCallingIdentity();
17233            String[] requiredPermissions = requiredPermission == null ? null
17234                    : new String[] {requiredPermission};
17235            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17236                    resultTo, resultCode, resultData, resultExtras,
17237                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17238                    sticky, -1, uid, userId);
17239            Binder.restoreCallingIdentity(origId);
17240            return res;
17241        }
17242    }
17243
17244    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17245        // Refuse possible leaked file descriptors
17246        if (intent != null && intent.hasFileDescriptors() == true) {
17247            throw new IllegalArgumentException("File descriptors passed in Intent");
17248        }
17249
17250        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17251                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17252
17253        synchronized(this) {
17254            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17255                    != PackageManager.PERMISSION_GRANTED) {
17256                String msg = "Permission Denial: unbroadcastIntent() from pid="
17257                        + Binder.getCallingPid()
17258                        + ", uid=" + Binder.getCallingUid()
17259                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17260                Slog.w(TAG, msg);
17261                throw new SecurityException(msg);
17262            }
17263            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17264            if (stickies != null) {
17265                ArrayList<Intent> list = stickies.get(intent.getAction());
17266                if (list != null) {
17267                    int N = list.size();
17268                    int i;
17269                    for (i=0; i<N; i++) {
17270                        if (intent.filterEquals(list.get(i))) {
17271                            list.remove(i);
17272                            break;
17273                        }
17274                    }
17275                    if (list.size() <= 0) {
17276                        stickies.remove(intent.getAction());
17277                    }
17278                }
17279                if (stickies.size() <= 0) {
17280                    mStickyBroadcasts.remove(userId);
17281                }
17282            }
17283        }
17284    }
17285
17286    void backgroundServicesFinishedLocked(int userId) {
17287        for (BroadcastQueue queue : mBroadcastQueues) {
17288            queue.backgroundServicesFinishedLocked(userId);
17289        }
17290    }
17291
17292    public void finishReceiver(IBinder who, int resultCode, String resultData,
17293            Bundle resultExtras, boolean resultAbort, int flags) {
17294        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17295
17296        // Refuse possible leaked file descriptors
17297        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17298            throw new IllegalArgumentException("File descriptors passed in Bundle");
17299        }
17300
17301        final long origId = Binder.clearCallingIdentity();
17302        try {
17303            boolean doNext = false;
17304            BroadcastRecord r;
17305
17306            synchronized(this) {
17307                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17308                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17309                r = queue.getMatchingOrderedReceiver(who);
17310                if (r != null) {
17311                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17312                        resultData, resultExtras, resultAbort, true);
17313                }
17314            }
17315
17316            if (doNext) {
17317                r.queue.processNextBroadcast(false);
17318            }
17319            trimApplications();
17320        } finally {
17321            Binder.restoreCallingIdentity(origId);
17322        }
17323    }
17324
17325    // =========================================================
17326    // INSTRUMENTATION
17327    // =========================================================
17328
17329    public boolean startInstrumentation(ComponentName className,
17330            String profileFile, int flags, Bundle arguments,
17331            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17332            int userId, String abiOverride) {
17333        enforceNotIsolatedCaller("startInstrumentation");
17334        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17335                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17336        // Refuse possible leaked file descriptors
17337        if (arguments != null && arguments.hasFileDescriptors()) {
17338            throw new IllegalArgumentException("File descriptors passed in Bundle");
17339        }
17340
17341        synchronized(this) {
17342            InstrumentationInfo ii = null;
17343            ApplicationInfo ai = null;
17344            try {
17345                ii = mContext.getPackageManager().getInstrumentationInfo(
17346                    className, STOCK_PM_FLAGS);
17347                ai = AppGlobals.getPackageManager().getApplicationInfo(
17348                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17349            } catch (PackageManager.NameNotFoundException e) {
17350            } catch (RemoteException e) {
17351            }
17352            if (ii == null) {
17353                reportStartInstrumentationFailure(watcher, className,
17354                        "Unable to find instrumentation info for: " + className);
17355                return false;
17356            }
17357            if (ai == null) {
17358                reportStartInstrumentationFailure(watcher, className,
17359                        "Unable to find instrumentation target package: " + ii.targetPackage);
17360                return false;
17361            }
17362
17363            int match = mContext.getPackageManager().checkSignatures(
17364                    ii.targetPackage, ii.packageName);
17365            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17366                String msg = "Permission Denial: starting instrumentation "
17367                        + className + " from pid="
17368                        + Binder.getCallingPid()
17369                        + ", uid=" + Binder.getCallingPid()
17370                        + " not allowed because package " + ii.packageName
17371                        + " does not have a signature matching the target "
17372                        + ii.targetPackage;
17373                reportStartInstrumentationFailure(watcher, className, msg);
17374                throw new SecurityException(msg);
17375            }
17376
17377            final long origId = Binder.clearCallingIdentity();
17378            // Instrumentation can kill and relaunch even persistent processes
17379            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17380                    "start instr");
17381            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17382            app.instrumentationClass = className;
17383            app.instrumentationInfo = ai;
17384            app.instrumentationProfileFile = profileFile;
17385            app.instrumentationArguments = arguments;
17386            app.instrumentationWatcher = watcher;
17387            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17388            app.instrumentationResultClass = className;
17389            Binder.restoreCallingIdentity(origId);
17390        }
17391
17392        return true;
17393    }
17394
17395    /**
17396     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17397     * error to the logs, but if somebody is watching, send the report there too.  This enables
17398     * the "am" command to report errors with more information.
17399     *
17400     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17401     * @param cn The component name of the instrumentation.
17402     * @param report The error report.
17403     */
17404    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17405            ComponentName cn, String report) {
17406        Slog.w(TAG, report);
17407        try {
17408            if (watcher != null) {
17409                Bundle results = new Bundle();
17410                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17411                results.putString("Error", report);
17412                watcher.instrumentationStatus(cn, -1, results);
17413            }
17414        } catch (RemoteException e) {
17415            Slog.w(TAG, e);
17416        }
17417    }
17418
17419    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17420        if (app.instrumentationWatcher != null) {
17421            try {
17422                // NOTE:  IInstrumentationWatcher *must* be oneway here
17423                app.instrumentationWatcher.instrumentationFinished(
17424                    app.instrumentationClass,
17425                    resultCode,
17426                    results);
17427            } catch (RemoteException e) {
17428            }
17429        }
17430
17431        // Can't call out of the system process with a lock held, so post a message.
17432        if (app.instrumentationUiAutomationConnection != null) {
17433            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17434                    app.instrumentationUiAutomationConnection).sendToTarget();
17435        }
17436
17437        app.instrumentationWatcher = null;
17438        app.instrumentationUiAutomationConnection = null;
17439        app.instrumentationClass = null;
17440        app.instrumentationInfo = null;
17441        app.instrumentationProfileFile = null;
17442        app.instrumentationArguments = null;
17443
17444        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17445                "finished inst");
17446    }
17447
17448    public void finishInstrumentation(IApplicationThread target,
17449            int resultCode, Bundle results) {
17450        int userId = UserHandle.getCallingUserId();
17451        // Refuse possible leaked file descriptors
17452        if (results != null && results.hasFileDescriptors()) {
17453            throw new IllegalArgumentException("File descriptors passed in Intent");
17454        }
17455
17456        synchronized(this) {
17457            ProcessRecord app = getRecordForAppLocked(target);
17458            if (app == null) {
17459                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17460                return;
17461            }
17462            final long origId = Binder.clearCallingIdentity();
17463            finishInstrumentationLocked(app, resultCode, results);
17464            Binder.restoreCallingIdentity(origId);
17465        }
17466    }
17467
17468    // =========================================================
17469    // CONFIGURATION
17470    // =========================================================
17471
17472    public ConfigurationInfo getDeviceConfigurationInfo() {
17473        ConfigurationInfo config = new ConfigurationInfo();
17474        synchronized (this) {
17475            config.reqTouchScreen = mConfiguration.touchscreen;
17476            config.reqKeyboardType = mConfiguration.keyboard;
17477            config.reqNavigation = mConfiguration.navigation;
17478            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17479                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17480                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17481            }
17482            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17483                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17484                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17485            }
17486            config.reqGlEsVersion = GL_ES_VERSION;
17487        }
17488        return config;
17489    }
17490
17491    ActivityStack getFocusedStack() {
17492        return mStackSupervisor.getFocusedStack();
17493    }
17494
17495    @Override
17496    public int getFocusedStackId() throws RemoteException {
17497        ActivityStack focusedStack = getFocusedStack();
17498        if (focusedStack != null) {
17499            return focusedStack.getStackId();
17500        }
17501        return -1;
17502    }
17503
17504    public Configuration getConfiguration() {
17505        Configuration ci;
17506        synchronized(this) {
17507            ci = new Configuration(mConfiguration);
17508            ci.userSetLocale = false;
17509        }
17510        return ci;
17511    }
17512
17513    @Override
17514    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17516                "suppressResizeConfigChanges()");
17517        synchronized (this) {
17518            mSuppressResizeConfigChanges = suppress;
17519        }
17520    }
17521
17522    @Override
17523    public void removeStack(int stackId) {
17524        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17525                "detahStack()");
17526        if (stackId == HOME_STACK_ID) {
17527            throw new IllegalArgumentException("Removing home stack is not allowed.");
17528        }
17529        synchronized (this) {
17530            ActivityStack stack = mStackSupervisor.getStack(stackId);
17531            if (stack != null) {
17532                ArrayList<TaskRecord> tasks = stack.getAllTasks();
17533                for (int i = tasks.size() - 1; i >= 0; i--) {
17534                    removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
17535                            !REMOVE_FROM_RECENTS);
17536                }
17537            }
17538        }
17539    }
17540
17541    @Override
17542    public void updatePersistentConfiguration(Configuration values) {
17543        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17544                "updateConfiguration()");
17545        enforceWriteSettingsPermission("updateConfiguration()");
17546        if (values == null) {
17547            throw new NullPointerException("Configuration must not be null");
17548        }
17549
17550        int userId = UserHandle.getCallingUserId();
17551
17552        synchronized(this) {
17553            final long origId = Binder.clearCallingIdentity();
17554            updateConfigurationLocked(values, null, false, true, userId);
17555            Binder.restoreCallingIdentity(origId);
17556        }
17557    }
17558
17559    private void enforceWriteSettingsPermission(String func) {
17560        int uid = Binder.getCallingUid();
17561        if (uid == Process.ROOT_UID) {
17562            return;
17563        }
17564
17565        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17566                Settings.getPackageNameForUid(mContext, uid), false)) {
17567            return;
17568        }
17569
17570        String msg = "Permission Denial: " + func + " from pid="
17571                + Binder.getCallingPid()
17572                + ", uid=" + uid
17573                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17574        Slog.w(TAG, msg);
17575        throw new SecurityException(msg);
17576    }
17577
17578    public void updateConfiguration(Configuration values) {
17579        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17580                "updateConfiguration()");
17581
17582        synchronized(this) {
17583            if (values == null && mWindowManager != null) {
17584                // sentinel: fetch the current configuration from the window manager
17585                values = mWindowManager.computeNewConfiguration();
17586            }
17587
17588            if (mWindowManager != null) {
17589                mProcessList.applyDisplaySize(mWindowManager);
17590            }
17591
17592            final long origId = Binder.clearCallingIdentity();
17593            if (values != null) {
17594                Settings.System.clearConfiguration(values);
17595            }
17596            updateConfigurationLocked(values, null, false);
17597            Binder.restoreCallingIdentity(origId);
17598        }
17599    }
17600    void updateUserConfigurationLocked() {
17601        Configuration configuration = new Configuration(mConfiguration);
17602        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17603                mUserController.mCurrentUserId);
17604        updateConfigurationLocked(configuration, null, false);
17605    }
17606
17607    boolean updateConfigurationLocked(Configuration values,
17608            ActivityRecord starting, boolean initLocale) {
17609        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17610        return updateConfigurationLocked(values, starting, initLocale, false,
17611                UserHandle.USER_NULL);
17612    }
17613
17614    /**
17615     * Do either or both things: (1) change the current configuration, and (2)
17616     * make sure the given activity is running with the (now) current
17617     * configuration.  Returns true if the activity has been left running, or
17618     * false if <var>starting</var> is being destroyed to match the new
17619     * configuration.
17620     *
17621     * @param userId is only used when persistent parameter is set to true to persist configuration
17622     *               for that particular user
17623     */
17624    boolean updateConfigurationLocked(Configuration values,
17625            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17626        int changes = 0;
17627
17628        if (values != null) {
17629            Configuration newConfig = new Configuration(mConfiguration);
17630            changes = newConfig.updateFrom(values);
17631            if (changes != 0) {
17632                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17633                        "Updating configuration to: " + values);
17634
17635                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17636
17637                if (!initLocale && values.locale != null && values.userSetLocale) {
17638                    final String languageTag = values.locale.toLanguageTag();
17639                    SystemProperties.set("persist.sys.locale", languageTag);
17640                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17641                            values.locale));
17642                }
17643
17644                mConfigurationSeq++;
17645                if (mConfigurationSeq <= 0) {
17646                    mConfigurationSeq = 1;
17647                }
17648                newConfig.seq = mConfigurationSeq;
17649                mConfiguration = newConfig;
17650                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17651                mUsageStatsService.reportConfigurationChange(newConfig,
17652                        mUserController.mCurrentUserId);
17653                //mUsageStatsService.noteStartConfig(newConfig);
17654
17655                final Configuration configCopy = new Configuration(mConfiguration);
17656
17657                // TODO: If our config changes, should we auto dismiss any currently
17658                // showing dialogs?
17659                mShowDialogs = shouldShowDialogs(newConfig);
17660
17661                AttributeCache ac = AttributeCache.instance();
17662                if (ac != null) {
17663                    ac.updateConfiguration(configCopy);
17664                }
17665
17666                // Make sure all resources in our process are updated
17667                // right now, so that anyone who is going to retrieve
17668                // resource values after we return will be sure to get
17669                // the new ones.  This is especially important during
17670                // boot, where the first config change needs to guarantee
17671                // all resources have that config before following boot
17672                // code is executed.
17673                mSystemThread.applyConfigurationToResources(configCopy);
17674
17675                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17676                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17677                    msg.obj = new Configuration(configCopy);
17678                    msg.arg1 = userId;
17679                    mHandler.sendMessage(msg);
17680                }
17681
17682                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17683                    ProcessRecord app = mLruProcesses.get(i);
17684                    try {
17685                        if (app.thread != null) {
17686                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17687                                    + app.processName + " new config " + mConfiguration);
17688                            app.thread.scheduleConfigurationChanged(configCopy);
17689                        }
17690                    } catch (Exception e) {
17691                    }
17692                }
17693                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17694                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17695                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17696                        | Intent.FLAG_RECEIVER_FOREGROUND);
17697                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17698                        null, AppOpsManager.OP_NONE, null, false, false,
17699                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17700                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17701                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17702                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17703                    if (!mProcessesReady) {
17704                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17705                    }
17706                    broadcastIntentLocked(null, null, intent,
17707                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17708                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17709                }
17710            }
17711        }
17712
17713        boolean kept = true;
17714        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17715        // mainStack is null during startup.
17716        if (mainStack != null) {
17717            if (changes != 0 && starting == null) {
17718                // If the configuration changed, and the caller is not already
17719                // in the process of starting an activity, then find the top
17720                // activity to check if its configuration needs to change.
17721                starting = mainStack.topRunningActivityLocked();
17722            }
17723
17724            if (starting != null) {
17725                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17726                // And we need to make sure at this point that all other activities
17727                // are made visible with the correct configuration.
17728                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17729                        !PRESERVE_WINDOWS);
17730            }
17731        }
17732
17733        if (values != null && mWindowManager != null) {
17734            mWindowManager.setNewConfiguration(mConfiguration);
17735        }
17736
17737        return kept;
17738    }
17739
17740    /**
17741     * Decide based on the configuration whether we should shouw the ANR,
17742     * crash, etc dialogs.  The idea is that if there is no affordnace to
17743     * press the on-screen buttons, we shouldn't show the dialog.
17744     *
17745     * A thought: SystemUI might also want to get told about this, the Power
17746     * dialog / global actions also might want different behaviors.
17747     */
17748    private static final boolean shouldShowDialogs(Configuration config) {
17749        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17750                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17751                && config.navigation == Configuration.NAVIGATION_NONAV);
17752    }
17753
17754    @Override
17755    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17756        synchronized (this) {
17757            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17758            if (srec != null) {
17759                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17760            }
17761        }
17762        return false;
17763    }
17764
17765    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17766            Intent resultData) {
17767
17768        synchronized (this) {
17769            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17770            if (r != null) {
17771                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17772            }
17773            return false;
17774        }
17775    }
17776
17777    public int getLaunchedFromUid(IBinder activityToken) {
17778        ActivityRecord srec;
17779        synchronized (this) {
17780            srec = ActivityRecord.forTokenLocked(activityToken);
17781        }
17782        if (srec == null) {
17783            return -1;
17784        }
17785        return srec.launchedFromUid;
17786    }
17787
17788    public String getLaunchedFromPackage(IBinder activityToken) {
17789        ActivityRecord srec;
17790        synchronized (this) {
17791            srec = ActivityRecord.forTokenLocked(activityToken);
17792        }
17793        if (srec == null) {
17794            return null;
17795        }
17796        return srec.launchedFromPackage;
17797    }
17798
17799    // =========================================================
17800    // LIFETIME MANAGEMENT
17801    // =========================================================
17802
17803    // Returns which broadcast queue the app is the current [or imminent] receiver
17804    // on, or 'null' if the app is not an active broadcast recipient.
17805    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17806        BroadcastRecord r = app.curReceiver;
17807        if (r != null) {
17808            return r.queue;
17809        }
17810
17811        // It's not the current receiver, but it might be starting up to become one
17812        synchronized (this) {
17813            for (BroadcastQueue queue : mBroadcastQueues) {
17814                r = queue.mPendingBroadcast;
17815                if (r != null && r.curApp == app) {
17816                    // found it; report which queue it's in
17817                    return queue;
17818                }
17819            }
17820        }
17821
17822        return null;
17823    }
17824
17825    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17826            ComponentName targetComponent, String targetProcess) {
17827        if (!mTrackingAssociations) {
17828            return null;
17829        }
17830        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17831                = mAssociations.get(targetUid);
17832        if (components == null) {
17833            components = new ArrayMap<>();
17834            mAssociations.put(targetUid, components);
17835        }
17836        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17837        if (sourceUids == null) {
17838            sourceUids = new SparseArray<>();
17839            components.put(targetComponent, sourceUids);
17840        }
17841        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17842        if (sourceProcesses == null) {
17843            sourceProcesses = new ArrayMap<>();
17844            sourceUids.put(sourceUid, sourceProcesses);
17845        }
17846        Association ass = sourceProcesses.get(sourceProcess);
17847        if (ass == null) {
17848            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17849                    targetProcess);
17850            sourceProcesses.put(sourceProcess, ass);
17851        }
17852        ass.mCount++;
17853        ass.mNesting++;
17854        if (ass.mNesting == 1) {
17855            ass.mStartTime = SystemClock.uptimeMillis();
17856        }
17857        return ass;
17858    }
17859
17860    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17861            ComponentName targetComponent) {
17862        if (!mTrackingAssociations) {
17863            return;
17864        }
17865        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17866                = mAssociations.get(targetUid);
17867        if (components == null) {
17868            return;
17869        }
17870        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17871        if (sourceUids == null) {
17872            return;
17873        }
17874        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17875        if (sourceProcesses == null) {
17876            return;
17877        }
17878        Association ass = sourceProcesses.get(sourceProcess);
17879        if (ass == null || ass.mNesting <= 0) {
17880            return;
17881        }
17882        ass.mNesting--;
17883        if (ass.mNesting == 0) {
17884            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17885        }
17886    }
17887
17888    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17889            boolean doingAll, long now) {
17890        if (mAdjSeq == app.adjSeq) {
17891            // This adjustment has already been computed.
17892            return app.curRawAdj;
17893        }
17894
17895        if (app.thread == null) {
17896            app.adjSeq = mAdjSeq;
17897            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17898            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17899            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17900        }
17901
17902        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17903        app.adjSource = null;
17904        app.adjTarget = null;
17905        app.empty = false;
17906        app.cached = false;
17907
17908        final int activitiesSize = app.activities.size();
17909
17910        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17911            // The max adjustment doesn't allow this app to be anything
17912            // below foreground, so it is not worth doing work for it.
17913            app.adjType = "fixed";
17914            app.adjSeq = mAdjSeq;
17915            app.curRawAdj = app.maxAdj;
17916            app.foregroundActivities = false;
17917            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17918            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17919            // System processes can do UI, and when they do we want to have
17920            // them trim their memory after the user leaves the UI.  To
17921            // facilitate this, here we need to determine whether or not it
17922            // is currently showing UI.
17923            app.systemNoUi = true;
17924            if (app == TOP_APP) {
17925                app.systemNoUi = false;
17926            } else if (activitiesSize > 0) {
17927                for (int j = 0; j < activitiesSize; j++) {
17928                    final ActivityRecord r = app.activities.get(j);
17929                    if (r.visible) {
17930                        app.systemNoUi = false;
17931                    }
17932                }
17933            }
17934            if (!app.systemNoUi) {
17935                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17936            }
17937            return (app.curAdj=app.maxAdj);
17938        }
17939
17940        app.systemNoUi = false;
17941
17942        final int PROCESS_STATE_TOP = mTopProcessState;
17943
17944        // Determine the importance of the process, starting with most
17945        // important to least, and assign an appropriate OOM adjustment.
17946        int adj;
17947        int schedGroup;
17948        int procState;
17949        boolean foregroundActivities = false;
17950        BroadcastQueue queue;
17951        if (app == TOP_APP) {
17952            // The last app on the list is the foreground app.
17953            adj = ProcessList.FOREGROUND_APP_ADJ;
17954            schedGroup = Process.THREAD_GROUP_DEFAULT;
17955            app.adjType = "top-activity";
17956            foregroundActivities = true;
17957            procState = PROCESS_STATE_TOP;
17958        } else if (app.instrumentationClass != null) {
17959            // Don't want to kill running instrumentation.
17960            adj = ProcessList.FOREGROUND_APP_ADJ;
17961            schedGroup = Process.THREAD_GROUP_DEFAULT;
17962            app.adjType = "instrumentation";
17963            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17964        } else if ((queue = isReceivingBroadcast(app)) != null) {
17965            // An app that is currently receiving a broadcast also
17966            // counts as being in the foreground for OOM killer purposes.
17967            // It's placed in a sched group based on the nature of the
17968            // broadcast as reflected by which queue it's active in.
17969            adj = ProcessList.FOREGROUND_APP_ADJ;
17970            schedGroup = (queue == mFgBroadcastQueue)
17971                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17972            app.adjType = "broadcast";
17973            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17974        } else if (app.executingServices.size() > 0) {
17975            // An app that is currently executing a service callback also
17976            // counts as being in the foreground.
17977            adj = ProcessList.FOREGROUND_APP_ADJ;
17978            schedGroup = app.execServicesFg ?
17979                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17980            app.adjType = "exec-service";
17981            procState = ActivityManager.PROCESS_STATE_SERVICE;
17982            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17983        } else {
17984            // As far as we know the process is empty.  We may change our mind later.
17985            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17986            // At this point we don't actually know the adjustment.  Use the cached adj
17987            // value that the caller wants us to.
17988            adj = cachedAdj;
17989            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17990            app.cached = true;
17991            app.empty = true;
17992            app.adjType = "cch-empty";
17993        }
17994
17995        // Examine all activities if not already foreground.
17996        if (!foregroundActivities && activitiesSize > 0) {
17997            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
17998            for (int j = 0; j < activitiesSize; j++) {
17999                final ActivityRecord r = app.activities.get(j);
18000                if (r.app != app) {
18001                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18002                            + app + "?!? Using " + r.app + " instead.");
18003                    continue;
18004                }
18005                if (r.visible) {
18006                    // App has a visible activity; only upgrade adjustment.
18007                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18008                        adj = ProcessList.VISIBLE_APP_ADJ;
18009                        app.adjType = "visible";
18010                    }
18011                    if (procState > PROCESS_STATE_TOP) {
18012                        procState = PROCESS_STATE_TOP;
18013                    }
18014                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18015                    app.cached = false;
18016                    app.empty = false;
18017                    foregroundActivities = true;
18018                    if (r.task != null && minLayer > 0) {
18019                        final int layer = r.task.mLayerRank;
18020                        if (layer >= 0 && minLayer > layer) {
18021                            minLayer = layer;
18022                        }
18023                    }
18024                    break;
18025                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18026                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18027                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18028                        app.adjType = "pausing";
18029                    }
18030                    if (procState > PROCESS_STATE_TOP) {
18031                        procState = PROCESS_STATE_TOP;
18032                    }
18033                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18034                    app.cached = false;
18035                    app.empty = false;
18036                    foregroundActivities = true;
18037                } else if (r.state == ActivityState.STOPPING) {
18038                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18039                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18040                        app.adjType = "stopping";
18041                    }
18042                    // For the process state, we will at this point consider the
18043                    // process to be cached.  It will be cached either as an activity
18044                    // or empty depending on whether the activity is finishing.  We do
18045                    // this so that we can treat the process as cached for purposes of
18046                    // memory trimming (determing current memory level, trim command to
18047                    // send to process) since there can be an arbitrary number of stopping
18048                    // processes and they should soon all go into the cached state.
18049                    if (!r.finishing) {
18050                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18051                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18052                        }
18053                    }
18054                    app.cached = false;
18055                    app.empty = false;
18056                    foregroundActivities = true;
18057                } else {
18058                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18059                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18060                        app.adjType = "cch-act";
18061                    }
18062                }
18063            }
18064            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18065                adj += minLayer;
18066            }
18067        }
18068
18069        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18070            if (app.foregroundServices) {
18071                // The user is aware of this app, so make it visible.
18072                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18073                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18074                app.cached = false;
18075                app.adjType = "fg-service";
18076                schedGroup = Process.THREAD_GROUP_DEFAULT;
18077            } else if (app.forcingToForeground != null) {
18078                // The user is aware of this app, so make it visible.
18079                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18080                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18081                app.cached = false;
18082                app.adjType = "force-fg";
18083                app.adjSource = app.forcingToForeground;
18084                schedGroup = Process.THREAD_GROUP_DEFAULT;
18085            }
18086        }
18087
18088        if (app == mHeavyWeightProcess) {
18089            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18090                // We don't want to kill the current heavy-weight process.
18091                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18092                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18093                app.cached = false;
18094                app.adjType = "heavy";
18095            }
18096            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18097                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18098            }
18099        }
18100
18101        if (app == mHomeProcess) {
18102            if (adj > ProcessList.HOME_APP_ADJ) {
18103                // This process is hosting what we currently consider to be the
18104                // home app, so we don't want to let it go into the background.
18105                adj = ProcessList.HOME_APP_ADJ;
18106                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18107                app.cached = false;
18108                app.adjType = "home";
18109            }
18110            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18111                procState = ActivityManager.PROCESS_STATE_HOME;
18112            }
18113        }
18114
18115        if (app == mPreviousProcess && app.activities.size() > 0) {
18116            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18117                // This was the previous process that showed UI to the user.
18118                // We want to try to keep it around more aggressively, to give
18119                // a good experience around switching between two apps.
18120                adj = ProcessList.PREVIOUS_APP_ADJ;
18121                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18122                app.cached = false;
18123                app.adjType = "previous";
18124            }
18125            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18126                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18127            }
18128        }
18129
18130        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18131                + " reason=" + app.adjType);
18132
18133        // By default, we use the computed adjustment.  It may be changed if
18134        // there are applications dependent on our services or providers, but
18135        // this gives us a baseline and makes sure we don't get into an
18136        // infinite recursion.
18137        app.adjSeq = mAdjSeq;
18138        app.curRawAdj = adj;
18139        app.hasStartedServices = false;
18140
18141        if (mBackupTarget != null && app == mBackupTarget.app) {
18142            // If possible we want to avoid killing apps while they're being backed up
18143            if (adj > ProcessList.BACKUP_APP_ADJ) {
18144                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18145                adj = ProcessList.BACKUP_APP_ADJ;
18146                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18147                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18148                }
18149                app.adjType = "backup";
18150                app.cached = false;
18151            }
18152            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18153                procState = ActivityManager.PROCESS_STATE_BACKUP;
18154            }
18155        }
18156
18157        boolean mayBeTop = false;
18158
18159        for (int is = app.services.size()-1;
18160                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18161                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18162                        || procState > ActivityManager.PROCESS_STATE_TOP);
18163                is--) {
18164            ServiceRecord s = app.services.valueAt(is);
18165            if (s.startRequested) {
18166                app.hasStartedServices = true;
18167                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18168                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18169                }
18170                if (app.hasShownUi && app != mHomeProcess) {
18171                    // If this process has shown some UI, let it immediately
18172                    // go to the LRU list because it may be pretty heavy with
18173                    // UI stuff.  We'll tag it with a label just to help
18174                    // debug and understand what is going on.
18175                    if (adj > ProcessList.SERVICE_ADJ) {
18176                        app.adjType = "cch-started-ui-services";
18177                    }
18178                } else {
18179                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18180                        // This service has seen some activity within
18181                        // recent memory, so we will keep its process ahead
18182                        // of the background processes.
18183                        if (adj > ProcessList.SERVICE_ADJ) {
18184                            adj = ProcessList.SERVICE_ADJ;
18185                            app.adjType = "started-services";
18186                            app.cached = false;
18187                        }
18188                    }
18189                    // If we have let the service slide into the background
18190                    // state, still have some text describing what it is doing
18191                    // even though the service no longer has an impact.
18192                    if (adj > ProcessList.SERVICE_ADJ) {
18193                        app.adjType = "cch-started-services";
18194                    }
18195                }
18196            }
18197            for (int conni = s.connections.size()-1;
18198                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18199                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18200                            || procState > ActivityManager.PROCESS_STATE_TOP);
18201                    conni--) {
18202                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18203                for (int i = 0;
18204                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18205                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18206                                || procState > ActivityManager.PROCESS_STATE_TOP);
18207                        i++) {
18208                    // XXX should compute this based on the max of
18209                    // all connected clients.
18210                    ConnectionRecord cr = clist.get(i);
18211                    if (cr.binding.client == app) {
18212                        // Binding to ourself is not interesting.
18213                        continue;
18214                    }
18215                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18216                        ProcessRecord client = cr.binding.client;
18217                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18218                                TOP_APP, doingAll, now);
18219                        int clientProcState = client.curProcState;
18220                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18221                            // If the other app is cached for any reason, for purposes here
18222                            // we are going to consider it empty.  The specific cached state
18223                            // doesn't propagate except under certain conditions.
18224                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18225                        }
18226                        String adjType = null;
18227                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18228                            // Not doing bind OOM management, so treat
18229                            // this guy more like a started service.
18230                            if (app.hasShownUi && app != mHomeProcess) {
18231                                // If this process has shown some UI, let it immediately
18232                                // go to the LRU list because it may be pretty heavy with
18233                                // UI stuff.  We'll tag it with a label just to help
18234                                // debug and understand what is going on.
18235                                if (adj > clientAdj) {
18236                                    adjType = "cch-bound-ui-services";
18237                                }
18238                                app.cached = false;
18239                                clientAdj = adj;
18240                                clientProcState = procState;
18241                            } else {
18242                                if (now >= (s.lastActivity
18243                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18244                                    // This service has not seen activity within
18245                                    // recent memory, so allow it to drop to the
18246                                    // LRU list if there is no other reason to keep
18247                                    // it around.  We'll also tag it with a label just
18248                                    // to help debug and undertand what is going on.
18249                                    if (adj > clientAdj) {
18250                                        adjType = "cch-bound-services";
18251                                    }
18252                                    clientAdj = adj;
18253                                }
18254                            }
18255                        }
18256                        if (adj > clientAdj) {
18257                            // If this process has recently shown UI, and
18258                            // the process that is binding to it is less
18259                            // important than being visible, then we don't
18260                            // care about the binding as much as we care
18261                            // about letting this process get into the LRU
18262                            // list to be killed and restarted if needed for
18263                            // memory.
18264                            if (app.hasShownUi && app != mHomeProcess
18265                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18266                                adjType = "cch-bound-ui-services";
18267                            } else {
18268                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18269                                        |Context.BIND_IMPORTANT)) != 0) {
18270                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18271                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18272                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18273                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18274                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18275                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18276                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18277                                    adj = clientAdj;
18278                                } else {
18279                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18280                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18281                                    }
18282                                }
18283                                if (!client.cached) {
18284                                    app.cached = false;
18285                                }
18286                                adjType = "service";
18287                            }
18288                        }
18289                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18290                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18291                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18292                            }
18293                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18294                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18295                                    // Special handling of clients who are in the top state.
18296                                    // We *may* want to consider this process to be in the
18297                                    // top state as well, but only if there is not another
18298                                    // reason for it to be running.  Being on the top is a
18299                                    // special state, meaning you are specifically running
18300                                    // for the current top app.  If the process is already
18301                                    // running in the background for some other reason, it
18302                                    // is more important to continue considering it to be
18303                                    // in the background state.
18304                                    mayBeTop = true;
18305                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18306                                } else {
18307                                    // Special handling for above-top states (persistent
18308                                    // processes).  These should not bring the current process
18309                                    // into the top state, since they are not on top.  Instead
18310                                    // give them the best state after that.
18311                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18312                                        clientProcState =
18313                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18314                                    } else if (mWakefulness
18315                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18316                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18317                                                    != 0) {
18318                                        clientProcState =
18319                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18320                                    } else {
18321                                        clientProcState =
18322                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18323                                    }
18324                                }
18325                            }
18326                        } else {
18327                            if (clientProcState <
18328                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18329                                clientProcState =
18330                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18331                            }
18332                        }
18333                        if (procState > clientProcState) {
18334                            procState = clientProcState;
18335                        }
18336                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18337                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18338                            app.pendingUiClean = true;
18339                        }
18340                        if (adjType != null) {
18341                            app.adjType = adjType;
18342                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18343                                    .REASON_SERVICE_IN_USE;
18344                            app.adjSource = cr.binding.client;
18345                            app.adjSourceProcState = clientProcState;
18346                            app.adjTarget = s.name;
18347                        }
18348                    }
18349                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18350                        app.treatLikeActivity = true;
18351                    }
18352                    final ActivityRecord a = cr.activity;
18353                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18354                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18355                                (a.visible || a.state == ActivityState.RESUMED
18356                                 || a.state == ActivityState.PAUSING)) {
18357                            adj = ProcessList.FOREGROUND_APP_ADJ;
18358                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18359                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18360                            }
18361                            app.cached = false;
18362                            app.adjType = "service";
18363                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18364                                    .REASON_SERVICE_IN_USE;
18365                            app.adjSource = a;
18366                            app.adjSourceProcState = procState;
18367                            app.adjTarget = s.name;
18368                        }
18369                    }
18370                }
18371            }
18372        }
18373
18374        for (int provi = app.pubProviders.size()-1;
18375                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18376                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18377                        || procState > ActivityManager.PROCESS_STATE_TOP);
18378                provi--) {
18379            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18380            for (int i = cpr.connections.size()-1;
18381                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18382                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18383                            || procState > ActivityManager.PROCESS_STATE_TOP);
18384                    i--) {
18385                ContentProviderConnection conn = cpr.connections.get(i);
18386                ProcessRecord client = conn.client;
18387                if (client == app) {
18388                    // Being our own client is not interesting.
18389                    continue;
18390                }
18391                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18392                int clientProcState = client.curProcState;
18393                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18394                    // If the other app is cached for any reason, for purposes here
18395                    // we are going to consider it empty.
18396                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18397                }
18398                if (adj > clientAdj) {
18399                    if (app.hasShownUi && app != mHomeProcess
18400                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18401                        app.adjType = "cch-ui-provider";
18402                    } else {
18403                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18404                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18405                        app.adjType = "provider";
18406                    }
18407                    app.cached &= client.cached;
18408                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18409                            .REASON_PROVIDER_IN_USE;
18410                    app.adjSource = client;
18411                    app.adjSourceProcState = clientProcState;
18412                    app.adjTarget = cpr.name;
18413                }
18414                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18415                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18416                        // Special handling of clients who are in the top state.
18417                        // We *may* want to consider this process to be in the
18418                        // top state as well, but only if there is not another
18419                        // reason for it to be running.  Being on the top is a
18420                        // special state, meaning you are specifically running
18421                        // for the current top app.  If the process is already
18422                        // running in the background for some other reason, it
18423                        // is more important to continue considering it to be
18424                        // in the background state.
18425                        mayBeTop = true;
18426                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18427                    } else {
18428                        // Special handling for above-top states (persistent
18429                        // processes).  These should not bring the current process
18430                        // into the top state, since they are not on top.  Instead
18431                        // give them the best state after that.
18432                        clientProcState =
18433                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18434                    }
18435                }
18436                if (procState > clientProcState) {
18437                    procState = clientProcState;
18438                }
18439                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18440                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18441                }
18442            }
18443            // If the provider has external (non-framework) process
18444            // dependencies, ensure that its adjustment is at least
18445            // FOREGROUND_APP_ADJ.
18446            if (cpr.hasExternalProcessHandles()) {
18447                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18448                    adj = ProcessList.FOREGROUND_APP_ADJ;
18449                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18450                    app.cached = false;
18451                    app.adjType = "provider";
18452                    app.adjTarget = cpr.name;
18453                }
18454                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18455                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18456                }
18457            }
18458        }
18459
18460        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18461            // A client of one of our services or providers is in the top state.  We
18462            // *may* want to be in the top state, but not if we are already running in
18463            // the background for some other reason.  For the decision here, we are going
18464            // to pick out a few specific states that we want to remain in when a client
18465            // is top (states that tend to be longer-term) and otherwise allow it to go
18466            // to the top state.
18467            switch (procState) {
18468                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18469                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18470                case ActivityManager.PROCESS_STATE_SERVICE:
18471                    // These all are longer-term states, so pull them up to the top
18472                    // of the background states, but not all the way to the top state.
18473                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18474                    break;
18475                default:
18476                    // Otherwise, top is a better choice, so take it.
18477                    procState = ActivityManager.PROCESS_STATE_TOP;
18478                    break;
18479            }
18480        }
18481
18482        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18483            if (app.hasClientActivities) {
18484                // This is a cached process, but with client activities.  Mark it so.
18485                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18486                app.adjType = "cch-client-act";
18487            } else if (app.treatLikeActivity) {
18488                // This is a cached process, but somebody wants us to treat it like it has
18489                // an activity, okay!
18490                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18491                app.adjType = "cch-as-act";
18492            }
18493        }
18494
18495        if (adj == ProcessList.SERVICE_ADJ) {
18496            if (doingAll) {
18497                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18498                mNewNumServiceProcs++;
18499                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18500                if (!app.serviceb) {
18501                    // This service isn't far enough down on the LRU list to
18502                    // normally be a B service, but if we are low on RAM and it
18503                    // is large we want to force it down since we would prefer to
18504                    // keep launcher over it.
18505                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18506                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18507                        app.serviceHighRam = true;
18508                        app.serviceb = true;
18509                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18510                    } else {
18511                        mNewNumAServiceProcs++;
18512                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18513                    }
18514                } else {
18515                    app.serviceHighRam = false;
18516                }
18517            }
18518            if (app.serviceb) {
18519                adj = ProcessList.SERVICE_B_ADJ;
18520            }
18521        }
18522
18523        app.curRawAdj = adj;
18524
18525        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18526        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18527        if (adj > app.maxAdj) {
18528            adj = app.maxAdj;
18529            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18530                schedGroup = Process.THREAD_GROUP_DEFAULT;
18531            }
18532        }
18533
18534        // Do final modification to adj.  Everything we do between here and applying
18535        // the final setAdj must be done in this function, because we will also use
18536        // it when computing the final cached adj later.  Note that we don't need to
18537        // worry about this for max adj above, since max adj will always be used to
18538        // keep it out of the cached vaues.
18539        app.curAdj = app.modifyRawOomAdj(adj);
18540        app.curSchedGroup = schedGroup;
18541        app.curProcState = procState;
18542        app.foregroundActivities = foregroundActivities;
18543
18544        return app.curRawAdj;
18545    }
18546
18547    /**
18548     * Record new PSS sample for a process.
18549     */
18550    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18551        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18552        proc.lastPssTime = now;
18553        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18554        if (DEBUG_PSS) Slog.d(TAG_PSS,
18555                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18556                + " state=" + ProcessList.makeProcStateString(procState));
18557        if (proc.initialIdlePss == 0) {
18558            proc.initialIdlePss = pss;
18559        }
18560        proc.lastPss = pss;
18561        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18562            proc.lastCachedPss = pss;
18563        }
18564
18565        final SparseArray<Pair<Long, String>> watchUids
18566                = mMemWatchProcesses.getMap().get(proc.processName);
18567        Long check = null;
18568        if (watchUids != null) {
18569            Pair<Long, String> val = watchUids.get(proc.uid);
18570            if (val == null) {
18571                val = watchUids.get(0);
18572            }
18573            if (val != null) {
18574                check = val.first;
18575            }
18576        }
18577        if (check != null) {
18578            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18579                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18580                if (!isDebuggable) {
18581                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18582                        isDebuggable = true;
18583                    }
18584                }
18585                if (isDebuggable) {
18586                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18587                    final ProcessRecord myProc = proc;
18588                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18589                    mMemWatchDumpProcName = proc.processName;
18590                    mMemWatchDumpFile = heapdumpFile.toString();
18591                    mMemWatchDumpPid = proc.pid;
18592                    mMemWatchDumpUid = proc.uid;
18593                    BackgroundThread.getHandler().post(new Runnable() {
18594                        @Override
18595                        public void run() {
18596                            revokeUriPermission(ActivityThread.currentActivityThread()
18597                                            .getApplicationThread(),
18598                                    DumpHeapActivity.JAVA_URI,
18599                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18600                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18601                                    UserHandle.myUserId());
18602                            ParcelFileDescriptor fd = null;
18603                            try {
18604                                heapdumpFile.delete();
18605                                fd = ParcelFileDescriptor.open(heapdumpFile,
18606                                        ParcelFileDescriptor.MODE_CREATE |
18607                                                ParcelFileDescriptor.MODE_TRUNCATE |
18608                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18609                                                ParcelFileDescriptor.MODE_APPEND);
18610                                IApplicationThread thread = myProc.thread;
18611                                if (thread != null) {
18612                                    try {
18613                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18614                                                "Requesting dump heap from "
18615                                                + myProc + " to " + heapdumpFile);
18616                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18617                                    } catch (RemoteException e) {
18618                                    }
18619                                }
18620                            } catch (FileNotFoundException e) {
18621                                e.printStackTrace();
18622                            } finally {
18623                                if (fd != null) {
18624                                    try {
18625                                        fd.close();
18626                                    } catch (IOException e) {
18627                                    }
18628                                }
18629                            }
18630                        }
18631                    });
18632                } else {
18633                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18634                            + ", but debugging not enabled");
18635                }
18636            }
18637        }
18638    }
18639
18640    /**
18641     * Schedule PSS collection of a process.
18642     */
18643    void requestPssLocked(ProcessRecord proc, int procState) {
18644        if (mPendingPssProcesses.contains(proc)) {
18645            return;
18646        }
18647        if (mPendingPssProcesses.size() == 0) {
18648            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18649        }
18650        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18651        proc.pssProcState = procState;
18652        mPendingPssProcesses.add(proc);
18653    }
18654
18655    /**
18656     * Schedule PSS collection of all processes.
18657     */
18658    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18659        if (!always) {
18660            if (now < (mLastFullPssTime +
18661                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18662                return;
18663            }
18664        }
18665        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18666        mLastFullPssTime = now;
18667        mFullPssPending = true;
18668        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18669        mPendingPssProcesses.clear();
18670        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18671            ProcessRecord app = mLruProcesses.get(i);
18672            if (app.thread == null
18673                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18674                continue;
18675            }
18676            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18677                app.pssProcState = app.setProcState;
18678                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18679                        mTestPssMode, isSleeping(), now);
18680                mPendingPssProcesses.add(app);
18681            }
18682        }
18683        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18684    }
18685
18686    public void setTestPssMode(boolean enabled) {
18687        synchronized (this) {
18688            mTestPssMode = enabled;
18689            if (enabled) {
18690                // Whenever we enable the mode, we want to take a snapshot all of current
18691                // process mem use.
18692                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18693            }
18694        }
18695    }
18696
18697    /**
18698     * Ask a given process to GC right now.
18699     */
18700    final void performAppGcLocked(ProcessRecord app) {
18701        try {
18702            app.lastRequestedGc = SystemClock.uptimeMillis();
18703            if (app.thread != null) {
18704                if (app.reportLowMemory) {
18705                    app.reportLowMemory = false;
18706                    app.thread.scheduleLowMemory();
18707                } else {
18708                    app.thread.processInBackground();
18709                }
18710            }
18711        } catch (Exception e) {
18712            // whatever.
18713        }
18714    }
18715
18716    /**
18717     * Returns true if things are idle enough to perform GCs.
18718     */
18719    private final boolean canGcNowLocked() {
18720        boolean processingBroadcasts = false;
18721        for (BroadcastQueue q : mBroadcastQueues) {
18722            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18723                processingBroadcasts = true;
18724            }
18725        }
18726        return !processingBroadcasts
18727                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18728    }
18729
18730    /**
18731     * Perform GCs on all processes that are waiting for it, but only
18732     * if things are idle.
18733     */
18734    final void performAppGcsLocked() {
18735        final int N = mProcessesToGc.size();
18736        if (N <= 0) {
18737            return;
18738        }
18739        if (canGcNowLocked()) {
18740            while (mProcessesToGc.size() > 0) {
18741                ProcessRecord proc = mProcessesToGc.remove(0);
18742                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18743                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18744                            <= SystemClock.uptimeMillis()) {
18745                        // To avoid spamming the system, we will GC processes one
18746                        // at a time, waiting a few seconds between each.
18747                        performAppGcLocked(proc);
18748                        scheduleAppGcsLocked();
18749                        return;
18750                    } else {
18751                        // It hasn't been long enough since we last GCed this
18752                        // process...  put it in the list to wait for its time.
18753                        addProcessToGcListLocked(proc);
18754                        break;
18755                    }
18756                }
18757            }
18758
18759            scheduleAppGcsLocked();
18760        }
18761    }
18762
18763    /**
18764     * If all looks good, perform GCs on all processes waiting for them.
18765     */
18766    final void performAppGcsIfAppropriateLocked() {
18767        if (canGcNowLocked()) {
18768            performAppGcsLocked();
18769            return;
18770        }
18771        // Still not idle, wait some more.
18772        scheduleAppGcsLocked();
18773    }
18774
18775    /**
18776     * Schedule the execution of all pending app GCs.
18777     */
18778    final void scheduleAppGcsLocked() {
18779        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18780
18781        if (mProcessesToGc.size() > 0) {
18782            // Schedule a GC for the time to the next process.
18783            ProcessRecord proc = mProcessesToGc.get(0);
18784            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18785
18786            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18787            long now = SystemClock.uptimeMillis();
18788            if (when < (now+GC_TIMEOUT)) {
18789                when = now + GC_TIMEOUT;
18790            }
18791            mHandler.sendMessageAtTime(msg, when);
18792        }
18793    }
18794
18795    /**
18796     * Add a process to the array of processes waiting to be GCed.  Keeps the
18797     * list in sorted order by the last GC time.  The process can't already be
18798     * on the list.
18799     */
18800    final void addProcessToGcListLocked(ProcessRecord proc) {
18801        boolean added = false;
18802        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18803            if (mProcessesToGc.get(i).lastRequestedGc <
18804                    proc.lastRequestedGc) {
18805                added = true;
18806                mProcessesToGc.add(i+1, proc);
18807                break;
18808            }
18809        }
18810        if (!added) {
18811            mProcessesToGc.add(0, proc);
18812        }
18813    }
18814
18815    /**
18816     * Set up to ask a process to GC itself.  This will either do it
18817     * immediately, or put it on the list of processes to gc the next
18818     * time things are idle.
18819     */
18820    final void scheduleAppGcLocked(ProcessRecord app) {
18821        long now = SystemClock.uptimeMillis();
18822        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18823            return;
18824        }
18825        if (!mProcessesToGc.contains(app)) {
18826            addProcessToGcListLocked(app);
18827            scheduleAppGcsLocked();
18828        }
18829    }
18830
18831    final void checkExcessivePowerUsageLocked(boolean doKills) {
18832        updateCpuStatsNow();
18833
18834        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18835        boolean doWakeKills = doKills;
18836        boolean doCpuKills = doKills;
18837        if (mLastPowerCheckRealtime == 0) {
18838            doWakeKills = false;
18839        }
18840        if (mLastPowerCheckUptime == 0) {
18841            doCpuKills = false;
18842        }
18843        if (stats.isScreenOn()) {
18844            doWakeKills = false;
18845        }
18846        final long curRealtime = SystemClock.elapsedRealtime();
18847        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18848        final long curUptime = SystemClock.uptimeMillis();
18849        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18850        mLastPowerCheckRealtime = curRealtime;
18851        mLastPowerCheckUptime = curUptime;
18852        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18853            doWakeKills = false;
18854        }
18855        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18856            doCpuKills = false;
18857        }
18858        int i = mLruProcesses.size();
18859        while (i > 0) {
18860            i--;
18861            ProcessRecord app = mLruProcesses.get(i);
18862            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18863                long wtime;
18864                synchronized (stats) {
18865                    wtime = stats.getProcessWakeTime(app.info.uid,
18866                            app.pid, curRealtime);
18867                }
18868                long wtimeUsed = wtime - app.lastWakeTime;
18869                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18870                if (DEBUG_POWER) {
18871                    StringBuilder sb = new StringBuilder(128);
18872                    sb.append("Wake for ");
18873                    app.toShortString(sb);
18874                    sb.append(": over ");
18875                    TimeUtils.formatDuration(realtimeSince, sb);
18876                    sb.append(" used ");
18877                    TimeUtils.formatDuration(wtimeUsed, sb);
18878                    sb.append(" (");
18879                    sb.append((wtimeUsed*100)/realtimeSince);
18880                    sb.append("%)");
18881                    Slog.i(TAG_POWER, sb.toString());
18882                    sb.setLength(0);
18883                    sb.append("CPU for ");
18884                    app.toShortString(sb);
18885                    sb.append(": over ");
18886                    TimeUtils.formatDuration(uptimeSince, sb);
18887                    sb.append(" used ");
18888                    TimeUtils.formatDuration(cputimeUsed, sb);
18889                    sb.append(" (");
18890                    sb.append((cputimeUsed*100)/uptimeSince);
18891                    sb.append("%)");
18892                    Slog.i(TAG_POWER, sb.toString());
18893                }
18894                // If a process has held a wake lock for more
18895                // than 50% of the time during this period,
18896                // that sounds bad.  Kill!
18897                if (doWakeKills && realtimeSince > 0
18898                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18899                    synchronized (stats) {
18900                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18901                                realtimeSince, wtimeUsed);
18902                    }
18903                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18904                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18905                } else if (doCpuKills && uptimeSince > 0
18906                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18907                    synchronized (stats) {
18908                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18909                                uptimeSince, cputimeUsed);
18910                    }
18911                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18912                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18913                } else {
18914                    app.lastWakeTime = wtime;
18915                    app.lastCpuTime = app.curCpuTime;
18916                }
18917            }
18918        }
18919    }
18920
18921    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18922        boolean success = true;
18923
18924        if (app.curRawAdj != app.setRawAdj) {
18925            app.setRawAdj = app.curRawAdj;
18926        }
18927
18928        int changes = 0;
18929
18930        if (app.curAdj != app.setAdj) {
18931            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18932            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18933                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18934                    + app.adjType);
18935            app.setAdj = app.curAdj;
18936        }
18937
18938        if (app.setSchedGroup != app.curSchedGroup) {
18939            app.setSchedGroup = app.curSchedGroup;
18940            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18941                    "Setting process group of " + app.processName
18942                    + " to " + app.curSchedGroup);
18943            if (app.waitingToKill != null && app.curReceiver == null
18944                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18945                app.kill(app.waitingToKill, true);
18946                success = false;
18947            } else {
18948                if (true) {
18949                    long oldId = Binder.clearCallingIdentity();
18950                    try {
18951                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18952                    } catch (Exception e) {
18953                        Slog.w(TAG, "Failed setting process group of " + app.pid
18954                                + " to " + app.curSchedGroup);
18955                        e.printStackTrace();
18956                    } finally {
18957                        Binder.restoreCallingIdentity(oldId);
18958                    }
18959                } else {
18960                    if (app.thread != null) {
18961                        try {
18962                            app.thread.setSchedulingGroup(app.curSchedGroup);
18963                        } catch (RemoteException e) {
18964                        }
18965                    }
18966                }
18967                Process.setSwappiness(app.pid,
18968                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18969            }
18970        }
18971        if (app.repForegroundActivities != app.foregroundActivities) {
18972            app.repForegroundActivities = app.foregroundActivities;
18973            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18974        }
18975        if (app.repProcState != app.curProcState) {
18976            app.repProcState = app.curProcState;
18977            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18978            if (app.thread != null) {
18979                try {
18980                    if (false) {
18981                        //RuntimeException h = new RuntimeException("here");
18982                        Slog.i(TAG, "Sending new process state " + app.repProcState
18983                                + " to " + app /*, h*/);
18984                    }
18985                    app.thread.setProcessState(app.repProcState);
18986                } catch (RemoteException e) {
18987                }
18988            }
18989        }
18990        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18991                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18992            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18993                // Experimental code to more aggressively collect pss while
18994                // running test...  the problem is that this tends to collect
18995                // the data right when a process is transitioning between process
18996                // states, which well tend to give noisy data.
18997                long start = SystemClock.uptimeMillis();
18998                long pss = Debug.getPss(app.pid, mTmpLong, null);
18999                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19000                mPendingPssProcesses.remove(app);
19001                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19002                        + " to " + app.curProcState + ": "
19003                        + (SystemClock.uptimeMillis()-start) + "ms");
19004            }
19005            app.lastStateTime = now;
19006            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19007                    mTestPssMode, isSleeping(), now);
19008            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19009                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19010                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19011                    + (app.nextPssTime-now) + ": " + app);
19012        } else {
19013            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19014                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19015                    mTestPssMode)))) {
19016                requestPssLocked(app, app.setProcState);
19017                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19018                        mTestPssMode, isSleeping(), now);
19019            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19020                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19021        }
19022        if (app.setProcState != app.curProcState) {
19023            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19024                    "Proc state change of " + app.processName
19025                    + " to " + app.curProcState);
19026            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19027            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19028            if (setImportant && !curImportant) {
19029                // This app is no longer something we consider important enough to allow to
19030                // use arbitrary amounts of battery power.  Note
19031                // its current wake lock time to later know to kill it if
19032                // it is not behaving well.
19033                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19034                synchronized (stats) {
19035                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19036                            app.pid, SystemClock.elapsedRealtime());
19037                }
19038                app.lastCpuTime = app.curCpuTime;
19039
19040            }
19041            // Inform UsageStats of important process state change
19042            // Must be called before updating setProcState
19043            maybeUpdateUsageStatsLocked(app);
19044
19045            app.setProcState = app.curProcState;
19046            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19047                app.notCachedSinceIdle = false;
19048            }
19049            if (!doingAll) {
19050                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19051            } else {
19052                app.procStateChanged = true;
19053            }
19054        }
19055
19056        if (changes != 0) {
19057            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19058                    "Changes in " + app + ": " + changes);
19059            int i = mPendingProcessChanges.size()-1;
19060            ProcessChangeItem item = null;
19061            while (i >= 0) {
19062                item = mPendingProcessChanges.get(i);
19063                if (item.pid == app.pid) {
19064                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19065                            "Re-using existing item: " + item);
19066                    break;
19067                }
19068                i--;
19069            }
19070            if (i < 0) {
19071                // No existing item in pending changes; need a new one.
19072                final int NA = mAvailProcessChanges.size();
19073                if (NA > 0) {
19074                    item = mAvailProcessChanges.remove(NA-1);
19075                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19076                            "Retrieving available item: " + item);
19077                } else {
19078                    item = new ProcessChangeItem();
19079                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19080                            "Allocating new item: " + item);
19081                }
19082                item.changes = 0;
19083                item.pid = app.pid;
19084                item.uid = app.info.uid;
19085                if (mPendingProcessChanges.size() == 0) {
19086                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19087                            "*** Enqueueing dispatch processes changed!");
19088                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
19089                }
19090                mPendingProcessChanges.add(item);
19091            }
19092            item.changes |= changes;
19093            item.processState = app.repProcState;
19094            item.foregroundActivities = app.repForegroundActivities;
19095            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19096                    "Item " + Integer.toHexString(System.identityHashCode(item))
19097                    + " " + app.toShortString() + ": changes=" + item.changes
19098                    + " procState=" + item.processState
19099                    + " foreground=" + item.foregroundActivities
19100                    + " type=" + app.adjType + " source=" + app.adjSource
19101                    + " target=" + app.adjTarget);
19102        }
19103
19104        return success;
19105    }
19106
19107    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
19108        if (uidRec.pendingChange == null) {
19109            if (mPendingUidChanges.size() == 0) {
19110                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19111                        "*** Enqueueing dispatch uid changed!");
19112                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
19113            }
19114            final int NA = mAvailUidChanges.size();
19115            if (NA > 0) {
19116                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
19117                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19118                        "Retrieving available item: " + uidRec.pendingChange);
19119            } else {
19120                uidRec.pendingChange = new UidRecord.ChangeItem();
19121                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19122                        "Allocating new item: " + uidRec.pendingChange);
19123            }
19124            uidRec.pendingChange.uidRecord = uidRec;
19125            uidRec.pendingChange.uid = uidRec.uid;
19126            mPendingUidChanges.add(uidRec.pendingChange);
19127        }
19128        uidRec.pendingChange.gone = gone;
19129        uidRec.pendingChange.processState = uidRec.setProcState;
19130    }
19131
19132    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19133            String authority) {
19134        if (app == null) return;
19135        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19136            UserState userState = mUserController.getStartedUserState(app.userId);
19137            if (userState == null) return;
19138            final long now = SystemClock.elapsedRealtime();
19139            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19140            if (lastReported == null || lastReported < now - 60 * 1000L) {
19141                mUsageStatsService.reportContentProviderUsage(
19142                        authority, providerPkgName, app.userId);
19143                userState.mProviderLastReportedFg.put(authority, now);
19144            }
19145        }
19146    }
19147
19148    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
19149        if (DEBUG_USAGE_STATS) {
19150            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19151                    + "] state changes: old = " + app.setProcState + ", new = "
19152                    + app.curProcState);
19153        }
19154        if (mUsageStatsService == null) {
19155            return;
19156        }
19157        boolean isInteraction;
19158        // To avoid some abuse patterns, we are going to be careful about what we consider
19159        // to be an app interaction.  Being the top activity doesn't count while the display
19160        // is sleeping, nor do short foreground services.
19161        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19162            isInteraction = true;
19163            app.fgInteractionTime = 0;
19164        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19165            final long now = SystemClock.elapsedRealtime();
19166            if (app.fgInteractionTime == 0) {
19167                app.fgInteractionTime = now;
19168                isInteraction = false;
19169            } else {
19170                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19171            }
19172        } else {
19173            isInteraction = app.curProcState
19174                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19175            app.fgInteractionTime = 0;
19176        }
19177        if (isInteraction && !app.reportedInteraction) {
19178            String[] packages = app.getPackageList();
19179            if (packages != null) {
19180                for (int i = 0; i < packages.length; i++) {
19181                    mUsageStatsService.reportEvent(packages[i], app.userId,
19182                            UsageEvents.Event.SYSTEM_INTERACTION);
19183                }
19184            }
19185        }
19186        app.reportedInteraction = isInteraction;
19187    }
19188
19189    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19190        if (proc.thread != null) {
19191            if (proc.baseProcessTracker != null) {
19192                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19193            }
19194            if (proc.repProcState >= 0) {
19195                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19196                        proc.repProcState);
19197            }
19198        }
19199    }
19200
19201    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19202            ProcessRecord TOP_APP, boolean doingAll, long now) {
19203        if (app.thread == null) {
19204            return false;
19205        }
19206
19207        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19208
19209        return applyOomAdjLocked(app, doingAll, now);
19210    }
19211
19212    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19213            boolean oomAdj) {
19214        if (isForeground != proc.foregroundServices) {
19215            proc.foregroundServices = isForeground;
19216            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19217                    proc.info.uid);
19218            if (isForeground) {
19219                if (curProcs == null) {
19220                    curProcs = new ArrayList<ProcessRecord>();
19221                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19222                }
19223                if (!curProcs.contains(proc)) {
19224                    curProcs.add(proc);
19225                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19226                            proc.info.packageName, proc.info.uid);
19227                }
19228            } else {
19229                if (curProcs != null) {
19230                    if (curProcs.remove(proc)) {
19231                        mBatteryStatsService.noteEvent(
19232                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19233                                proc.info.packageName, proc.info.uid);
19234                        if (curProcs.size() <= 0) {
19235                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19236                        }
19237                    }
19238                }
19239            }
19240            if (oomAdj) {
19241                updateOomAdjLocked();
19242            }
19243        }
19244    }
19245
19246    private final ActivityRecord resumedAppLocked() {
19247        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19248        String pkg;
19249        int uid;
19250        if (act != null) {
19251            pkg = act.packageName;
19252            uid = act.info.applicationInfo.uid;
19253        } else {
19254            pkg = null;
19255            uid = -1;
19256        }
19257        // Has the UID or resumed package name changed?
19258        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19259                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19260            if (mCurResumedPackage != null) {
19261                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19262                        mCurResumedPackage, mCurResumedUid);
19263            }
19264            mCurResumedPackage = pkg;
19265            mCurResumedUid = uid;
19266            if (mCurResumedPackage != null) {
19267                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19268                        mCurResumedPackage, mCurResumedUid);
19269            }
19270        }
19271        return act;
19272    }
19273
19274    final boolean updateOomAdjLocked(ProcessRecord app) {
19275        final ActivityRecord TOP_ACT = resumedAppLocked();
19276        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19277        final boolean wasCached = app.cached;
19278
19279        mAdjSeq++;
19280
19281        // This is the desired cached adjusment we want to tell it to use.
19282        // If our app is currently cached, we know it, and that is it.  Otherwise,
19283        // we don't know it yet, and it needs to now be cached we will then
19284        // need to do a complete oom adj.
19285        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19286                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19287        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19288                SystemClock.uptimeMillis());
19289        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19290            // Changed to/from cached state, so apps after it in the LRU
19291            // list may also be changed.
19292            updateOomAdjLocked();
19293        }
19294        return success;
19295    }
19296
19297    final void updateOomAdjLocked() {
19298        final ActivityRecord TOP_ACT = resumedAppLocked();
19299        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19300        final long now = SystemClock.uptimeMillis();
19301        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19302        final int N = mLruProcesses.size();
19303
19304        if (false) {
19305            RuntimeException e = new RuntimeException();
19306            e.fillInStackTrace();
19307            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19308        }
19309
19310        // Reset state in all uid records.
19311        for (int i=mActiveUids.size()-1; i>=0; i--) {
19312            final UidRecord uidRec = mActiveUids.valueAt(i);
19313            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19314                    "Starting update of " + uidRec);
19315            uidRec.reset();
19316        }
19317
19318        mStackSupervisor.rankTaskLayersIfNeeded();
19319
19320        mAdjSeq++;
19321        mNewNumServiceProcs = 0;
19322        mNewNumAServiceProcs = 0;
19323
19324        final int emptyProcessLimit;
19325        final int cachedProcessLimit;
19326        if (mProcessLimit <= 0) {
19327            emptyProcessLimit = cachedProcessLimit = 0;
19328        } else if (mProcessLimit == 1) {
19329            emptyProcessLimit = 1;
19330            cachedProcessLimit = 0;
19331        } else {
19332            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19333            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19334        }
19335
19336        // Let's determine how many processes we have running vs.
19337        // how many slots we have for background processes; we may want
19338        // to put multiple processes in a slot of there are enough of
19339        // them.
19340        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19341                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19342        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19343        if (numEmptyProcs > cachedProcessLimit) {
19344            // If there are more empty processes than our limit on cached
19345            // processes, then use the cached process limit for the factor.
19346            // This ensures that the really old empty processes get pushed
19347            // down to the bottom, so if we are running low on memory we will
19348            // have a better chance at keeping around more cached processes
19349            // instead of a gazillion empty processes.
19350            numEmptyProcs = cachedProcessLimit;
19351        }
19352        int emptyFactor = numEmptyProcs/numSlots;
19353        if (emptyFactor < 1) emptyFactor = 1;
19354        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19355        if (cachedFactor < 1) cachedFactor = 1;
19356        int stepCached = 0;
19357        int stepEmpty = 0;
19358        int numCached = 0;
19359        int numEmpty = 0;
19360        int numTrimming = 0;
19361
19362        mNumNonCachedProcs = 0;
19363        mNumCachedHiddenProcs = 0;
19364
19365        // First update the OOM adjustment for each of the
19366        // application processes based on their current state.
19367        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19368        int nextCachedAdj = curCachedAdj+1;
19369        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19370        int nextEmptyAdj = curEmptyAdj+2;
19371        for (int i=N-1; i>=0; i--) {
19372            ProcessRecord app = mLruProcesses.get(i);
19373            if (!app.killedByAm && app.thread != null) {
19374                app.procStateChanged = false;
19375                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19376
19377                // If we haven't yet assigned the final cached adj
19378                // to the process, do that now.
19379                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19380                    switch (app.curProcState) {
19381                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19382                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19383                            // This process is a cached process holding activities...
19384                            // assign it the next cached value for that type, and then
19385                            // step that cached level.
19386                            app.curRawAdj = curCachedAdj;
19387                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19388                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19389                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19390                                    + ")");
19391                            if (curCachedAdj != nextCachedAdj) {
19392                                stepCached++;
19393                                if (stepCached >= cachedFactor) {
19394                                    stepCached = 0;
19395                                    curCachedAdj = nextCachedAdj;
19396                                    nextCachedAdj += 2;
19397                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19398                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19399                                    }
19400                                }
19401                            }
19402                            break;
19403                        default:
19404                            // For everything else, assign next empty cached process
19405                            // level and bump that up.  Note that this means that
19406                            // long-running services that have dropped down to the
19407                            // cached level will be treated as empty (since their process
19408                            // state is still as a service), which is what we want.
19409                            app.curRawAdj = curEmptyAdj;
19410                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19411                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19412                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19413                                    + ")");
19414                            if (curEmptyAdj != nextEmptyAdj) {
19415                                stepEmpty++;
19416                                if (stepEmpty >= emptyFactor) {
19417                                    stepEmpty = 0;
19418                                    curEmptyAdj = nextEmptyAdj;
19419                                    nextEmptyAdj += 2;
19420                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19421                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19422                                    }
19423                                }
19424                            }
19425                            break;
19426                    }
19427                }
19428
19429                applyOomAdjLocked(app, true, now);
19430
19431                // Count the number of process types.
19432                switch (app.curProcState) {
19433                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19434                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19435                        mNumCachedHiddenProcs++;
19436                        numCached++;
19437                        if (numCached > cachedProcessLimit) {
19438                            app.kill("cached #" + numCached, true);
19439                        }
19440                        break;
19441                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19442                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19443                                && app.lastActivityTime < oldTime) {
19444                            app.kill("empty for "
19445                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19446                                    / 1000) + "s", true);
19447                        } else {
19448                            numEmpty++;
19449                            if (numEmpty > emptyProcessLimit) {
19450                                app.kill("empty #" + numEmpty, true);
19451                            }
19452                        }
19453                        break;
19454                    default:
19455                        mNumNonCachedProcs++;
19456                        break;
19457                }
19458
19459                if (app.isolated && app.services.size() <= 0) {
19460                    // If this is an isolated process, and there are no
19461                    // services running in it, then the process is no longer
19462                    // needed.  We agressively kill these because we can by
19463                    // definition not re-use the same process again, and it is
19464                    // good to avoid having whatever code was running in them
19465                    // left sitting around after no longer needed.
19466                    app.kill("isolated not needed", true);
19467                } else {
19468                    // Keeping this process, update its uid.
19469                    final UidRecord uidRec = app.uidRecord;
19470                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19471                        uidRec.curProcState = app.curProcState;
19472                    }
19473                }
19474
19475                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19476                        && !app.killedByAm) {
19477                    numTrimming++;
19478                }
19479            }
19480        }
19481
19482        mNumServiceProcs = mNewNumServiceProcs;
19483
19484        // Now determine the memory trimming level of background processes.
19485        // Unfortunately we need to start at the back of the list to do this
19486        // properly.  We only do this if the number of background apps we
19487        // are managing to keep around is less than half the maximum we desire;
19488        // if we are keeping a good number around, we'll let them use whatever
19489        // memory they want.
19490        final int numCachedAndEmpty = numCached + numEmpty;
19491        int memFactor;
19492        if (numCached <= ProcessList.TRIM_CACHED_APPS
19493                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19494            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19495                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19496            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19497                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19498            } else {
19499                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19500            }
19501        } else {
19502            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19503        }
19504        // We always allow the memory level to go up (better).  We only allow it to go
19505        // down if we are in a state where that is allowed, *and* the total number of processes
19506        // has gone down since last time.
19507        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19508                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19509                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19510        if (memFactor > mLastMemoryLevel) {
19511            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19512                memFactor = mLastMemoryLevel;
19513                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19514            }
19515        }
19516        mLastMemoryLevel = memFactor;
19517        mLastNumProcesses = mLruProcesses.size();
19518        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19519        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19520        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19521            if (mLowRamStartTime == 0) {
19522                mLowRamStartTime = now;
19523            }
19524            int step = 0;
19525            int fgTrimLevel;
19526            switch (memFactor) {
19527                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19528                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19529                    break;
19530                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19531                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19532                    break;
19533                default:
19534                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19535                    break;
19536            }
19537            int factor = numTrimming/3;
19538            int minFactor = 2;
19539            if (mHomeProcess != null) minFactor++;
19540            if (mPreviousProcess != null) minFactor++;
19541            if (factor < minFactor) factor = minFactor;
19542            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19543            for (int i=N-1; i>=0; i--) {
19544                ProcessRecord app = mLruProcesses.get(i);
19545                if (allChanged || app.procStateChanged) {
19546                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19547                    app.procStateChanged = false;
19548                }
19549                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19550                        && !app.killedByAm) {
19551                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19552                        try {
19553                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19554                                    "Trimming memory of " + app.processName + " to " + curLevel);
19555                            app.thread.scheduleTrimMemory(curLevel);
19556                        } catch (RemoteException e) {
19557                        }
19558                        if (false) {
19559                            // For now we won't do this; our memory trimming seems
19560                            // to be good enough at this point that destroying
19561                            // activities causes more harm than good.
19562                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19563                                    && app != mHomeProcess && app != mPreviousProcess) {
19564                                // Need to do this on its own message because the stack may not
19565                                // be in a consistent state at this point.
19566                                // For these apps we will also finish their activities
19567                                // to help them free memory.
19568                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19569                            }
19570                        }
19571                    }
19572                    app.trimMemoryLevel = curLevel;
19573                    step++;
19574                    if (step >= factor) {
19575                        step = 0;
19576                        switch (curLevel) {
19577                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19578                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19579                                break;
19580                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19581                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19582                                break;
19583                        }
19584                    }
19585                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19586                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19587                            && app.thread != null) {
19588                        try {
19589                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19590                                    "Trimming memory of heavy-weight " + app.processName
19591                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19592                            app.thread.scheduleTrimMemory(
19593                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19594                        } catch (RemoteException e) {
19595                        }
19596                    }
19597                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19598                } else {
19599                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19600                            || app.systemNoUi) && app.pendingUiClean) {
19601                        // If this application is now in the background and it
19602                        // had done UI, then give it the special trim level to
19603                        // have it free UI resources.
19604                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19605                        if (app.trimMemoryLevel < level && app.thread != null) {
19606                            try {
19607                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19608                                        "Trimming memory of bg-ui " + app.processName
19609                                        + " to " + level);
19610                                app.thread.scheduleTrimMemory(level);
19611                            } catch (RemoteException e) {
19612                            }
19613                        }
19614                        app.pendingUiClean = false;
19615                    }
19616                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19617                        try {
19618                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19619                                    "Trimming memory of fg " + app.processName
19620                                    + " to " + fgTrimLevel);
19621                            app.thread.scheduleTrimMemory(fgTrimLevel);
19622                        } catch (RemoteException e) {
19623                        }
19624                    }
19625                    app.trimMemoryLevel = fgTrimLevel;
19626                }
19627            }
19628        } else {
19629            if (mLowRamStartTime != 0) {
19630                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19631                mLowRamStartTime = 0;
19632            }
19633            for (int i=N-1; i>=0; i--) {
19634                ProcessRecord app = mLruProcesses.get(i);
19635                if (allChanged || app.procStateChanged) {
19636                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19637                    app.procStateChanged = false;
19638                }
19639                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19640                        || app.systemNoUi) && app.pendingUiClean) {
19641                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19642                            && app.thread != null) {
19643                        try {
19644                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19645                                    "Trimming memory of ui hidden " + app.processName
19646                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19647                            app.thread.scheduleTrimMemory(
19648                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19649                        } catch (RemoteException e) {
19650                        }
19651                    }
19652                    app.pendingUiClean = false;
19653                }
19654                app.trimMemoryLevel = 0;
19655            }
19656        }
19657
19658        if (mAlwaysFinishActivities) {
19659            // Need to do this on its own message because the stack may not
19660            // be in a consistent state at this point.
19661            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19662        }
19663
19664        if (allChanged) {
19665            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19666        }
19667
19668        // Update from any uid changes.
19669        for (int i=mActiveUids.size()-1; i>=0; i--) {
19670            final UidRecord uidRec = mActiveUids.valueAt(i);
19671            if (uidRec.setProcState != uidRec.curProcState) {
19672                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19673                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19674                        + " to " + uidRec.curProcState);
19675                uidRec.setProcState = uidRec.curProcState;
19676                enqueueUidChangeLocked(uidRec, false);
19677            }
19678        }
19679
19680        if (mProcessStats.shouldWriteNowLocked(now)) {
19681            mHandler.post(new Runnable() {
19682                @Override public void run() {
19683                    synchronized (ActivityManagerService.this) {
19684                        mProcessStats.writeStateAsyncLocked();
19685                    }
19686                }
19687            });
19688        }
19689
19690        if (DEBUG_OOM_ADJ) {
19691            final long duration = SystemClock.uptimeMillis() - now;
19692            if (false) {
19693                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19694                        new RuntimeException("here").fillInStackTrace());
19695            } else {
19696                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19697            }
19698        }
19699    }
19700
19701    final void trimApplications() {
19702        synchronized (this) {
19703            int i;
19704
19705            // First remove any unused application processes whose package
19706            // has been removed.
19707            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19708                final ProcessRecord app = mRemovedProcesses.get(i);
19709                if (app.activities.size() == 0
19710                        && app.curReceiver == null && app.services.size() == 0) {
19711                    Slog.i(
19712                        TAG, "Exiting empty application process "
19713                        + app.processName + " ("
19714                        + (app.thread != null ? app.thread.asBinder() : null)
19715                        + ")\n");
19716                    if (app.pid > 0 && app.pid != MY_PID) {
19717                        app.kill("empty", false);
19718                    } else {
19719                        try {
19720                            app.thread.scheduleExit();
19721                        } catch (Exception e) {
19722                            // Ignore exceptions.
19723                        }
19724                    }
19725                    cleanUpApplicationRecordLocked(app, false, true, -1);
19726                    mRemovedProcesses.remove(i);
19727
19728                    if (app.persistent) {
19729                        addAppLocked(app.info, false, null /* ABI override */);
19730                    }
19731                }
19732            }
19733
19734            // Now update the oom adj for all processes.
19735            updateOomAdjLocked();
19736        }
19737    }
19738
19739    /** This method sends the specified signal to each of the persistent apps */
19740    public void signalPersistentProcesses(int sig) throws RemoteException {
19741        if (sig != Process.SIGNAL_USR1) {
19742            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19743        }
19744
19745        synchronized (this) {
19746            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19747                    != PackageManager.PERMISSION_GRANTED) {
19748                throw new SecurityException("Requires permission "
19749                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19750            }
19751
19752            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19753                ProcessRecord r = mLruProcesses.get(i);
19754                if (r.thread != null && r.persistent) {
19755                    Process.sendSignal(r.pid, sig);
19756                }
19757            }
19758        }
19759    }
19760
19761    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19762        if (proc == null || proc == mProfileProc) {
19763            proc = mProfileProc;
19764            profileType = mProfileType;
19765            clearProfilerLocked();
19766        }
19767        if (proc == null) {
19768            return;
19769        }
19770        try {
19771            proc.thread.profilerControl(false, null, profileType);
19772        } catch (RemoteException e) {
19773            throw new IllegalStateException("Process disappeared");
19774        }
19775    }
19776
19777    private void clearProfilerLocked() {
19778        if (mProfileFd != null) {
19779            try {
19780                mProfileFd.close();
19781            } catch (IOException e) {
19782            }
19783        }
19784        mProfileApp = null;
19785        mProfileProc = null;
19786        mProfileFile = null;
19787        mProfileType = 0;
19788        mAutoStopProfiler = false;
19789        mSamplingInterval = 0;
19790    }
19791
19792    public boolean profileControl(String process, int userId, boolean start,
19793            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19794
19795        try {
19796            synchronized (this) {
19797                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19798                // its own permission.
19799                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19800                        != PackageManager.PERMISSION_GRANTED) {
19801                    throw new SecurityException("Requires permission "
19802                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19803                }
19804
19805                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19806                    throw new IllegalArgumentException("null profile info or fd");
19807                }
19808
19809                ProcessRecord proc = null;
19810                if (process != null) {
19811                    proc = findProcessLocked(process, userId, "profileControl");
19812                }
19813
19814                if (start && (proc == null || proc.thread == null)) {
19815                    throw new IllegalArgumentException("Unknown process: " + process);
19816                }
19817
19818                if (start) {
19819                    stopProfilerLocked(null, 0);
19820                    setProfileApp(proc.info, proc.processName, profilerInfo);
19821                    mProfileProc = proc;
19822                    mProfileType = profileType;
19823                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19824                    try {
19825                        fd = fd.dup();
19826                    } catch (IOException e) {
19827                        fd = null;
19828                    }
19829                    profilerInfo.profileFd = fd;
19830                    proc.thread.profilerControl(start, profilerInfo, profileType);
19831                    fd = null;
19832                    mProfileFd = null;
19833                } else {
19834                    stopProfilerLocked(proc, profileType);
19835                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19836                        try {
19837                            profilerInfo.profileFd.close();
19838                        } catch (IOException e) {
19839                        }
19840                    }
19841                }
19842
19843                return true;
19844            }
19845        } catch (RemoteException e) {
19846            throw new IllegalStateException("Process disappeared");
19847        } finally {
19848            if (profilerInfo != null && profilerInfo.profileFd != null) {
19849                try {
19850                    profilerInfo.profileFd.close();
19851                } catch (IOException e) {
19852                }
19853            }
19854        }
19855    }
19856
19857    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19858        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19859                userId, true, ALLOW_FULL_ONLY, callName, null);
19860        ProcessRecord proc = null;
19861        try {
19862            int pid = Integer.parseInt(process);
19863            synchronized (mPidsSelfLocked) {
19864                proc = mPidsSelfLocked.get(pid);
19865            }
19866        } catch (NumberFormatException e) {
19867        }
19868
19869        if (proc == null) {
19870            ArrayMap<String, SparseArray<ProcessRecord>> all
19871                    = mProcessNames.getMap();
19872            SparseArray<ProcessRecord> procs = all.get(process);
19873            if (procs != null && procs.size() > 0) {
19874                proc = procs.valueAt(0);
19875                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19876                    for (int i=1; i<procs.size(); i++) {
19877                        ProcessRecord thisProc = procs.valueAt(i);
19878                        if (thisProc.userId == userId) {
19879                            proc = thisProc;
19880                            break;
19881                        }
19882                    }
19883                }
19884            }
19885        }
19886
19887        return proc;
19888    }
19889
19890    public boolean dumpHeap(String process, int userId, boolean managed,
19891            String path, ParcelFileDescriptor fd) throws RemoteException {
19892
19893        try {
19894            synchronized (this) {
19895                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19896                // its own permission (same as profileControl).
19897                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19898                        != PackageManager.PERMISSION_GRANTED) {
19899                    throw new SecurityException("Requires permission "
19900                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19901                }
19902
19903                if (fd == null) {
19904                    throw new IllegalArgumentException("null fd");
19905                }
19906
19907                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19908                if (proc == null || proc.thread == null) {
19909                    throw new IllegalArgumentException("Unknown process: " + process);
19910                }
19911
19912                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19913                if (!isDebuggable) {
19914                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19915                        throw new SecurityException("Process not debuggable: " + proc);
19916                    }
19917                }
19918
19919                proc.thread.dumpHeap(managed, path, fd);
19920                fd = null;
19921                return true;
19922            }
19923        } catch (RemoteException e) {
19924            throw new IllegalStateException("Process disappeared");
19925        } finally {
19926            if (fd != null) {
19927                try {
19928                    fd.close();
19929                } catch (IOException e) {
19930                }
19931            }
19932        }
19933    }
19934
19935    @Override
19936    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19937            String reportPackage) {
19938        if (processName != null) {
19939            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19940                    "setDumpHeapDebugLimit()");
19941        } else {
19942            synchronized (mPidsSelfLocked) {
19943                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19944                if (proc == null) {
19945                    throw new SecurityException("No process found for calling pid "
19946                            + Binder.getCallingPid());
19947                }
19948                if (!Build.IS_DEBUGGABLE
19949                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19950                    throw new SecurityException("Not running a debuggable build");
19951                }
19952                processName = proc.processName;
19953                uid = proc.uid;
19954                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19955                    throw new SecurityException("Package " + reportPackage + " is not running in "
19956                            + proc);
19957                }
19958            }
19959        }
19960        synchronized (this) {
19961            if (maxMemSize > 0) {
19962                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19963            } else {
19964                if (uid != 0) {
19965                    mMemWatchProcesses.remove(processName, uid);
19966                } else {
19967                    mMemWatchProcesses.getMap().remove(processName);
19968                }
19969            }
19970        }
19971    }
19972
19973    @Override
19974    public void dumpHeapFinished(String path) {
19975        synchronized (this) {
19976            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19977                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19978                        + " does not match last pid " + mMemWatchDumpPid);
19979                return;
19980            }
19981            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19982                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19983                        + " does not match last path " + mMemWatchDumpFile);
19984                return;
19985            }
19986            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19987            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19988        }
19989    }
19990
19991    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19992    public void monitor() {
19993        synchronized (this) { }
19994    }
19995
19996    void onCoreSettingsChange(Bundle settings) {
19997        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19998            ProcessRecord processRecord = mLruProcesses.get(i);
19999            try {
20000                if (processRecord.thread != null) {
20001                    processRecord.thread.setCoreSettings(settings);
20002                }
20003            } catch (RemoteException re) {
20004                /* ignore */
20005            }
20006        }
20007    }
20008
20009    // Multi-user methods
20010
20011    /**
20012     * Start user, if its not already running, but don't bring it to foreground.
20013     */
20014    @Override
20015    public boolean startUserInBackground(final int userId) {
20016        return mUserController.startUser(userId, /* foreground */ false);
20017    }
20018
20019    /**
20020     * Start user, if its not already running, and bring it to foreground.
20021     */
20022    boolean startUserInForeground(final int userId, Dialog dlg) {
20023        boolean result = mUserController.startUser(userId, /* foreground */ true);
20024        dlg.dismiss();
20025        return result;
20026    }
20027
20028    private Set<Integer> getProfileIdsLocked(int userId) {
20029        Set<Integer> userIds = new HashSet<Integer>();
20030        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20031                userId, false /* enabledOnly */);
20032        for (UserInfo user : profiles) {
20033            userIds.add(Integer.valueOf(user.id));
20034        }
20035        return userIds;
20036    }
20037
20038    @Override
20039    public boolean switchUser(final int userId) {
20040        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20041        String userName;
20042        synchronized (this) {
20043            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
20044            if (userInfo == null) {
20045                Slog.w(TAG, "No user info for user #" + userId);
20046                return false;
20047            }
20048            if (userInfo.isManagedProfile()) {
20049                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
20050                return false;
20051            }
20052            userName = userInfo.name;
20053            mUserController.mTargetUserId = userId;
20054        }
20055        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
20056        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
20057        return true;
20058    }
20059
20060    private void showUserSwitchDialog(int userId, String userName) {
20061        // The dialog will show and then initiate the user switch by calling startUserInForeground
20062        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
20063                true /* above system */);
20064        d.show();
20065    }
20066
20067    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20068        long ident = Binder.clearCallingIdentity();
20069        try {
20070            Intent intent;
20071            if (oldUserId >= 0) {
20072                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20073                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20074                int count = profiles.size();
20075                for (int i = 0; i < count; i++) {
20076                    int profileUserId = profiles.get(i).id;
20077                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20078                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20079                            | Intent.FLAG_RECEIVER_FOREGROUND);
20080                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20081                    broadcastIntentLocked(null, null, intent,
20082                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20083                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20084                }
20085            }
20086            if (newUserId >= 0) {
20087                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20088                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20089                int count = profiles.size();
20090                for (int i = 0; i < count; i++) {
20091                    int profileUserId = profiles.get(i).id;
20092                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20093                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20094                            | Intent.FLAG_RECEIVER_FOREGROUND);
20095                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20096                    broadcastIntentLocked(null, null, intent,
20097                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20098                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20099                }
20100                intent = new Intent(Intent.ACTION_USER_SWITCHED);
20101                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20102                        | Intent.FLAG_RECEIVER_FOREGROUND);
20103                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20104                broadcastIntentLocked(null, null, intent,
20105                        null, null, 0, null, null,
20106                        new String[] {android.Manifest.permission.MANAGE_USERS},
20107                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20108                        UserHandle.USER_ALL);
20109            }
20110        } finally {
20111            Binder.restoreCallingIdentity(ident);
20112        }
20113    }
20114
20115    void scheduleStartProfilesLocked() {
20116        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20117            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20118                    DateUtils.SECOND_IN_MILLIS);
20119        }
20120    }
20121
20122    @Override
20123    public int stopUser(final int userId, final IStopUserCallback callback) {
20124        return mUserController.stopUser(userId, callback);
20125    }
20126
20127    void onUserRemovedLocked(int userId) {
20128        mRecentTasks.removeTasksForUserLocked(userId);
20129    }
20130
20131    @Override
20132    public UserInfo getCurrentUser() {
20133        return mUserController.getCurrentUser();
20134    }
20135
20136    @Override
20137    public boolean isUserRunning(int userId, boolean orStopped) {
20138        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20139                != PackageManager.PERMISSION_GRANTED) {
20140            String msg = "Permission Denial: isUserRunning() from pid="
20141                    + Binder.getCallingPid()
20142                    + ", uid=" + Binder.getCallingUid()
20143                    + " requires " + INTERACT_ACROSS_USERS;
20144            Slog.w(TAG, msg);
20145            throw new SecurityException(msg);
20146        }
20147        synchronized (this) {
20148            return isUserRunningLocked(userId, orStopped);
20149        }
20150    }
20151
20152    boolean isUserRunningLocked(int userId, boolean orStopped) {
20153        UserState state = mUserController.getStartedUserState(userId);
20154        if (state == null) {
20155            return false;
20156        }
20157        if (orStopped) {
20158            return true;
20159        }
20160        return state.mState != UserState.STATE_STOPPING
20161                && state.mState != UserState.STATE_SHUTDOWN;
20162    }
20163
20164    @Override
20165    public int[] getRunningUserIds() {
20166        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20167                != PackageManager.PERMISSION_GRANTED) {
20168            String msg = "Permission Denial: isUserRunning() from pid="
20169                    + Binder.getCallingPid()
20170                    + ", uid=" + Binder.getCallingUid()
20171                    + " requires " + INTERACT_ACROSS_USERS;
20172            Slog.w(TAG, msg);
20173            throw new SecurityException(msg);
20174        }
20175        synchronized (this) {
20176            return mUserController.getStartedUserArrayLocked();
20177        }
20178    }
20179
20180    @Override
20181    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20182        mUserController.registerUserSwitchObserver(observer);
20183    }
20184
20185    @Override
20186    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20187        mUserController.unregisterUserSwitchObserver(observer);
20188    }
20189
20190    int[] getUsersLocked() {
20191        UserManagerService ums = getUserManagerLocked();
20192        return ums != null ? ums.getUserIds() : new int[] { 0 };
20193    }
20194
20195    UserManagerService getUserManagerLocked() {
20196        if (mUserManager == null) {
20197            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20198            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20199        }
20200        return mUserManager;
20201    }
20202
20203    private int applyUserId(int uid, int userId) {
20204        return UserHandle.getUid(userId, uid);
20205    }
20206
20207    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20208        if (info == null) return null;
20209        ApplicationInfo newInfo = new ApplicationInfo(info);
20210        newInfo.uid = applyUserId(info.uid, userId);
20211        newInfo.dataDir = Environment
20212                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20213                .getAbsolutePath();
20214        return newInfo;
20215    }
20216
20217    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20218        if (aInfo == null
20219                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20220            return aInfo;
20221        }
20222
20223        ActivityInfo info = new ActivityInfo(aInfo);
20224        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20225        return info;
20226    }
20227
20228    private boolean processSanityChecksLocked(ProcessRecord process) {
20229        if (process == null || process.thread == null) {
20230            return false;
20231        }
20232
20233        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20234        if (!isDebuggable) {
20235            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20236                return false;
20237            }
20238        }
20239
20240        return true;
20241    }
20242
20243    public boolean startBinderTracking() throws RemoteException {
20244        synchronized (this) {
20245            mBinderTransactionTrackingEnabled = true;
20246            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20247            // permission (same as profileControl).
20248            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20249                    != PackageManager.PERMISSION_GRANTED) {
20250                throw new SecurityException("Requires permission "
20251                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20252            }
20253
20254            for (int i = 0; i < mLruProcesses.size(); i++) {
20255                ProcessRecord process = mLruProcesses.get(i);
20256                if (!processSanityChecksLocked(process)) {
20257                    continue;
20258                }
20259                try {
20260                    process.thread.startBinderTracking();
20261                } catch (RemoteException e) {
20262                    Log.v(TAG, "Process disappared");
20263                }
20264            }
20265            return true;
20266        }
20267    }
20268
20269    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20270        try {
20271            synchronized (this) {
20272                mBinderTransactionTrackingEnabled = false;
20273                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20274                // permission (same as profileControl).
20275                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20276                        != PackageManager.PERMISSION_GRANTED) {
20277                    throw new SecurityException("Requires permission "
20278                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20279                }
20280
20281                if (fd == null) {
20282                    throw new IllegalArgumentException("null fd");
20283                }
20284
20285                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20286                pw.println("Binder transaction traces for all processes.\n");
20287                for (ProcessRecord process : mLruProcesses) {
20288                    if (!processSanityChecksLocked(process)) {
20289                        continue;
20290                    }
20291
20292                    pw.println("Traces for process: " + process.processName);
20293                    pw.flush();
20294                    try {
20295                        TransferPipe tp = new TransferPipe();
20296                        try {
20297                            process.thread.stopBinderTrackingAndDump(
20298                                    tp.getWriteFd().getFileDescriptor());
20299                            tp.go(fd.getFileDescriptor());
20300                        } finally {
20301                            tp.kill();
20302                        }
20303                    } catch (IOException e) {
20304                        pw.println("Failure while dumping IPC traces from " + process +
20305                                ".  Exception: " + e);
20306                        pw.flush();
20307                    } catch (RemoteException e) {
20308                        pw.println("Got a RemoteException while dumping IPC traces from " +
20309                                process + ".  Exception: " + e);
20310                        pw.flush();
20311                    }
20312                }
20313                fd = null;
20314                return true;
20315            }
20316        } finally {
20317            if (fd != null) {
20318                try {
20319                    fd.close();
20320                } catch (IOException e) {
20321                }
20322            }
20323        }
20324    }
20325
20326    void stopReportingCrashesLocked(ProcessRecord proc) {
20327        if (mAppsNotReportingCrashes == null) {
20328            mAppsNotReportingCrashes = new ArraySet<>();
20329        }
20330        mAppsNotReportingCrashes.add(proc.info.packageName);
20331    }
20332
20333    private final class LocalService extends ActivityManagerInternal {
20334        @Override
20335        public void onWakefulnessChanged(int wakefulness) {
20336            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20337        }
20338
20339        @Override
20340        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20341                String processName, String abiOverride, int uid, Runnable crashHandler) {
20342            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20343                    processName, abiOverride, uid, crashHandler);
20344        }
20345
20346        @Override
20347        public SleepToken acquireSleepToken(String tag) {
20348            Preconditions.checkNotNull(tag);
20349
20350            synchronized (ActivityManagerService.this) {
20351                SleepTokenImpl token = new SleepTokenImpl(tag);
20352                mSleepTokens.add(token);
20353                updateSleepIfNeededLocked();
20354                return token;
20355            }
20356        }
20357
20358        @Override
20359        public ComponentName getHomeActivityForUser(int userId) {
20360            synchronized (ActivityManagerService.this) {
20361                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20362                return homeActivity == null ? null : homeActivity.realActivity;
20363            }
20364        }
20365
20366        @Override
20367        public void onUserRemoved(int userId) {
20368            synchronized (ActivityManagerService.this) {
20369                ActivityManagerService.this.onUserRemovedLocked(userId);
20370            }
20371        }
20372    }
20373
20374    private final class SleepTokenImpl extends SleepToken {
20375        private final String mTag;
20376        private final long mAcquireTime;
20377
20378        public SleepTokenImpl(String tag) {
20379            mTag = tag;
20380            mAcquireTime = SystemClock.uptimeMillis();
20381        }
20382
20383        @Override
20384        public void release() {
20385            synchronized (ActivityManagerService.this) {
20386                if (mSleepTokens.remove(this)) {
20387                    updateSleepIfNeededLocked();
20388                }
20389            }
20390        }
20391
20392        @Override
20393        public String toString() {
20394            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20395        }
20396    }
20397
20398    /**
20399     * An implementation of IAppTask, that allows an app to manage its own tasks via
20400     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20401     * only the process that calls getAppTasks() can call the AppTask methods.
20402     */
20403    class AppTaskImpl extends IAppTask.Stub {
20404        private int mTaskId;
20405        private int mCallingUid;
20406
20407        public AppTaskImpl(int taskId, int callingUid) {
20408            mTaskId = taskId;
20409            mCallingUid = callingUid;
20410        }
20411
20412        private void checkCaller() {
20413            if (mCallingUid != Binder.getCallingUid()) {
20414                throw new SecurityException("Caller " + mCallingUid
20415                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20416            }
20417        }
20418
20419        @Override
20420        public void finishAndRemoveTask() {
20421            checkCaller();
20422
20423            synchronized (ActivityManagerService.this) {
20424                long origId = Binder.clearCallingIdentity();
20425                try {
20426                    // We remove the task from recents to preserve backwards
20427                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20428                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20429                    }
20430                } finally {
20431                    Binder.restoreCallingIdentity(origId);
20432                }
20433            }
20434        }
20435
20436        @Override
20437        public ActivityManager.RecentTaskInfo getTaskInfo() {
20438            checkCaller();
20439
20440            synchronized (ActivityManagerService.this) {
20441                long origId = Binder.clearCallingIdentity();
20442                try {
20443                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20444                    if (tr == null) {
20445                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20446                    }
20447                    return createRecentTaskInfoFromTaskRecord(tr);
20448                } finally {
20449                    Binder.restoreCallingIdentity(origId);
20450                }
20451            }
20452        }
20453
20454        @Override
20455        public void moveToFront() {
20456            checkCaller();
20457            // Will bring task to front if it already has a root activity.
20458            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20459        }
20460
20461        @Override
20462        public int startActivity(IBinder whoThread, String callingPackage,
20463                Intent intent, String resolvedType, Bundle options) {
20464            checkCaller();
20465
20466            int callingUser = UserHandle.getCallingUserId();
20467            TaskRecord tr;
20468            IApplicationThread appThread;
20469            synchronized (ActivityManagerService.this) {
20470                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20471                if (tr == null) {
20472                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20473                }
20474                appThread = ApplicationThreadNative.asInterface(whoThread);
20475                if (appThread == null) {
20476                    throw new IllegalArgumentException("Bad app thread " + appThread);
20477                }
20478            }
20479            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20480                    resolvedType, null, null, null, null, 0, 0, null, null,
20481                    null, options, false, callingUser, null, tr);
20482        }
20483
20484        @Override
20485        public void setExcludeFromRecents(boolean exclude) {
20486            checkCaller();
20487
20488            synchronized (ActivityManagerService.this) {
20489                long origId = Binder.clearCallingIdentity();
20490                try {
20491                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20492                    if (tr == null) {
20493                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20494                    }
20495                    Intent intent = tr.getBaseIntent();
20496                    if (exclude) {
20497                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20498                    } else {
20499                        intent.setFlags(intent.getFlags()
20500                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20501                    }
20502                } finally {
20503                    Binder.restoreCallingIdentity(origId);
20504                }
20505            }
20506        }
20507    }
20508}
20509