ActivityManagerService.java revision 99b6043dad9d215cf15810b885b6b8c215dd5b5a
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.READ_EXTERNAL_STORAGE;
22import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
23import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
24import static android.content.pm.PackageManager.PERMISSION_GRANTED;
25import static com.android.internal.util.XmlUtils.readBooleanAttribute;
26import static com.android.internal.util.XmlUtils.readIntAttribute;
27import static com.android.internal.util.XmlUtils.readLongAttribute;
28import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
29import static com.android.internal.util.XmlUtils.writeIntAttribute;
30import static com.android.internal.util.XmlUtils.writeLongAttribute;
31import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
32import static com.android.server.am.ActivityManagerDebugConfig.*;
33import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
34import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
36import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
37import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
38import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
39import static org.xmlpull.v1.XmlPullParser.START_TAG;
40
41import android.Manifest;
42import android.app.AppOpsManager;
43import android.app.ApplicationThreadNative;
44import android.app.BroadcastOptions;
45import android.app.IActivityContainer;
46import android.app.IActivityContainerCallback;
47import android.app.IAppTask;
48import android.app.ITaskStackListener;
49import android.app.ProfilerInfo;
50import android.app.assist.AssistContent;
51import android.app.assist.AssistStructure;
52import android.app.usage.UsageEvents;
53import android.app.usage.UsageStatsManagerInternal;
54import android.appwidget.AppWidgetManager;
55import android.content.pm.PermissionInfo;
56import android.content.res.Resources;
57import android.graphics.Bitmap;
58import android.graphics.Point;
59import android.graphics.Rect;
60import android.os.BatteryStats;
61import android.os.PersistableBundle;
62import android.os.PowerManager;
63import android.os.Trace;
64import android.os.TransactionTooLargeException;
65import android.os.WorkSource;
66import android.os.storage.IMountService;
67import android.os.storage.StorageManager;
68import android.service.voice.IVoiceInteractionSession;
69import android.util.ArrayMap;
70import android.util.ArraySet;
71import android.util.DebugUtils;
72import android.util.SparseIntArray;
73import android.view.Display;
74
75import com.android.internal.R;
76import com.android.internal.annotations.GuardedBy;
77import com.android.internal.app.DumpHeapActivity;
78import com.android.internal.app.IAppOpsService;
79import com.android.internal.app.IVoiceInteractor;
80import com.android.internal.app.ProcessMap;
81import com.android.internal.app.ProcessStats;
82import com.android.internal.os.BackgroundThread;
83import com.android.internal.os.BatteryStatsImpl;
84import com.android.internal.os.IResultReceiver;
85import com.android.internal.os.ProcessCpuTracker;
86import com.android.internal.os.TransferPipe;
87import com.android.internal.os.Zygote;
88import com.android.internal.util.ArrayUtils;
89import com.android.internal.util.FastPrintWriter;
90import com.android.internal.util.FastXmlSerializer;
91import com.android.internal.util.MemInfoReader;
92import com.android.internal.util.Preconditions;
93import com.android.server.AppOpsService;
94import com.android.server.AttributeCache;
95import com.android.server.DeviceIdleController;
96import com.android.server.IntentResolver;
97import com.android.server.LocalServices;
98import com.android.server.ServiceThread;
99import com.android.server.SystemService;
100import com.android.server.SystemServiceManager;
101import com.android.server.Watchdog;
102import com.android.server.am.ActivityStack.ActivityState;
103import com.android.server.firewall.IntentFirewall;
104import com.android.server.pm.Installer;
105import com.android.server.pm.UserManagerService;
106import com.android.server.statusbar.StatusBarManagerInternal;
107import com.android.server.wm.AppTransition;
108import com.android.server.wm.WindowManagerService;
109import com.google.android.collect.Lists;
110import com.google.android.collect.Maps;
111
112import libcore.io.IoUtils;
113import libcore.util.EmptyArray;
114
115import org.xmlpull.v1.XmlPullParser;
116import org.xmlpull.v1.XmlPullParserException;
117import org.xmlpull.v1.XmlSerializer;
118
119import android.app.Activity;
120import android.app.ActivityManager;
121import android.app.ActivityManager.RunningTaskInfo;
122import android.app.ActivityManager.StackInfo;
123import android.app.ActivityManagerInternal;
124import android.app.ActivityManagerInternal.SleepToken;
125import android.app.ActivityManagerNative;
126import android.app.ActivityOptions;
127import android.app.ActivityThread;
128import android.app.AlertDialog;
129import android.app.AppGlobals;
130import android.app.ApplicationErrorReport;
131import android.app.Dialog;
132import android.app.IActivityController;
133import android.app.IApplicationThread;
134import android.app.IInstrumentationWatcher;
135import android.app.INotificationManager;
136import android.app.IProcessObserver;
137import android.app.IServiceConnection;
138import android.app.IStopUserCallback;
139import android.app.IUidObserver;
140import android.app.IUiAutomationConnection;
141import android.app.IUserSwitchObserver;
142import android.app.Instrumentation;
143import android.app.Notification;
144import android.app.NotificationManager;
145import android.app.PendingIntent;
146import android.app.backup.IBackupManager;
147import android.app.admin.DevicePolicyManager;
148import android.content.ActivityNotFoundException;
149import android.content.BroadcastReceiver;
150import android.content.ClipData;
151import android.content.ComponentCallbacks2;
152import android.content.ComponentName;
153import android.content.ContentProvider;
154import android.content.ContentResolver;
155import android.content.Context;
156import android.content.DialogInterface;
157import android.content.IContentProvider;
158import android.content.IIntentReceiver;
159import android.content.IIntentSender;
160import android.content.Intent;
161import android.content.IntentFilter;
162import android.content.IntentSender;
163import android.content.pm.ActivityInfo;
164import android.content.pm.ApplicationInfo;
165import android.content.pm.ConfigurationInfo;
166import android.content.pm.IPackageDataObserver;
167import android.content.pm.IPackageManager;
168import android.content.pm.InstrumentationInfo;
169import android.content.pm.PackageInfo;
170import android.content.pm.PackageManager;
171import android.content.pm.ParceledListSlice;
172import android.content.pm.UserInfo;
173import android.content.pm.PackageManager.NameNotFoundException;
174import android.content.pm.PathPermission;
175import android.content.pm.ProviderInfo;
176import android.content.pm.ResolveInfo;
177import android.content.pm.ServiceInfo;
178import android.content.res.CompatibilityInfo;
179import android.content.res.Configuration;
180import android.net.Proxy;
181import android.net.ProxyInfo;
182import android.net.Uri;
183import android.os.Binder;
184import android.os.Build;
185import android.os.Bundle;
186import android.os.Debug;
187import android.os.DropBoxManager;
188import android.os.Environment;
189import android.os.FactoryTest;
190import android.os.FileObserver;
191import android.os.FileUtils;
192import android.os.Handler;
193import android.os.IBinder;
194import android.os.IPermissionController;
195import android.os.IProcessInfoService;
196import android.os.IRemoteCallback;
197import android.os.IUserManager;
198import android.os.Looper;
199import android.os.Message;
200import android.os.Parcel;
201import android.os.ParcelFileDescriptor;
202import android.os.PowerManagerInternal;
203import android.os.Process;
204import android.os.RemoteCallbackList;
205import android.os.RemoteException;
206import android.os.SELinux;
207import android.os.ServiceManager;
208import android.os.StrictMode;
209import android.os.SystemClock;
210import android.os.SystemProperties;
211import android.os.UpdateLock;
212import android.os.UserHandle;
213import android.os.UserManager;
214import android.provider.Settings;
215import android.text.format.DateUtils;
216import android.text.format.Time;
217import android.util.AtomicFile;
218import android.util.EventLog;
219import android.util.Log;
220import android.util.Pair;
221import android.util.PrintWriterPrinter;
222import android.util.Slog;
223import android.util.SparseArray;
224import android.util.TimeUtils;
225import android.util.Xml;
226import android.view.Gravity;
227import android.view.LayoutInflater;
228import android.view.View;
229import android.view.WindowManager;
230
231import dalvik.system.VMRuntime;
232
233import java.io.BufferedInputStream;
234import java.io.BufferedOutputStream;
235import java.io.DataInputStream;
236import java.io.DataOutputStream;
237import java.io.File;
238import java.io.FileDescriptor;
239import java.io.FileInputStream;
240import java.io.FileNotFoundException;
241import java.io.FileOutputStream;
242import java.io.IOException;
243import java.io.InputStreamReader;
244import java.io.PrintWriter;
245import java.io.StringWriter;
246import java.lang.ref.WeakReference;
247import java.nio.charset.StandardCharsets;
248import java.util.ArrayList;
249import java.util.Arrays;
250import java.util.Collections;
251import java.util.Comparator;
252import java.util.HashMap;
253import java.util.HashSet;
254import java.util.Iterator;
255import java.util.List;
256import java.util.Locale;
257import java.util.Map;
258import java.util.Set;
259import java.util.concurrent.atomic.AtomicBoolean;
260import java.util.concurrent.atomic.AtomicLong;
261
262public final class ActivityManagerService extends ActivityManagerNative
263        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
264
265    // File that stores last updated system version and called preboot receivers
266    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
267
268    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
269    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
270    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
271    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
272    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
273    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
274    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
275    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
276    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
277    private static final String TAG_LRU = TAG + POSTFIX_LRU;
278    private static final String TAG_MU = TAG + POSTFIX_MU;
279    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
280    private static final String TAG_POWER = TAG + POSTFIX_POWER;
281    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
282    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
283    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
284    private static final String TAG_PSS = TAG + POSTFIX_PSS;
285    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
286    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
287    private static final String TAG_STACK = TAG + POSTFIX_STACK;
288    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
289    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
290    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
291    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
292    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
293
294    /** Control over CPU and battery monitoring */
295    // write battery stats every 30 minutes.
296    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
297    static final boolean MONITOR_CPU_USAGE = true;
298    // don't sample cpu less than every 5 seconds.
299    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
300    // wait possibly forever for next cpu sample.
301    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
302    static final boolean MONITOR_THREAD_CPU_USAGE = false;
303
304    // The flags that are set for all calls we make to the package manager.
305    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
306
307    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
308
309    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
310
311    // Amount of time after a call to stopAppSwitches() during which we will
312    // prevent further untrusted switches from happening.
313    static final long APP_SWITCH_DELAY_TIME = 5*1000;
314
315    // How long we wait for a launched process to attach to the activity manager
316    // before we decide it's never going to come up for real.
317    static final int PROC_START_TIMEOUT = 10*1000;
318
319    // How long we wait for a launched process to attach to the activity manager
320    // before we decide it's never going to come up for real, when the process was
321    // started with a wrapper for instrumentation (such as Valgrind) because it
322    // could take much longer than usual.
323    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
324
325    // How long to wait after going idle before forcing apps to GC.
326    static final int GC_TIMEOUT = 5*1000;
327
328    // The minimum amount of time between successive GC requests for a process.
329    static final int GC_MIN_INTERVAL = 60*1000;
330
331    // The minimum amount of time between successive PSS requests for a process.
332    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
333
334    // The minimum amount of time between successive PSS requests for a process
335    // when the request is due to the memory state being lowered.
336    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
337
338    // The rate at which we check for apps using excessive power -- 15 mins.
339    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
340
341    // The minimum sample duration we will allow before deciding we have
342    // enough data on wake locks to start killing things.
343    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
344
345    // The minimum sample duration we will allow before deciding we have
346    // enough data on CPU usage to start killing things.
347    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
348
349    // How long we allow a receiver to run before giving up on it.
350    static final int BROADCAST_FG_TIMEOUT = 10*1000;
351    static final int BROADCAST_BG_TIMEOUT = 60*1000;
352
353    // How long we wait until we timeout on key dispatching.
354    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
355
356    // How long we wait until we timeout on key dispatching during instrumentation.
357    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
358
359    // Amount of time we wait for observers to handle a user switch before
360    // giving up on them and unfreezing the screen.
361    static final int USER_SWITCH_TIMEOUT = 2*1000;
362
363    // This is the amount of time an app needs to be running a foreground service before
364    // we will consider it to be doing interaction for usage stats.
365    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
366
367    // Maximum number of users we allow to be running at a time.
368    static final int MAX_RUNNING_USERS = 3;
369
370    // How long to wait in getAssistContextExtras for the activity and foreground services
371    // to respond with the result.
372    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
373
374    // How long top wait when going through the modern assist (which doesn't need to block
375    // on getting this result before starting to launch its UI).
376    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
377
378    // Maximum number of persisted Uri grants a package is allowed
379    static final int MAX_PERSISTED_URI_GRANTS = 128;
380
381    static final int MY_PID = Process.myPid();
382
383    static final String[] EMPTY_STRING_ARRAY = new String[0];
384
385    // How many bytes to write into the dropbox log before truncating
386    static final int DROPBOX_MAX_SIZE = 256 * 1024;
387
388    // Access modes for handleIncomingUser.
389    static final int ALLOW_NON_FULL = 0;
390    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
391    static final int ALLOW_FULL_ONLY = 2;
392
393    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
394
395    // Delay in notifying task stack change listeners (in millis)
396    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
397
398    // Necessary ApplicationInfo flags to mark an app as persistent
399    private static final int PERSISTENT_MASK =
400            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
401
402    /** All system services */
403    SystemServiceManager mSystemServiceManager;
404
405    private Installer mInstaller;
406
407    /** Run all ActivityStacks through this */
408    ActivityStackSupervisor mStackSupervisor;
409
410    /** Task stack change listeners. */
411    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
412            new RemoteCallbackList<ITaskStackListener>();
413
414    public IntentFirewall mIntentFirewall;
415
416    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
417    // default actuion automatically.  Important for devices without direct input
418    // devices.
419    private boolean mShowDialogs = true;
420
421    BroadcastQueue mFgBroadcastQueue;
422    BroadcastQueue mBgBroadcastQueue;
423    // Convenient for easy iteration over the queues. Foreground is first
424    // so that dispatch of foreground broadcasts gets precedence.
425    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
426
427    BroadcastQueue broadcastQueueForIntent(Intent intent) {
428        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
429        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
430                "Broadcast intent " + intent + " on "
431                + (isFg ? "foreground" : "background") + " queue");
432        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
433    }
434
435    /**
436     * Activity we have told the window manager to have key focus.
437     */
438    ActivityRecord mFocusedActivity = null;
439
440    /**
441     * User id of the last activity mFocusedActivity was set to.
442     */
443    private int mLastFocusedUserId;
444
445    /**
446     * If non-null, we are tracking the time the user spends in the currently focused app.
447     */
448    private AppTimeTracker mCurAppTimeTracker;
449
450    /**
451     * List of intents that were used to start the most recent tasks.
452     */
453    private final RecentTasks mRecentTasks;
454
455    /**
456     * For addAppTask: cached of the last activity component that was added.
457     */
458    ComponentName mLastAddedTaskComponent;
459
460    /**
461     * For addAppTask: cached of the last activity uid that was added.
462     */
463    int mLastAddedTaskUid;
464
465    /**
466     * For addAppTask: cached of the last ActivityInfo that was added.
467     */
468    ActivityInfo mLastAddedTaskActivity;
469
470    /**
471     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
472     */
473    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
474
475    /**
476     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
477     */
478    String mDeviceOwnerName;
479
480    public class PendingAssistExtras extends Binder implements Runnable {
481        public final ActivityRecord activity;
482        public final Bundle extras;
483        public final Intent intent;
484        public final String hint;
485        public final IResultReceiver receiver;
486        public final int userHandle;
487        public boolean haveResult = false;
488        public Bundle result = null;
489        public AssistStructure structure = null;
490        public AssistContent content = null;
491        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
492                String _hint, IResultReceiver _receiver, int _userHandle) {
493            activity = _activity;
494            extras = _extras;
495            intent = _intent;
496            hint = _hint;
497            receiver = _receiver;
498            userHandle = _userHandle;
499        }
500        @Override
501        public void run() {
502            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
503            synchronized (ActivityManagerService.this) {
504                synchronized (this) {
505                    haveResult = true;
506                    notifyAll();
507                }
508                pendingAssistExtrasTimedOutLocked(this);
509            }
510        }
511    }
512
513    final ArrayList<PendingAssistExtras> mPendingAssistExtras
514            = new ArrayList<PendingAssistExtras>();
515
516    /**
517     * Process management.
518     */
519    final ProcessList mProcessList = new ProcessList();
520
521    /**
522     * All of the applications we currently have running organized by name.
523     * The keys are strings of the application package name (as
524     * returned by the package manager), and the keys are ApplicationRecord
525     * objects.
526     */
527    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
528
529    /**
530     * Tracking long-term execution of processes to look for abuse and other
531     * bad app behavior.
532     */
533    final ProcessStatsService mProcessStats;
534
535    /**
536     * The currently running isolated processes.
537     */
538    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
539
540    /**
541     * Counter for assigning isolated process uids, to avoid frequently reusing the
542     * same ones.
543     */
544    int mNextIsolatedProcessUid = 0;
545
546    /**
547     * The currently running heavy-weight process, if any.
548     */
549    ProcessRecord mHeavyWeightProcess = null;
550
551    /**
552     * The last time that various processes have crashed.
553     */
554    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
555
556    /**
557     * Information about a process that is currently marked as bad.
558     */
559    static final class BadProcessInfo {
560        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
561            this.time = time;
562            this.shortMsg = shortMsg;
563            this.longMsg = longMsg;
564            this.stack = stack;
565        }
566
567        final long time;
568        final String shortMsg;
569        final String longMsg;
570        final String stack;
571    }
572
573    /**
574     * Set of applications that we consider to be bad, and will reject
575     * incoming broadcasts from (which the user has no control over).
576     * Processes are added to this set when they have crashed twice within
577     * a minimum amount of time; they are removed from it when they are
578     * later restarted (hopefully due to some user action).  The value is the
579     * time it was added to the list.
580     */
581    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
582
583    /**
584     * All of the processes we currently have running organized by pid.
585     * The keys are the pid running the application.
586     *
587     * <p>NOTE: This object is protected by its own lock, NOT the global
588     * activity manager lock!
589     */
590    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
591
592    /**
593     * All of the processes that have been forced to be foreground.  The key
594     * is the pid of the caller who requested it (we hold a death
595     * link on it).
596     */
597    abstract class ForegroundToken implements IBinder.DeathRecipient {
598        int pid;
599        IBinder token;
600    }
601    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
602
603    /**
604     * List of records for processes that someone had tried to start before the
605     * system was ready.  We don't start them at that point, but ensure they
606     * are started by the time booting is complete.
607     */
608    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
609
610    /**
611     * List of persistent applications that are in the process
612     * of being started.
613     */
614    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
615
616    /**
617     * Processes that are being forcibly torn down.
618     */
619    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
620
621    /**
622     * List of running applications, sorted by recent usage.
623     * The first entry in the list is the least recently used.
624     */
625    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
626
627    /**
628     * Where in mLruProcesses that the processes hosting activities start.
629     */
630    int mLruProcessActivityStart = 0;
631
632    /**
633     * Where in mLruProcesses that the processes hosting services start.
634     * This is after (lower index) than mLruProcessesActivityStart.
635     */
636    int mLruProcessServiceStart = 0;
637
638    /**
639     * List of processes that should gc as soon as things are idle.
640     */
641    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
642
643    /**
644     * Processes we want to collect PSS data from.
645     */
646    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
647
648    /**
649     * Last time we requested PSS data of all processes.
650     */
651    long mLastFullPssTime = SystemClock.uptimeMillis();
652
653    /**
654     * If set, the next time we collect PSS data we should do a full collection
655     * with data from native processes and the kernel.
656     */
657    boolean mFullPssPending = false;
658
659    /**
660     * This is the process holding what we currently consider to be
661     * the "home" activity.
662     */
663    ProcessRecord mHomeProcess;
664
665    /**
666     * This is the process holding the activity the user last visited that
667     * is in a different process from the one they are currently in.
668     */
669    ProcessRecord mPreviousProcess;
670
671    /**
672     * The time at which the previous process was last visible.
673     */
674    long mPreviousProcessVisibleTime;
675
676    /**
677     * Track all uids that have actively running processes.
678     */
679    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
680
681    /**
682     * Which users have been started, so are allowed to run code.
683     */
684    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
685
686    /**
687     * LRU list of history of current users.  Most recently current is at the end.
688     */
689    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
690
691    /**
692     * Constant array of the users that are currently started.
693     */
694    int[] mStartedUserArray = new int[] { 0 };
695
696    /**
697     * Registered observers of the user switching mechanics.
698     */
699    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
700            = new RemoteCallbackList<IUserSwitchObserver>();
701
702    /**
703     * Currently active user switch.
704     */
705    Object mCurUserSwitchCallback;
706
707    /**
708     * Packages that the user has asked to have run in screen size
709     * compatibility mode instead of filling the screen.
710     */
711    final CompatModePackages mCompatModePackages;
712
713    /**
714     * Set of IntentSenderRecord objects that are currently active.
715     */
716    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
717            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
718
719    /**
720     * Fingerprints (hashCode()) of stack traces that we've
721     * already logged DropBox entries for.  Guarded by itself.  If
722     * something (rogue user app) forces this over
723     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
724     */
725    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
726    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
727
728    /**
729     * Strict Mode background batched logging state.
730     *
731     * The string buffer is guarded by itself, and its lock is also
732     * used to determine if another batched write is already
733     * in-flight.
734     */
735    private final StringBuilder mStrictModeBuffer = new StringBuilder();
736
737    /**
738     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
739     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
740     */
741    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
742
743    /**
744     * Resolver for broadcast intents to registered receivers.
745     * Holds BroadcastFilter (subclass of IntentFilter).
746     */
747    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
748            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
749        @Override
750        protected boolean allowFilterResult(
751                BroadcastFilter filter, List<BroadcastFilter> dest) {
752            IBinder target = filter.receiverList.receiver.asBinder();
753            for (int i = dest.size() - 1; i >= 0; i--) {
754                if (dest.get(i).receiverList.receiver.asBinder() == target) {
755                    return false;
756                }
757            }
758            return true;
759        }
760
761        @Override
762        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
763            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
764                    || userId == filter.owningUserId) {
765                return super.newResult(filter, match, userId);
766            }
767            return null;
768        }
769
770        @Override
771        protected BroadcastFilter[] newArray(int size) {
772            return new BroadcastFilter[size];
773        }
774
775        @Override
776        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
777            return packageName.equals(filter.packageName);
778        }
779    };
780
781    /**
782     * State of all active sticky broadcasts per user.  Keys are the action of the
783     * sticky Intent, values are an ArrayList of all broadcasted intents with
784     * that action (which should usually be one).  The SparseArray is keyed
785     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
786     * for stickies that are sent to all users.
787     */
788    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
789            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
790
791    final ActiveServices mServices;
792
793    final static class Association {
794        final int mSourceUid;
795        final String mSourceProcess;
796        final int mTargetUid;
797        final ComponentName mTargetComponent;
798        final String mTargetProcess;
799
800        int mCount;
801        long mTime;
802
803        int mNesting;
804        long mStartTime;
805
806        Association(int sourceUid, String sourceProcess, int targetUid,
807                ComponentName targetComponent, String targetProcess) {
808            mSourceUid = sourceUid;
809            mSourceProcess = sourceProcess;
810            mTargetUid = targetUid;
811            mTargetComponent = targetComponent;
812            mTargetProcess = targetProcess;
813        }
814    }
815
816    /**
817     * When service association tracking is enabled, this is all of the associations we
818     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
819     * -> association data.
820     */
821    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
822            mAssociations = new SparseArray<>();
823    boolean mTrackingAssociations;
824
825    /**
826     * Backup/restore process management
827     */
828    String mBackupAppName = null;
829    BackupRecord mBackupTarget = null;
830
831    final ProviderMap mProviderMap;
832
833    /**
834     * List of content providers who have clients waiting for them.  The
835     * application is currently being launched and the provider will be
836     * removed from this list once it is published.
837     */
838    final ArrayList<ContentProviderRecord> mLaunchingProviders
839            = new ArrayList<ContentProviderRecord>();
840
841    /**
842     * File storing persisted {@link #mGrantedUriPermissions}.
843     */
844    private final AtomicFile mGrantFile;
845
846    /** XML constants used in {@link #mGrantFile} */
847    private static final String TAG_URI_GRANTS = "uri-grants";
848    private static final String TAG_URI_GRANT = "uri-grant";
849    private static final String ATTR_USER_HANDLE = "userHandle";
850    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
851    private static final String ATTR_TARGET_USER_ID = "targetUserId";
852    private static final String ATTR_SOURCE_PKG = "sourcePkg";
853    private static final String ATTR_TARGET_PKG = "targetPkg";
854    private static final String ATTR_URI = "uri";
855    private static final String ATTR_MODE_FLAGS = "modeFlags";
856    private static final String ATTR_CREATED_TIME = "createdTime";
857    private static final String ATTR_PREFIX = "prefix";
858
859    /**
860     * Global set of specific {@link Uri} permissions that have been granted.
861     * This optimized lookup structure maps from {@link UriPermission#targetUid}
862     * to {@link UriPermission#uri} to {@link UriPermission}.
863     */
864    @GuardedBy("this")
865    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
866            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
867
868    public static class GrantUri {
869        public final int sourceUserId;
870        public final Uri uri;
871        public boolean prefix;
872
873        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
874            this.sourceUserId = sourceUserId;
875            this.uri = uri;
876            this.prefix = prefix;
877        }
878
879        @Override
880        public int hashCode() {
881            int hashCode = 1;
882            hashCode = 31 * hashCode + sourceUserId;
883            hashCode = 31 * hashCode + uri.hashCode();
884            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
885            return hashCode;
886        }
887
888        @Override
889        public boolean equals(Object o) {
890            if (o instanceof GrantUri) {
891                GrantUri other = (GrantUri) o;
892                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
893                        && prefix == other.prefix;
894            }
895            return false;
896        }
897
898        @Override
899        public String toString() {
900            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
901            if (prefix) result += " [prefix]";
902            return result;
903        }
904
905        public String toSafeString() {
906            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
907            if (prefix) result += " [prefix]";
908            return result;
909        }
910
911        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
912            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
913                    ContentProvider.getUriWithoutUserId(uri), false);
914        }
915    }
916
917    CoreSettingsObserver mCoreSettingsObserver;
918
919    /**
920     * Thread-local storage used to carry caller permissions over through
921     * indirect content-provider access.
922     */
923    private class Identity {
924        public final IBinder token;
925        public final int pid;
926        public final int uid;
927
928        Identity(IBinder _token, int _pid, int _uid) {
929            token = _token;
930            pid = _pid;
931            uid = _uid;
932        }
933    }
934
935    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
936
937    /**
938     * All information we have collected about the runtime performance of
939     * any user id that can impact battery performance.
940     */
941    final BatteryStatsService mBatteryStatsService;
942
943    /**
944     * Information about component usage
945     */
946    UsageStatsManagerInternal mUsageStatsService;
947
948    /**
949     * Access to DeviceIdleController service.
950     */
951    DeviceIdleController.LocalService mLocalDeviceIdleController;
952
953    /**
954     * Information about and control over application operations
955     */
956    final AppOpsService mAppOpsService;
957
958    /**
959     * Save recent tasks information across reboots.
960     */
961    final TaskPersister mTaskPersister;
962
963    /**
964     * Current configuration information.  HistoryRecord objects are given
965     * a reference to this object to indicate which configuration they are
966     * currently running in, so this object must be kept immutable.
967     */
968    Configuration mConfiguration = new Configuration();
969
970    /**
971     * Current sequencing integer of the configuration, for skipping old
972     * configurations.
973     */
974    int mConfigurationSeq = 0;
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    IActivityController mController = null;
1195    String mProfileApp = null;
1196    ProcessRecord mProfileProc = null;
1197    String mProfileFile;
1198    ParcelFileDescriptor mProfileFd;
1199    int mSamplingInterval = 0;
1200    boolean mAutoStopProfiler = false;
1201    int mProfileType = 0;
1202    String mOpenGlTraceApp = null;
1203    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1204    String mMemWatchDumpProcName;
1205    String mMemWatchDumpFile;
1206    int mMemWatchDumpPid;
1207    int mMemWatchDumpUid;
1208
1209    final long[] mTmpLong = new long[1];
1210
1211    static final class ProcessChangeItem {
1212        static final int CHANGE_ACTIVITIES = 1<<0;
1213        static final int CHANGE_PROCESS_STATE = 1<<1;
1214        int changes;
1215        int uid;
1216        int pid;
1217        int processState;
1218        boolean foregroundActivities;
1219    }
1220
1221    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1222    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1223
1224    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1225    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1226
1227    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1228    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1229
1230    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1231    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1232
1233    /**
1234     * Runtime CPU use collection thread.  This object's lock is used to
1235     * perform synchronization with the thread (notifying it to run).
1236     */
1237    final Thread mProcessCpuThread;
1238
1239    /**
1240     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1241     * Must acquire this object's lock when accessing it.
1242     * NOTE: this lock will be held while doing long operations (trawling
1243     * through all processes in /proc), so it should never be acquired by
1244     * any critical paths such as when holding the main activity manager lock.
1245     */
1246    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1247            MONITOR_THREAD_CPU_USAGE);
1248    final AtomicLong mLastCpuTime = new AtomicLong(0);
1249    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1250
1251    long mLastWriteTime = 0;
1252
1253    /**
1254     * Used to retain an update lock when the foreground activity is in
1255     * immersive mode.
1256     */
1257    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1258
1259    /**
1260     * Set to true after the system has finished booting.
1261     */
1262    boolean mBooted = false;
1263
1264    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1265    int mProcessLimitOverride = -1;
1266
1267    WindowManagerService mWindowManager;
1268
1269    final ActivityThread mSystemThread;
1270
1271    // Holds the current foreground user's id
1272    int mCurrentUserId = 0;
1273    // Holds the target user's id during a user switch
1274    int mTargetUserId = UserHandle.USER_NULL;
1275    // If there are multiple profiles for the current user, their ids are here
1276    // Currently only the primary user can have managed profiles
1277    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1278
1279    /**
1280     * Mapping from each known user ID to the profile group ID it is associated with.
1281     */
1282    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1283
1284    private UserManagerService mUserManager;
1285
1286    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1287        final ProcessRecord mApp;
1288        final int mPid;
1289        final IApplicationThread mAppThread;
1290
1291        AppDeathRecipient(ProcessRecord app, int pid,
1292                IApplicationThread thread) {
1293            if (DEBUG_ALL) Slog.v(
1294                TAG, "New death recipient " + this
1295                + " for thread " + thread.asBinder());
1296            mApp = app;
1297            mPid = pid;
1298            mAppThread = thread;
1299        }
1300
1301        @Override
1302        public void binderDied() {
1303            if (DEBUG_ALL) Slog.v(
1304                TAG, "Death received in " + this
1305                + " for thread " + mAppThread.asBinder());
1306            synchronized(ActivityManagerService.this) {
1307                appDiedLocked(mApp, mPid, mAppThread, true);
1308            }
1309        }
1310    }
1311
1312    static final int SHOW_ERROR_MSG = 1;
1313    static final int SHOW_NOT_RESPONDING_MSG = 2;
1314    static final int SHOW_FACTORY_ERROR_MSG = 3;
1315    static final int UPDATE_CONFIGURATION_MSG = 4;
1316    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1317    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1318    static final int SERVICE_TIMEOUT_MSG = 12;
1319    static final int UPDATE_TIME_ZONE = 13;
1320    static final int SHOW_UID_ERROR_MSG = 14;
1321    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1322    static final int PROC_START_TIMEOUT_MSG = 20;
1323    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1324    static final int KILL_APPLICATION_MSG = 22;
1325    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1326    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1327    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1328    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1329    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1330    static final int CLEAR_DNS_CACHE_MSG = 28;
1331    static final int UPDATE_HTTP_PROXY_MSG = 29;
1332    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1333    static final int DISPATCH_PROCESSES_CHANGED = 31;
1334    static final int DISPATCH_PROCESS_DIED = 32;
1335    static final int REPORT_MEM_USAGE_MSG = 33;
1336    static final int REPORT_USER_SWITCH_MSG = 34;
1337    static final int CONTINUE_USER_SWITCH_MSG = 35;
1338    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1339    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1340    static final int PERSIST_URI_GRANTS_MSG = 38;
1341    static final int REQUEST_ALL_PSS_MSG = 39;
1342    static final int START_PROFILES_MSG = 40;
1343    static final int UPDATE_TIME = 41;
1344    static final int SYSTEM_USER_START_MSG = 42;
1345    static final int SYSTEM_USER_CURRENT_MSG = 43;
1346    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1347    static final int FINISH_BOOTING_MSG = 45;
1348    static final int START_USER_SWITCH_MSG = 46;
1349    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1350    static final int DISMISS_DIALOG_MSG = 48;
1351    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1352    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1353    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1354    static final int DELETE_DUMPHEAP_MSG = 52;
1355    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1356    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1357    static final int REPORT_TIME_TRACKER_MSG = 55;
1358
1359    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1360    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1361    static final int FIRST_COMPAT_MODE_MSG = 300;
1362    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1363
1364    CompatModeDialog mCompatModeDialog;
1365    long mLastMemUsageReportTime = 0;
1366
1367    /**
1368     * Flag whether the current user is a "monkey", i.e. whether
1369     * the UI is driven by a UI automation tool.
1370     */
1371    private boolean mUserIsMonkey;
1372
1373    /** Flag whether the device has a Recents UI */
1374    boolean mHasRecents;
1375
1376    /** The dimensions of the thumbnails in the Recents UI. */
1377    int mThumbnailWidth;
1378    int mThumbnailHeight;
1379
1380    final ServiceThread mHandlerThread;
1381    final MainHandler mHandler;
1382    final UiHandler mUiHandler;
1383
1384    final class UiHandler extends Handler {
1385        public UiHandler() {
1386            super(com.android.server.UiThread.get().getLooper(), null, true);
1387        }
1388
1389        @Override
1390        public void handleMessage(Message msg) {
1391            switch (msg.what) {
1392            case SHOW_ERROR_MSG: {
1393                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1394                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1395                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1396                synchronized (ActivityManagerService.this) {
1397                    ProcessRecord proc = (ProcessRecord)data.get("app");
1398                    AppErrorResult res = (AppErrorResult) data.get("result");
1399                    if (proc != null && proc.crashDialog != null) {
1400                        Slog.e(TAG, "App already has crash dialog: " + proc);
1401                        if (res != null) {
1402                            res.set(0);
1403                        }
1404                        return;
1405                    }
1406                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1407                            >= Process.FIRST_APPLICATION_UID
1408                            && proc.pid != MY_PID);
1409                    for (int userId : mCurrentProfileIds) {
1410                        isBackground &= (proc.userId != userId);
1411                    }
1412                    if (isBackground && !showBackground) {
1413                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1414                        if (res != null) {
1415                            res.set(0);
1416                        }
1417                        return;
1418                    }
1419                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1420                        Dialog d = new AppErrorDialog(mContext,
1421                                ActivityManagerService.this, res, proc);
1422                        d.show();
1423                        proc.crashDialog = d;
1424                    } else {
1425                        // The device is asleep, so just pretend that the user
1426                        // saw a crash dialog and hit "force quit".
1427                        if (res != null) {
1428                            res.set(0);
1429                        }
1430                    }
1431                }
1432
1433                ensureBootCompleted();
1434            } break;
1435            case SHOW_NOT_RESPONDING_MSG: {
1436                synchronized (ActivityManagerService.this) {
1437                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1438                    ProcessRecord proc = (ProcessRecord)data.get("app");
1439                    if (proc != null && proc.anrDialog != null) {
1440                        Slog.e(TAG, "App already has anr dialog: " + proc);
1441                        return;
1442                    }
1443
1444                    Intent intent = new Intent("android.intent.action.ANR");
1445                    if (!mProcessesReady) {
1446                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1447                                | Intent.FLAG_RECEIVER_FOREGROUND);
1448                    }
1449                    broadcastIntentLocked(null, null, intent,
1450                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1451                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1452
1453                    if (mShowDialogs) {
1454                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1455                                mContext, proc, (ActivityRecord)data.get("activity"),
1456                                msg.arg1 != 0);
1457                        d.show();
1458                        proc.anrDialog = d;
1459                    } else {
1460                        // Just kill the app if there is no dialog to be shown.
1461                        killAppAtUsersRequest(proc, null);
1462                    }
1463                }
1464
1465                ensureBootCompleted();
1466            } break;
1467            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1468                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1469                synchronized (ActivityManagerService.this) {
1470                    ProcessRecord proc = (ProcessRecord) data.get("app");
1471                    if (proc == null) {
1472                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1473                        break;
1474                    }
1475                    if (proc.crashDialog != null) {
1476                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1477                        return;
1478                    }
1479                    AppErrorResult res = (AppErrorResult) data.get("result");
1480                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1481                        Dialog d = new StrictModeViolationDialog(mContext,
1482                                ActivityManagerService.this, res, proc);
1483                        d.show();
1484                        proc.crashDialog = d;
1485                    } else {
1486                        // The device is asleep, so just pretend that the user
1487                        // saw a crash dialog and hit "force quit".
1488                        res.set(0);
1489                    }
1490                }
1491                ensureBootCompleted();
1492            } break;
1493            case SHOW_FACTORY_ERROR_MSG: {
1494                Dialog d = new FactoryErrorDialog(
1495                    mContext, msg.getData().getCharSequence("msg"));
1496                d.show();
1497                ensureBootCompleted();
1498            } break;
1499            case WAIT_FOR_DEBUGGER_MSG: {
1500                synchronized (ActivityManagerService.this) {
1501                    ProcessRecord app = (ProcessRecord)msg.obj;
1502                    if (msg.arg1 != 0) {
1503                        if (!app.waitedForDebugger) {
1504                            Dialog d = new AppWaitingForDebuggerDialog(
1505                                    ActivityManagerService.this,
1506                                    mContext, app);
1507                            app.waitDialog = d;
1508                            app.waitedForDebugger = true;
1509                            d.show();
1510                        }
1511                    } else {
1512                        if (app.waitDialog != null) {
1513                            app.waitDialog.dismiss();
1514                            app.waitDialog = null;
1515                        }
1516                    }
1517                }
1518            } break;
1519            case SHOW_UID_ERROR_MSG: {
1520                if (mShowDialogs) {
1521                    AlertDialog d = new BaseErrorDialog(mContext);
1522                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1523                    d.setCancelable(false);
1524                    d.setTitle(mContext.getText(R.string.android_system_label));
1525                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1526                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1527                            obtainMessage(DISMISS_DIALOG_MSG, d));
1528                    d.show();
1529                }
1530            } break;
1531            case SHOW_FINGERPRINT_ERROR_MSG: {
1532                if (mShowDialogs) {
1533                    AlertDialog d = new BaseErrorDialog(mContext);
1534                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1535                    d.setCancelable(false);
1536                    d.setTitle(mContext.getText(R.string.android_system_label));
1537                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1538                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1539                            obtainMessage(DISMISS_DIALOG_MSG, d));
1540                    d.show();
1541                }
1542            } break;
1543            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    ActivityRecord ar = (ActivityRecord) msg.obj;
1546                    if (mCompatModeDialog != null) {
1547                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1548                                ar.info.applicationInfo.packageName)) {
1549                            return;
1550                        }
1551                        mCompatModeDialog.dismiss();
1552                        mCompatModeDialog = null;
1553                    }
1554                    if (ar != null && false) {
1555                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1556                                ar.packageName)) {
1557                            int mode = mCompatModePackages.computeCompatModeLocked(
1558                                    ar.info.applicationInfo);
1559                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1560                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1561                                mCompatModeDialog = new CompatModeDialog(
1562                                        ActivityManagerService.this, mContext,
1563                                        ar.info.applicationInfo);
1564                                mCompatModeDialog.show();
1565                            }
1566                        }
1567                    }
1568                }
1569                break;
1570            }
1571            case START_USER_SWITCH_MSG: {
1572                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1573                break;
1574            }
1575            case DISMISS_DIALOG_MSG: {
1576                final Dialog d = (Dialog) msg.obj;
1577                d.dismiss();
1578                break;
1579            }
1580            case DISPATCH_PROCESSES_CHANGED: {
1581                dispatchProcessesChanged();
1582                break;
1583            }
1584            case DISPATCH_PROCESS_DIED: {
1585                final int pid = msg.arg1;
1586                final int uid = msg.arg2;
1587                dispatchProcessDied(pid, uid);
1588                break;
1589            }
1590            case DISPATCH_UIDS_CHANGED_MSG: {
1591                dispatchUidsChanged();
1592            } break;
1593            }
1594        }
1595    }
1596
1597    final class MainHandler extends Handler {
1598        public MainHandler(Looper looper) {
1599            super(looper, null, true);
1600        }
1601
1602        @Override
1603        public void handleMessage(Message msg) {
1604            switch (msg.what) {
1605            case UPDATE_CONFIGURATION_MSG: {
1606                final ContentResolver resolver = mContext.getContentResolver();
1607                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1608            } break;
1609            case GC_BACKGROUND_PROCESSES_MSG: {
1610                synchronized (ActivityManagerService.this) {
1611                    performAppGcsIfAppropriateLocked();
1612                }
1613            } break;
1614            case SERVICE_TIMEOUT_MSG: {
1615                if (mDidDexOpt) {
1616                    mDidDexOpt = false;
1617                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1618                    nmsg.obj = msg.obj;
1619                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1620                    return;
1621                }
1622                mServices.serviceTimeout((ProcessRecord)msg.obj);
1623            } break;
1624            case UPDATE_TIME_ZONE: {
1625                synchronized (ActivityManagerService.this) {
1626                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1627                        ProcessRecord r = mLruProcesses.get(i);
1628                        if (r.thread != null) {
1629                            try {
1630                                r.thread.updateTimeZone();
1631                            } catch (RemoteException ex) {
1632                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1633                            }
1634                        }
1635                    }
1636                }
1637            } break;
1638            case CLEAR_DNS_CACHE_MSG: {
1639                synchronized (ActivityManagerService.this) {
1640                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1641                        ProcessRecord r = mLruProcesses.get(i);
1642                        if (r.thread != null) {
1643                            try {
1644                                r.thread.clearDnsCache();
1645                            } catch (RemoteException ex) {
1646                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1647                            }
1648                        }
1649                    }
1650                }
1651            } break;
1652            case UPDATE_HTTP_PROXY_MSG: {
1653                ProxyInfo proxy = (ProxyInfo)msg.obj;
1654                String host = "";
1655                String port = "";
1656                String exclList = "";
1657                Uri pacFileUrl = Uri.EMPTY;
1658                if (proxy != null) {
1659                    host = proxy.getHost();
1660                    port = Integer.toString(proxy.getPort());
1661                    exclList = proxy.getExclusionListAsString();
1662                    pacFileUrl = proxy.getPacFileUrl();
1663                }
1664                synchronized (ActivityManagerService.this) {
1665                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1666                        ProcessRecord r = mLruProcesses.get(i);
1667                        if (r.thread != null) {
1668                            try {
1669                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1670                            } catch (RemoteException ex) {
1671                                Slog.w(TAG, "Failed to update http proxy for: " +
1672                                        r.info.processName);
1673                            }
1674                        }
1675                    }
1676                }
1677            } break;
1678            case PROC_START_TIMEOUT_MSG: {
1679                if (mDidDexOpt) {
1680                    mDidDexOpt = false;
1681                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1682                    nmsg.obj = msg.obj;
1683                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1684                    return;
1685                }
1686                ProcessRecord app = (ProcessRecord)msg.obj;
1687                synchronized (ActivityManagerService.this) {
1688                    processStartTimedOutLocked(app);
1689                }
1690            } break;
1691            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1692                synchronized (ActivityManagerService.this) {
1693                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1694                }
1695            } break;
1696            case KILL_APPLICATION_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    int appid = msg.arg1;
1699                    boolean restart = (msg.arg2 == 1);
1700                    Bundle bundle = (Bundle)msg.obj;
1701                    String pkg = bundle.getString("pkg");
1702                    String reason = bundle.getString("reason");
1703                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1704                            false, UserHandle.USER_ALL, reason);
1705                }
1706            } break;
1707            case FINALIZE_PENDING_INTENT_MSG: {
1708                ((PendingIntentRecord)msg.obj).completeFinalize();
1709            } break;
1710            case POST_HEAVY_NOTIFICATION_MSG: {
1711                INotificationManager inm = NotificationManager.getService();
1712                if (inm == null) {
1713                    return;
1714                }
1715
1716                ActivityRecord root = (ActivityRecord)msg.obj;
1717                ProcessRecord process = root.app;
1718                if (process == null) {
1719                    return;
1720                }
1721
1722                try {
1723                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1724                    String text = mContext.getString(R.string.heavy_weight_notification,
1725                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1726                    Notification notification = new Notification.Builder(context)
1727                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1728                            .setWhen(0)
1729                            .setOngoing(true)
1730                            .setTicker(text)
1731                            .setColor(mContext.getColor(
1732                                    com.android.internal.R.color.system_notification_accent_color))
1733                            .setContentTitle(text)
1734                            .setContentText(
1735                                    mContext.getText(R.string.heavy_weight_notification_detail))
1736                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1737                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1738                                    new UserHandle(root.userId)))
1739                            .build();
1740                    try {
1741                        int[] outId = new int[1];
1742                        inm.enqueueNotificationWithTag("android", "android", null,
1743                                R.string.heavy_weight_notification,
1744                                notification, outId, root.userId);
1745                    } catch (RuntimeException e) {
1746                        Slog.w(ActivityManagerService.TAG,
1747                                "Error showing notification for heavy-weight app", e);
1748                    } catch (RemoteException e) {
1749                    }
1750                } catch (NameNotFoundException e) {
1751                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1752                }
1753            } break;
1754            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1755                INotificationManager inm = NotificationManager.getService();
1756                if (inm == null) {
1757                    return;
1758                }
1759                try {
1760                    inm.cancelNotificationWithTag("android", null,
1761                            R.string.heavy_weight_notification,  msg.arg1);
1762                } catch (RuntimeException e) {
1763                    Slog.w(ActivityManagerService.TAG,
1764                            "Error canceling notification for service", e);
1765                } catch (RemoteException e) {
1766                }
1767            } break;
1768            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1769                synchronized (ActivityManagerService.this) {
1770                    checkExcessivePowerUsageLocked(true);
1771                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1772                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1773                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1774                }
1775            } break;
1776            case REPORT_MEM_USAGE_MSG: {
1777                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1778                Thread thread = new Thread() {
1779                    @Override public void run() {
1780                        reportMemUsage(memInfos);
1781                    }
1782                };
1783                thread.start();
1784                break;
1785            }
1786            case REPORT_USER_SWITCH_MSG: {
1787                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1788                break;
1789            }
1790            case CONTINUE_USER_SWITCH_MSG: {
1791                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1792                break;
1793            }
1794            case USER_SWITCH_TIMEOUT_MSG: {
1795                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1796                break;
1797            }
1798            case IMMERSIVE_MODE_LOCK_MSG: {
1799                final boolean nextState = (msg.arg1 != 0);
1800                if (mUpdateLock.isHeld() != nextState) {
1801                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1802                            "Applying new update lock state '" + nextState
1803                            + "' for " + (ActivityRecord)msg.obj);
1804                    if (nextState) {
1805                        mUpdateLock.acquire();
1806                    } else {
1807                        mUpdateLock.release();
1808                    }
1809                }
1810                break;
1811            }
1812            case PERSIST_URI_GRANTS_MSG: {
1813                writeGrantedUriPermissions();
1814                break;
1815            }
1816            case REQUEST_ALL_PSS_MSG: {
1817                synchronized (ActivityManagerService.this) {
1818                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1819                }
1820                break;
1821            }
1822            case START_PROFILES_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    startProfilesLocked();
1825                }
1826                break;
1827            }
1828            case UPDATE_TIME: {
1829                synchronized (ActivityManagerService.this) {
1830                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1831                        ProcessRecord r = mLruProcesses.get(i);
1832                        if (r.thread != null) {
1833                            try {
1834                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1835                            } catch (RemoteException ex) {
1836                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1837                            }
1838                        }
1839                    }
1840                }
1841                break;
1842            }
1843            case SYSTEM_USER_START_MSG: {
1844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1845                        Integer.toString(msg.arg1), msg.arg1);
1846                mSystemServiceManager.startUser(msg.arg1);
1847                break;
1848            }
1849            case SYSTEM_USER_CURRENT_MSG: {
1850                mBatteryStatsService.noteEvent(
1851                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1852                        Integer.toString(msg.arg2), msg.arg2);
1853                mBatteryStatsService.noteEvent(
1854                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1855                        Integer.toString(msg.arg1), msg.arg1);
1856                mSystemServiceManager.switchUser(msg.arg1);
1857                break;
1858            }
1859            case ENTER_ANIMATION_COMPLETE_MSG: {
1860                synchronized (ActivityManagerService.this) {
1861                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1862                    if (r != null && r.app != null && r.app.thread != null) {
1863                        try {
1864                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1865                        } catch (RemoteException e) {
1866                        }
1867                    }
1868                }
1869                break;
1870            }
1871            case FINISH_BOOTING_MSG: {
1872                if (msg.arg1 != 0) {
1873                    finishBooting();
1874                }
1875                if (msg.arg2 != 0) {
1876                    enableScreenAfterBoot();
1877                }
1878                break;
1879            }
1880            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1881                try {
1882                    Locale l = (Locale) msg.obj;
1883                    IBinder service = ServiceManager.getService("mount");
1884                    IMountService mountService = IMountService.Stub.asInterface(service);
1885                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1886                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1887                } catch (RemoteException e) {
1888                    Log.e(TAG, "Error storing locale for decryption UI", e);
1889                }
1890                break;
1891            }
1892            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1893                synchronized (ActivityManagerService.this) {
1894                    int i = mTaskStackListeners.beginBroadcast();
1895                    while (i > 0) {
1896                        i--;
1897                        try {
1898                            // Make a one-way callback to the listener
1899                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1900                        } catch (RemoteException e){
1901                            // Handled by the RemoteCallbackList
1902                        }
1903                    }
1904                    mTaskStackListeners.finishBroadcast();
1905                }
1906                break;
1907            }
1908            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1909                final int uid = msg.arg1;
1910                final byte[] firstPacket = (byte[]) msg.obj;
1911
1912                synchronized (mPidsSelfLocked) {
1913                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1914                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1915                        if (p.uid == uid) {
1916                            try {
1917                                p.thread.notifyCleartextNetwork(firstPacket);
1918                            } catch (RemoteException ignored) {
1919                            }
1920                        }
1921                    }
1922                }
1923                break;
1924            }
1925            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1926                final String procName;
1927                final int uid;
1928                final long memLimit;
1929                final String reportPackage;
1930                synchronized (ActivityManagerService.this) {
1931                    procName = mMemWatchDumpProcName;
1932                    uid = mMemWatchDumpUid;
1933                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1934                    if (val == null) {
1935                        val = mMemWatchProcesses.get(procName, 0);
1936                    }
1937                    if (val != null) {
1938                        memLimit = val.first;
1939                        reportPackage = val.second;
1940                    } else {
1941                        memLimit = 0;
1942                        reportPackage = null;
1943                    }
1944                }
1945                if (procName == null) {
1946                    return;
1947                }
1948
1949                if (DEBUG_PSS) Slog.d(TAG_PSS,
1950                        "Showing dump heap notification from " + procName + "/" + uid);
1951
1952                INotificationManager inm = NotificationManager.getService();
1953                if (inm == null) {
1954                    return;
1955                }
1956
1957                String text = mContext.getString(R.string.dump_heap_notification, procName);
1958
1959
1960                Intent deleteIntent = new Intent();
1961                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1962                Intent intent = new Intent();
1963                intent.setClassName("android", DumpHeapActivity.class.getName());
1964                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1965                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1966                if (reportPackage != null) {
1967                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1968                }
1969                int userId = UserHandle.getUserId(uid);
1970                Notification notification = new Notification.Builder(mContext)
1971                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1972                        .setWhen(0)
1973                        .setOngoing(true)
1974                        .setAutoCancel(true)
1975                        .setTicker(text)
1976                        .setColor(mContext.getColor(
1977                                com.android.internal.R.color.system_notification_accent_color))
1978                        .setContentTitle(text)
1979                        .setContentText(
1980                                mContext.getText(R.string.dump_heap_notification_detail))
1981                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1982                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1983                                new UserHandle(userId)))
1984                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1985                                deleteIntent, 0, UserHandle.OWNER))
1986                        .build();
1987
1988                try {
1989                    int[] outId = new int[1];
1990                    inm.enqueueNotificationWithTag("android", "android", null,
1991                            R.string.dump_heap_notification,
1992                            notification, outId, userId);
1993                } catch (RuntimeException e) {
1994                    Slog.w(ActivityManagerService.TAG,
1995                            "Error showing notification for dump heap", e);
1996                } catch (RemoteException e) {
1997                }
1998            } break;
1999            case DELETE_DUMPHEAP_MSG: {
2000                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2001                        DumpHeapActivity.JAVA_URI,
2002                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2003                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2004                        UserHandle.myUserId());
2005                synchronized (ActivityManagerService.this) {
2006                    mMemWatchDumpFile = null;
2007                    mMemWatchDumpProcName = null;
2008                    mMemWatchDumpPid = -1;
2009                    mMemWatchDumpUid = -1;
2010                }
2011            } break;
2012            case FOREGROUND_PROFILE_CHANGED_MSG: {
2013                dispatchForegroundProfileChanged(msg.arg1);
2014            } break;
2015            case REPORT_TIME_TRACKER_MSG: {
2016                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2017                tracker.deliverResult(mContext);
2018            } break;
2019            }
2020        }
2021    };
2022
2023    static final int COLLECT_PSS_BG_MSG = 1;
2024
2025    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2026        @Override
2027        public void handleMessage(Message msg) {
2028            switch (msg.what) {
2029            case COLLECT_PSS_BG_MSG: {
2030                long start = SystemClock.uptimeMillis();
2031                MemInfoReader memInfo = null;
2032                synchronized (ActivityManagerService.this) {
2033                    if (mFullPssPending) {
2034                        mFullPssPending = false;
2035                        memInfo = new MemInfoReader();
2036                    }
2037                }
2038                if (memInfo != null) {
2039                    updateCpuStatsNow();
2040                    long nativeTotalPss = 0;
2041                    synchronized (mProcessCpuTracker) {
2042                        final int N = mProcessCpuTracker.countStats();
2043                        for (int j=0; j<N; j++) {
2044                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2045                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2046                                // This is definitely an application process; skip it.
2047                                continue;
2048                            }
2049                            synchronized (mPidsSelfLocked) {
2050                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2051                                    // This is one of our own processes; skip it.
2052                                    continue;
2053                                }
2054                            }
2055                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2056                        }
2057                    }
2058                    memInfo.readMemInfo();
2059                    synchronized (ActivityManagerService.this) {
2060                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2061                                + (SystemClock.uptimeMillis()-start) + "ms");
2062                        final long cachedKb = memInfo.getCachedSizeKb();
2063                        final long freeKb = memInfo.getFreeSizeKb();
2064                        final long zramKb = memInfo.getZramTotalSizeKb();
2065                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2066                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2067                                kernelKb*1024, nativeTotalPss*1024);
2068                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2069                                nativeTotalPss);
2070                    }
2071                }
2072
2073                int num = 0;
2074                long[] tmp = new long[1];
2075                do {
2076                    ProcessRecord proc;
2077                    int procState;
2078                    int pid;
2079                    long lastPssTime;
2080                    synchronized (ActivityManagerService.this) {
2081                        if (mPendingPssProcesses.size() <= 0) {
2082                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2083                                    "Collected PSS of " + num + " processes in "
2084                                    + (SystemClock.uptimeMillis() - start) + "ms");
2085                            mPendingPssProcesses.clear();
2086                            return;
2087                        }
2088                        proc = mPendingPssProcesses.remove(0);
2089                        procState = proc.pssProcState;
2090                        lastPssTime = proc.lastPssTime;
2091                        if (proc.thread != null && procState == proc.setProcState
2092                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2093                                        < SystemClock.uptimeMillis()) {
2094                            pid = proc.pid;
2095                        } else {
2096                            proc = null;
2097                            pid = 0;
2098                        }
2099                    }
2100                    if (proc != null) {
2101                        long pss = Debug.getPss(pid, tmp, null);
2102                        synchronized (ActivityManagerService.this) {
2103                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2104                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2105                                num++;
2106                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2107                                        SystemClock.uptimeMillis());
2108                            }
2109                        }
2110                    }
2111                } while (true);
2112            }
2113            }
2114        }
2115    };
2116
2117    public void setSystemProcess() {
2118        try {
2119            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2120            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2121            ServiceManager.addService("meminfo", new MemBinder(this));
2122            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2123            ServiceManager.addService("dbinfo", new DbBinder(this));
2124            if (MONITOR_CPU_USAGE) {
2125                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2126            }
2127            ServiceManager.addService("permission", new PermissionController(this));
2128            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2129
2130            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2131                    "android", STOCK_PM_FLAGS);
2132            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2133
2134            synchronized (this) {
2135                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2136                app.persistent = true;
2137                app.pid = MY_PID;
2138                app.maxAdj = ProcessList.SYSTEM_ADJ;
2139                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2140                synchronized (mPidsSelfLocked) {
2141                    mPidsSelfLocked.put(app.pid, app);
2142                }
2143                updateLruProcessLocked(app, false, null);
2144                updateOomAdjLocked();
2145            }
2146        } catch (PackageManager.NameNotFoundException e) {
2147            throw new RuntimeException(
2148                    "Unable to find android system package", e);
2149        }
2150    }
2151
2152    public void setWindowManager(WindowManagerService wm) {
2153        mWindowManager = wm;
2154        mStackSupervisor.setWindowManager(wm);
2155    }
2156
2157    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2158        mUsageStatsService = usageStatsManager;
2159    }
2160
2161    public void startObservingNativeCrashes() {
2162        final NativeCrashListener ncl = new NativeCrashListener(this);
2163        ncl.start();
2164    }
2165
2166    public IAppOpsService getAppOpsService() {
2167        return mAppOpsService;
2168    }
2169
2170    static class MemBinder extends Binder {
2171        ActivityManagerService mActivityManagerService;
2172        MemBinder(ActivityManagerService activityManagerService) {
2173            mActivityManagerService = activityManagerService;
2174        }
2175
2176        @Override
2177        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2178            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2179                    != PackageManager.PERMISSION_GRANTED) {
2180                pw.println("Permission Denial: can't dump meminfo from from pid="
2181                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2182                        + " without permission " + android.Manifest.permission.DUMP);
2183                return;
2184            }
2185
2186            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2187        }
2188    }
2189
2190    static class GraphicsBinder extends Binder {
2191        ActivityManagerService mActivityManagerService;
2192        GraphicsBinder(ActivityManagerService activityManagerService) {
2193            mActivityManagerService = activityManagerService;
2194        }
2195
2196        @Override
2197        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2198            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2199                    != PackageManager.PERMISSION_GRANTED) {
2200                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2201                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2202                        + " without permission " + android.Manifest.permission.DUMP);
2203                return;
2204            }
2205
2206            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2207        }
2208    }
2209
2210    static class DbBinder extends Binder {
2211        ActivityManagerService mActivityManagerService;
2212        DbBinder(ActivityManagerService activityManagerService) {
2213            mActivityManagerService = activityManagerService;
2214        }
2215
2216        @Override
2217        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2218            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2219                    != PackageManager.PERMISSION_GRANTED) {
2220                pw.println("Permission Denial: can't dump dbinfo from from pid="
2221                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2222                        + " without permission " + android.Manifest.permission.DUMP);
2223                return;
2224            }
2225
2226            mActivityManagerService.dumpDbInfo(fd, pw, args);
2227        }
2228    }
2229
2230    static class CpuBinder extends Binder {
2231        ActivityManagerService mActivityManagerService;
2232        CpuBinder(ActivityManagerService activityManagerService) {
2233            mActivityManagerService = activityManagerService;
2234        }
2235
2236        @Override
2237        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2238            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2239                    != PackageManager.PERMISSION_GRANTED) {
2240                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2241                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2242                        + " without permission " + android.Manifest.permission.DUMP);
2243                return;
2244            }
2245
2246            synchronized (mActivityManagerService.mProcessCpuTracker) {
2247                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2248                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2249                        SystemClock.uptimeMillis()));
2250            }
2251        }
2252    }
2253
2254    public static final class Lifecycle extends SystemService {
2255        private final ActivityManagerService mService;
2256
2257        public Lifecycle(Context context) {
2258            super(context);
2259            mService = new ActivityManagerService(context);
2260        }
2261
2262        @Override
2263        public void onStart() {
2264            mService.start();
2265        }
2266
2267        public ActivityManagerService getService() {
2268            return mService;
2269        }
2270    }
2271
2272    // Note: This method is invoked on the main thread but may need to attach various
2273    // handlers to other threads.  So take care to be explicit about the looper.
2274    public ActivityManagerService(Context systemContext) {
2275        mContext = systemContext;
2276        mFactoryTest = FactoryTest.getMode();
2277        mSystemThread = ActivityThread.currentActivityThread();
2278
2279        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2280
2281        mHandlerThread = new ServiceThread(TAG,
2282                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2283        mHandlerThread.start();
2284        mHandler = new MainHandler(mHandlerThread.getLooper());
2285        mUiHandler = new UiHandler();
2286
2287        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2288                "foreground", BROADCAST_FG_TIMEOUT, false);
2289        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2290                "background", BROADCAST_BG_TIMEOUT, true);
2291        mBroadcastQueues[0] = mFgBroadcastQueue;
2292        mBroadcastQueues[1] = mBgBroadcastQueue;
2293
2294        mServices = new ActiveServices(this);
2295        mProviderMap = new ProviderMap(this);
2296
2297        // TODO: Move creation of battery stats service outside of activity manager service.
2298        File dataDir = Environment.getDataDirectory();
2299        File systemDir = new File(dataDir, "system");
2300        systemDir.mkdirs();
2301        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2302        mBatteryStatsService.getActiveStatistics().readLocked();
2303        mBatteryStatsService.scheduleWriteToDisk();
2304        mOnBattery = DEBUG_POWER ? true
2305                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2306        mBatteryStatsService.getActiveStatistics().setCallback(this);
2307
2308        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2309
2310        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2311
2312        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2313
2314        // User 0 is the first and only user that runs at boot.
2315        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2316        mUserLru.add(UserHandle.USER_OWNER);
2317        updateStartedUserArrayLocked();
2318
2319        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2320            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2321
2322        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2323
2324        mConfiguration.setToDefaults();
2325        mConfiguration.setLocale(Locale.getDefault());
2326
2327        mConfigurationSeq = mConfiguration.seq = 1;
2328        mProcessCpuTracker.init();
2329
2330        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2331        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2332        mRecentTasks = new RecentTasks(this);
2333        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2334        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2335
2336        mProcessCpuThread = new Thread("CpuTracker") {
2337            @Override
2338            public void run() {
2339                while (true) {
2340                    try {
2341                        try {
2342                            synchronized(this) {
2343                                final long now = SystemClock.uptimeMillis();
2344                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2345                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2346                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2347                                //        + ", write delay=" + nextWriteDelay);
2348                                if (nextWriteDelay < nextCpuDelay) {
2349                                    nextCpuDelay = nextWriteDelay;
2350                                }
2351                                if (nextCpuDelay > 0) {
2352                                    mProcessCpuMutexFree.set(true);
2353                                    this.wait(nextCpuDelay);
2354                                }
2355                            }
2356                        } catch (InterruptedException e) {
2357                        }
2358                        updateCpuStatsNow();
2359                    } catch (Exception e) {
2360                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2361                    }
2362                }
2363            }
2364        };
2365
2366        Watchdog.getInstance().addMonitor(this);
2367        Watchdog.getInstance().addThread(mHandler);
2368    }
2369
2370    public void setSystemServiceManager(SystemServiceManager mgr) {
2371        mSystemServiceManager = mgr;
2372    }
2373
2374    public void setInstaller(Installer installer) {
2375        mInstaller = installer;
2376    }
2377
2378    private void start() {
2379        Process.removeAllProcessGroups();
2380        mProcessCpuThread.start();
2381
2382        mBatteryStatsService.publish(mContext);
2383        mAppOpsService.publish(mContext);
2384        Slog.d("AppOps", "AppOpsService published");
2385        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2386    }
2387
2388    public void initPowerManagement() {
2389        mStackSupervisor.initPowerManagement();
2390        mBatteryStatsService.initPowerManagement();
2391        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2392        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2393        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2394        mVoiceWakeLock.setReferenceCounted(false);
2395    }
2396
2397    @Override
2398    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2399            throws RemoteException {
2400        if (code == SYSPROPS_TRANSACTION) {
2401            // We need to tell all apps about the system property change.
2402            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2403            synchronized(this) {
2404                final int NP = mProcessNames.getMap().size();
2405                for (int ip=0; ip<NP; ip++) {
2406                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2407                    final int NA = apps.size();
2408                    for (int ia=0; ia<NA; ia++) {
2409                        ProcessRecord app = apps.valueAt(ia);
2410                        if (app.thread != null) {
2411                            procs.add(app.thread.asBinder());
2412                        }
2413                    }
2414                }
2415            }
2416
2417            int N = procs.size();
2418            for (int i=0; i<N; i++) {
2419                Parcel data2 = Parcel.obtain();
2420                try {
2421                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2422                } catch (RemoteException e) {
2423                }
2424                data2.recycle();
2425            }
2426        }
2427        try {
2428            return super.onTransact(code, data, reply, flags);
2429        } catch (RuntimeException e) {
2430            // The activity manager only throws security exceptions, so let's
2431            // log all others.
2432            if (!(e instanceof SecurityException)) {
2433                Slog.wtf(TAG, "Activity Manager Crash", e);
2434            }
2435            throw e;
2436        }
2437    }
2438
2439    void updateCpuStats() {
2440        final long now = SystemClock.uptimeMillis();
2441        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2442            return;
2443        }
2444        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2445            synchronized (mProcessCpuThread) {
2446                mProcessCpuThread.notify();
2447            }
2448        }
2449    }
2450
2451    void updateCpuStatsNow() {
2452        synchronized (mProcessCpuTracker) {
2453            mProcessCpuMutexFree.set(false);
2454            final long now = SystemClock.uptimeMillis();
2455            boolean haveNewCpuStats = false;
2456
2457            if (MONITOR_CPU_USAGE &&
2458                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2459                mLastCpuTime.set(now);
2460                mProcessCpuTracker.update();
2461                if (mProcessCpuTracker.hasGoodLastStats()) {
2462                    haveNewCpuStats = true;
2463                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2464                    //Slog.i(TAG, "Total CPU usage: "
2465                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2466
2467                    // Slog the cpu usage if the property is set.
2468                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2469                        int user = mProcessCpuTracker.getLastUserTime();
2470                        int system = mProcessCpuTracker.getLastSystemTime();
2471                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2472                        int irq = mProcessCpuTracker.getLastIrqTime();
2473                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2474                        int idle = mProcessCpuTracker.getLastIdleTime();
2475
2476                        int total = user + system + iowait + irq + softIrq + idle;
2477                        if (total == 0) total = 1;
2478
2479                        EventLog.writeEvent(EventLogTags.CPU,
2480                                ((user+system+iowait+irq+softIrq) * 100) / total,
2481                                (user * 100) / total,
2482                                (system * 100) / total,
2483                                (iowait * 100) / total,
2484                                (irq * 100) / total,
2485                                (softIrq * 100) / total);
2486                    }
2487                }
2488            }
2489
2490            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2491            synchronized(bstats) {
2492                synchronized(mPidsSelfLocked) {
2493                    if (haveNewCpuStats) {
2494                        if (bstats.startAddingCpuLocked()) {
2495                            int totalUTime = 0;
2496                            int totalSTime = 0;
2497                            final int N = mProcessCpuTracker.countStats();
2498                            for (int i=0; i<N; i++) {
2499                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2500                                if (!st.working) {
2501                                    continue;
2502                                }
2503                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2504                                totalUTime += st.rel_utime;
2505                                totalSTime += st.rel_stime;
2506                                if (pr != null) {
2507                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2508                                    if (ps == null || !ps.isActive()) {
2509                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2510                                                pr.info.uid, pr.processName);
2511                                    }
2512                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2513                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2514                                } else {
2515                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2516                                    if (ps == null || !ps.isActive()) {
2517                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2518                                                bstats.mapUid(st.uid), st.name);
2519                                    }
2520                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2521                                }
2522                            }
2523                            final int userTime = mProcessCpuTracker.getLastUserTime();
2524                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2525                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2526                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2527                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2528                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2529                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2530                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2531                        }
2532                    }
2533                }
2534
2535                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2536                    mLastWriteTime = now;
2537                    mBatteryStatsService.scheduleWriteToDisk();
2538                }
2539            }
2540        }
2541    }
2542
2543    @Override
2544    public void batteryNeedsCpuUpdate() {
2545        updateCpuStatsNow();
2546    }
2547
2548    @Override
2549    public void batteryPowerChanged(boolean onBattery) {
2550        // When plugging in, update the CPU stats first before changing
2551        // the plug state.
2552        updateCpuStatsNow();
2553        synchronized (this) {
2554            synchronized(mPidsSelfLocked) {
2555                mOnBattery = DEBUG_POWER ? true : onBattery;
2556            }
2557        }
2558    }
2559
2560    @Override
2561    public void batterySendBroadcast(Intent intent) {
2562        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2563                AppOpsManager.OP_NONE, null, false, false,
2564                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2565    }
2566
2567    /**
2568     * Initialize the application bind args. These are passed to each
2569     * process when the bindApplication() IPC is sent to the process. They're
2570     * lazily setup to make sure the services are running when they're asked for.
2571     */
2572    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2573        if (mAppBindArgs == null) {
2574            mAppBindArgs = new HashMap<>();
2575
2576            // Isolated processes won't get this optimization, so that we don't
2577            // violate the rules about which services they have access to.
2578            if (!isolated) {
2579                // Setup the application init args
2580                mAppBindArgs.put("package", ServiceManager.getService("package"));
2581                mAppBindArgs.put("window", ServiceManager.getService("window"));
2582                mAppBindArgs.put(Context.ALARM_SERVICE,
2583                        ServiceManager.getService(Context.ALARM_SERVICE));
2584            }
2585        }
2586        return mAppBindArgs;
2587    }
2588
2589    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2590        if (r != null && mFocusedActivity != r) {
2591            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2592            ActivityRecord last = mFocusedActivity;
2593            mFocusedActivity = r;
2594            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2595                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2596                if (mCurAppTimeTracker != r.appTimeTracker) {
2597                    // We are switching app tracking.  Complete the current one.
2598                    if (mCurAppTimeTracker != null) {
2599                        mCurAppTimeTracker.stop();
2600                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2601                                mCurAppTimeTracker).sendToTarget();
2602                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2603                        mCurAppTimeTracker = null;
2604                    }
2605                    if (r.appTimeTracker != null) {
2606                        mCurAppTimeTracker = r.appTimeTracker;
2607                        startTimeTrackingFocusedActivityLocked();
2608                    }
2609                } else {
2610                    startTimeTrackingFocusedActivityLocked();
2611                }
2612            } else {
2613                r.appTimeTracker = null;
2614            }
2615            if (r.task != null && r.task.voiceInteractor != null) {
2616                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2617            } else {
2618                finishRunningVoiceLocked();
2619                if (last != null && last.task.voiceSession != null) {
2620                    // We had been in a voice interaction session, but now focused has
2621                    // move to something different.  Just finish the session, we can't
2622                    // return to it and retain the proper state and synchronization with
2623                    // the voice interaction service.
2624                    finishVoiceTask(last.task.voiceSession);
2625                }
2626            }
2627            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2628                mWindowManager.setFocusedApp(r.appToken, true);
2629            }
2630            applyUpdateLockStateLocked(r);
2631            if (mFocusedActivity.userId != mLastFocusedUserId) {
2632                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2633                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2634                        mFocusedActivity.userId, 0));
2635                mLastFocusedUserId = mFocusedActivity.userId;
2636            }
2637        }
2638        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2639                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2640                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2641    }
2642
2643    final void clearFocusedActivity(ActivityRecord r) {
2644        if (mFocusedActivity == r) {
2645            ActivityStack stack = mStackSupervisor.getFocusedStack();
2646            if (stack != null) {
2647                ActivityRecord top = stack.topActivity();
2648                if (top != null && top.userId != mLastFocusedUserId) {
2649                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2650                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2651                                    top.userId, 0));
2652                    mLastFocusedUserId = top.userId;
2653                }
2654            }
2655            mFocusedActivity = null;
2656            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2657        }
2658    }
2659
2660    @Override
2661    public void setFocusedStack(int stackId) {
2662        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2663        synchronized (ActivityManagerService.this) {
2664            ActivityStack stack = mStackSupervisor.getStack(stackId);
2665            if (stack != null) {
2666                ActivityRecord r = stack.topRunningActivityLocked(null);
2667                if (r != null) {
2668                    setFocusedActivityLocked(r, "setFocusedStack");
2669                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2670                }
2671            }
2672        }
2673    }
2674
2675    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2676    @Override
2677    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2678        synchronized (ActivityManagerService.this) {
2679            if (listener != null) {
2680                mTaskStackListeners.register(listener);
2681            }
2682        }
2683    }
2684
2685    @Override
2686    public void notifyActivityDrawn(IBinder token) {
2687        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2688        synchronized (this) {
2689            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2690            if (r != null) {
2691                r.task.stack.notifyActivityDrawnLocked(r);
2692            }
2693        }
2694    }
2695
2696    final void applyUpdateLockStateLocked(ActivityRecord r) {
2697        // Modifications to the UpdateLock state are done on our handler, outside
2698        // the activity manager's locks.  The new state is determined based on the
2699        // state *now* of the relevant activity record.  The object is passed to
2700        // the handler solely for logging detail, not to be consulted/modified.
2701        final boolean nextState = r != null && r.immersive;
2702        mHandler.sendMessage(
2703                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2704    }
2705
2706    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2707        Message msg = Message.obtain();
2708        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2709        msg.obj = r.task.askedCompatMode ? null : r;
2710        mUiHandler.sendMessage(msg);
2711    }
2712
2713    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2714            String what, Object obj, ProcessRecord srcApp) {
2715        app.lastActivityTime = now;
2716
2717        if (app.activities.size() > 0) {
2718            // Don't want to touch dependent processes that are hosting activities.
2719            return index;
2720        }
2721
2722        int lrui = mLruProcesses.lastIndexOf(app);
2723        if (lrui < 0) {
2724            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2725                    + what + " " + obj + " from " + srcApp);
2726            return index;
2727        }
2728
2729        if (lrui >= index) {
2730            // Don't want to cause this to move dependent processes *back* in the
2731            // list as if they were less frequently used.
2732            return index;
2733        }
2734
2735        if (lrui >= mLruProcessActivityStart) {
2736            // Don't want to touch dependent processes that are hosting activities.
2737            return index;
2738        }
2739
2740        mLruProcesses.remove(lrui);
2741        if (index > 0) {
2742            index--;
2743        }
2744        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2745                + " in LRU list: " + app);
2746        mLruProcesses.add(index, app);
2747        return index;
2748    }
2749
2750    private static void killProcessGroup(int uid, int pid) {
2751        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2752        Process.killProcessGroup(uid, pid);
2753        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2754    }
2755
2756    final void removeLruProcessLocked(ProcessRecord app) {
2757        int lrui = mLruProcesses.lastIndexOf(app);
2758        if (lrui >= 0) {
2759            if (!app.killed) {
2760                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2761                Process.killProcessQuiet(app.pid);
2762                killProcessGroup(app.info.uid, app.pid);
2763            }
2764            if (lrui <= mLruProcessActivityStart) {
2765                mLruProcessActivityStart--;
2766            }
2767            if (lrui <= mLruProcessServiceStart) {
2768                mLruProcessServiceStart--;
2769            }
2770            mLruProcesses.remove(lrui);
2771        }
2772    }
2773
2774    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2775            ProcessRecord client) {
2776        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2777                || app.treatLikeActivity;
2778        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2779        if (!activityChange && hasActivity) {
2780            // The process has activities, so we are only allowing activity-based adjustments
2781            // to move it.  It should be kept in the front of the list with other
2782            // processes that have activities, and we don't want those to change their
2783            // order except due to activity operations.
2784            return;
2785        }
2786
2787        mLruSeq++;
2788        final long now = SystemClock.uptimeMillis();
2789        app.lastActivityTime = now;
2790
2791        // First a quick reject: if the app is already at the position we will
2792        // put it, then there is nothing to do.
2793        if (hasActivity) {
2794            final int N = mLruProcesses.size();
2795            if (N > 0 && mLruProcesses.get(N-1) == app) {
2796                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2797                return;
2798            }
2799        } else {
2800            if (mLruProcessServiceStart > 0
2801                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2802                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2803                return;
2804            }
2805        }
2806
2807        int lrui = mLruProcesses.lastIndexOf(app);
2808
2809        if (app.persistent && lrui >= 0) {
2810            // We don't care about the position of persistent processes, as long as
2811            // they are in the list.
2812            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2813            return;
2814        }
2815
2816        /* In progress: compute new position first, so we can avoid doing work
2817           if the process is not actually going to move.  Not yet working.
2818        int addIndex;
2819        int nextIndex;
2820        boolean inActivity = false, inService = false;
2821        if (hasActivity) {
2822            // Process has activities, put it at the very tipsy-top.
2823            addIndex = mLruProcesses.size();
2824            nextIndex = mLruProcessServiceStart;
2825            inActivity = true;
2826        } else if (hasService) {
2827            // Process has services, put it at the top of the service list.
2828            addIndex = mLruProcessActivityStart;
2829            nextIndex = mLruProcessServiceStart;
2830            inActivity = true;
2831            inService = true;
2832        } else  {
2833            // Process not otherwise of interest, it goes to the top of the non-service area.
2834            addIndex = mLruProcessServiceStart;
2835            if (client != null) {
2836                int clientIndex = mLruProcesses.lastIndexOf(client);
2837                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2838                        + app);
2839                if (clientIndex >= 0 && addIndex > clientIndex) {
2840                    addIndex = clientIndex;
2841                }
2842            }
2843            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2844        }
2845
2846        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2847                + mLruProcessActivityStart + "): " + app);
2848        */
2849
2850        if (lrui >= 0) {
2851            if (lrui < mLruProcessActivityStart) {
2852                mLruProcessActivityStart--;
2853            }
2854            if (lrui < mLruProcessServiceStart) {
2855                mLruProcessServiceStart--;
2856            }
2857            /*
2858            if (addIndex > lrui) {
2859                addIndex--;
2860            }
2861            if (nextIndex > lrui) {
2862                nextIndex--;
2863            }
2864            */
2865            mLruProcesses.remove(lrui);
2866        }
2867
2868        /*
2869        mLruProcesses.add(addIndex, app);
2870        if (inActivity) {
2871            mLruProcessActivityStart++;
2872        }
2873        if (inService) {
2874            mLruProcessActivityStart++;
2875        }
2876        */
2877
2878        int nextIndex;
2879        if (hasActivity) {
2880            final int N = mLruProcesses.size();
2881            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2882                // Process doesn't have activities, but has clients with
2883                // activities...  move it up, but one below the top (the top
2884                // should always have a real activity).
2885                if (DEBUG_LRU) Slog.d(TAG_LRU,
2886                        "Adding to second-top of LRU activity list: " + app);
2887                mLruProcesses.add(N - 1, app);
2888                // To keep it from spamming the LRU list (by making a bunch of clients),
2889                // we will push down any other entries owned by the app.
2890                final int uid = app.info.uid;
2891                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2892                    ProcessRecord subProc = mLruProcesses.get(i);
2893                    if (subProc.info.uid == uid) {
2894                        // We want to push this one down the list.  If the process after
2895                        // it is for the same uid, however, don't do so, because we don't
2896                        // want them internally to be re-ordered.
2897                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2898                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2899                                    "Pushing uid " + uid + " swapping at " + i + ": "
2900                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2901                            ProcessRecord tmp = mLruProcesses.get(i);
2902                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2903                            mLruProcesses.set(i - 1, tmp);
2904                            i--;
2905                        }
2906                    } else {
2907                        // A gap, we can stop here.
2908                        break;
2909                    }
2910                }
2911            } else {
2912                // Process has activities, put it at the very tipsy-top.
2913                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2914                mLruProcesses.add(app);
2915            }
2916            nextIndex = mLruProcessServiceStart;
2917        } else if (hasService) {
2918            // Process has services, put it at the top of the service list.
2919            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2920            mLruProcesses.add(mLruProcessActivityStart, app);
2921            nextIndex = mLruProcessServiceStart;
2922            mLruProcessActivityStart++;
2923        } else  {
2924            // Process not otherwise of interest, it goes to the top of the non-service area.
2925            int index = mLruProcessServiceStart;
2926            if (client != null) {
2927                // If there is a client, don't allow the process to be moved up higher
2928                // in the list than that client.
2929                int clientIndex = mLruProcesses.lastIndexOf(client);
2930                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2931                        + " when updating " + app);
2932                if (clientIndex <= lrui) {
2933                    // Don't allow the client index restriction to push it down farther in the
2934                    // list than it already is.
2935                    clientIndex = lrui;
2936                }
2937                if (clientIndex >= 0 && index > clientIndex) {
2938                    index = clientIndex;
2939                }
2940            }
2941            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2942            mLruProcesses.add(index, app);
2943            nextIndex = index-1;
2944            mLruProcessActivityStart++;
2945            mLruProcessServiceStart++;
2946        }
2947
2948        // If the app is currently using a content provider or service,
2949        // bump those processes as well.
2950        for (int j=app.connections.size()-1; j>=0; j--) {
2951            ConnectionRecord cr = app.connections.valueAt(j);
2952            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2953                    && cr.binding.service.app != null
2954                    && cr.binding.service.app.lruSeq != mLruSeq
2955                    && !cr.binding.service.app.persistent) {
2956                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2957                        "service connection", cr, app);
2958            }
2959        }
2960        for (int j=app.conProviders.size()-1; j>=0; j--) {
2961            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2962            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2963                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2964                        "provider reference", cpr, app);
2965            }
2966        }
2967    }
2968
2969    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2970        if (uid == Process.SYSTEM_UID) {
2971            // The system gets to run in any process.  If there are multiple
2972            // processes with the same uid, just pick the first (this
2973            // should never happen).
2974            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2975            if (procs == null) return null;
2976            final int procCount = procs.size();
2977            for (int i = 0; i < procCount; i++) {
2978                final int procUid = procs.keyAt(i);
2979                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2980                    // Don't use an app process or different user process for system component.
2981                    continue;
2982                }
2983                return procs.valueAt(i);
2984            }
2985        }
2986        ProcessRecord proc = mProcessNames.get(processName, uid);
2987        if (false && proc != null && !keepIfLarge
2988                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2989                && proc.lastCachedPss >= 4000) {
2990            // Turn this condition on to cause killing to happen regularly, for testing.
2991            if (proc.baseProcessTracker != null) {
2992                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2993            }
2994            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2995        } else if (proc != null && !keepIfLarge
2996                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2997                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2998            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2999            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3000                if (proc.baseProcessTracker != null) {
3001                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3002                }
3003                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3004            }
3005        }
3006        return proc;
3007    }
3008
3009    void ensurePackageDexOpt(String packageName) {
3010        IPackageManager pm = AppGlobals.getPackageManager();
3011        try {
3012            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3013                mDidDexOpt = true;
3014            }
3015        } catch (RemoteException e) {
3016        }
3017    }
3018
3019    boolean isNextTransitionForward() {
3020        int transit = mWindowManager.getPendingAppTransition();
3021        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3022                || transit == AppTransition.TRANSIT_TASK_OPEN
3023                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3024    }
3025
3026    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3027            String processName, String abiOverride, int uid, Runnable crashHandler) {
3028        synchronized(this) {
3029            ApplicationInfo info = new ApplicationInfo();
3030            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3031            // For isolated processes, the former contains the parent's uid and the latter the
3032            // actual uid of the isolated process.
3033            // In the special case introduced by this method (which is, starting an isolated
3034            // process directly from the SystemServer without an actual parent app process) the
3035            // closest thing to a parent's uid is SYSTEM_UID.
3036            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3037            // the |isolated| logic in the ProcessRecord constructor.
3038            info.uid = Process.SYSTEM_UID;
3039            info.processName = processName;
3040            info.className = entryPoint;
3041            info.packageName = "android";
3042            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3043                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3044                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3045                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3046                    crashHandler);
3047            return proc != null ? proc.pid : 0;
3048        }
3049    }
3050
3051    final ProcessRecord startProcessLocked(String processName,
3052            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3053            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3054            boolean isolated, boolean keepIfLarge) {
3055        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3056                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3057                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3058                null /* crashHandler */);
3059    }
3060
3061    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3062            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3063            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3064            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3065        long startTime = SystemClock.elapsedRealtime();
3066        ProcessRecord app;
3067        if (!isolated) {
3068            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3069            checkTime(startTime, "startProcess: after getProcessRecord");
3070
3071            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3072                // If we are in the background, then check to see if this process
3073                // is bad.  If so, we will just silently fail.
3074                if (mBadProcesses.get(info.processName, info.uid) != null) {
3075                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3076                            + "/" + info.processName);
3077                    return null;
3078                }
3079            } else {
3080                // When the user is explicitly starting a process, then clear its
3081                // crash count so that we won't make it bad until they see at
3082                // least one crash dialog again, and make the process good again
3083                // if it had been bad.
3084                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3085                        + "/" + info.processName);
3086                mProcessCrashTimes.remove(info.processName, info.uid);
3087                if (mBadProcesses.get(info.processName, info.uid) != null) {
3088                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3089                            UserHandle.getUserId(info.uid), info.uid,
3090                            info.processName);
3091                    mBadProcesses.remove(info.processName, info.uid);
3092                    if (app != null) {
3093                        app.bad = false;
3094                    }
3095                }
3096            }
3097        } else {
3098            // If this is an isolated process, it can't re-use an existing process.
3099            app = null;
3100        }
3101
3102        // We don't have to do anything more if:
3103        // (1) There is an existing application record; and
3104        // (2) The caller doesn't think it is dead, OR there is no thread
3105        //     object attached to it so we know it couldn't have crashed; and
3106        // (3) There is a pid assigned to it, so it is either starting or
3107        //     already running.
3108        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3109                + " app=" + app + " knownToBeDead=" + knownToBeDead
3110                + " thread=" + (app != null ? app.thread : null)
3111                + " pid=" + (app != null ? app.pid : -1));
3112        if (app != null && app.pid > 0) {
3113            if (!knownToBeDead || app.thread == null) {
3114                // We already have the app running, or are waiting for it to
3115                // come up (we have a pid but not yet its thread), so keep it.
3116                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3117                // If this is a new package in the process, add the package to the list
3118                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3119                checkTime(startTime, "startProcess: done, added package to proc");
3120                return app;
3121            }
3122
3123            // An application record is attached to a previous process,
3124            // clean it up now.
3125            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3126            checkTime(startTime, "startProcess: bad proc running, killing");
3127            killProcessGroup(app.info.uid, app.pid);
3128            handleAppDiedLocked(app, true, true);
3129            checkTime(startTime, "startProcess: done killing old proc");
3130        }
3131
3132        String hostingNameStr = hostingName != null
3133                ? hostingName.flattenToShortString() : null;
3134
3135        if (app == null) {
3136            checkTime(startTime, "startProcess: creating new process record");
3137            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3138            if (app == null) {
3139                Slog.w(TAG, "Failed making new process record for "
3140                        + processName + "/" + info.uid + " isolated=" + isolated);
3141                return null;
3142            }
3143            app.crashHandler = crashHandler;
3144            checkTime(startTime, "startProcess: done creating new process record");
3145        } else {
3146            // If this is a new package in the process, add the package to the list
3147            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3148            checkTime(startTime, "startProcess: added package to existing proc");
3149        }
3150
3151        // If the system is not ready yet, then hold off on starting this
3152        // process until it is.
3153        if (!mProcessesReady
3154                && !isAllowedWhileBooting(info)
3155                && !allowWhileBooting) {
3156            if (!mProcessesOnHold.contains(app)) {
3157                mProcessesOnHold.add(app);
3158            }
3159            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3160                    "System not ready, putting on hold: " + app);
3161            checkTime(startTime, "startProcess: returning with proc on hold");
3162            return app;
3163        }
3164
3165        checkTime(startTime, "startProcess: stepping in to startProcess");
3166        startProcessLocked(
3167                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3168        checkTime(startTime, "startProcess: done starting proc!");
3169        return (app.pid != 0) ? app : null;
3170    }
3171
3172    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3173        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3174    }
3175
3176    private final void startProcessLocked(ProcessRecord app,
3177            String hostingType, String hostingNameStr) {
3178        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3179                null /* entryPoint */, null /* entryPointArgs */);
3180    }
3181
3182    private final void startProcessLocked(ProcessRecord app, String hostingType,
3183            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3184        long startTime = SystemClock.elapsedRealtime();
3185        if (app.pid > 0 && app.pid != MY_PID) {
3186            checkTime(startTime, "startProcess: removing from pids map");
3187            synchronized (mPidsSelfLocked) {
3188                mPidsSelfLocked.remove(app.pid);
3189                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3190            }
3191            checkTime(startTime, "startProcess: done removing from pids map");
3192            app.setPid(0);
3193        }
3194
3195        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3196                "startProcessLocked removing on hold: " + app);
3197        mProcessesOnHold.remove(app);
3198
3199        checkTime(startTime, "startProcess: starting to update cpu stats");
3200        updateCpuStats();
3201        checkTime(startTime, "startProcess: done updating cpu stats");
3202
3203        try {
3204            try {
3205                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3206                    // This is caught below as if we had failed to fork zygote
3207                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3208                }
3209            } catch (RemoteException e) {
3210                throw e.rethrowAsRuntimeException();
3211            }
3212
3213            int uid = app.uid;
3214            int[] gids = null;
3215            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3216            if (!app.isolated) {
3217                int[] permGids = null;
3218                try {
3219                    checkTime(startTime, "startProcess: getting gids from package manager");
3220                    final IPackageManager pm = AppGlobals.getPackageManager();
3221                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3222                    mountExternal = pm.getMountExternalMode(uid);
3223                } catch (RemoteException e) {
3224                    throw e.rethrowAsRuntimeException();
3225                }
3226
3227                /*
3228                 * Add shared application and profile GIDs so applications can share some
3229                 * resources like shared libraries and access user-wide resources
3230                 */
3231                if (ArrayUtils.isEmpty(permGids)) {
3232                    gids = new int[2];
3233                } else {
3234                    gids = new int[permGids.length + 2];
3235                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3236                }
3237                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3238                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3239            }
3240            checkTime(startTime, "startProcess: building args");
3241            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3242                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3243                        && mTopComponent != null
3244                        && app.processName.equals(mTopComponent.getPackageName())) {
3245                    uid = 0;
3246                }
3247                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3248                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3249                    uid = 0;
3250                }
3251            }
3252            int debugFlags = 0;
3253            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3254                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3255                // Also turn on CheckJNI for debuggable apps. It's quite
3256                // awkward to turn on otherwise.
3257                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3258            }
3259            // Run the app in safe mode if its manifest requests so or the
3260            // system is booted in safe mode.
3261            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3262                mSafeMode == true) {
3263                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3264            }
3265            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3266                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3267            }
3268            String jitDebugProperty = SystemProperties.get("debug.usejit");
3269            if ("true".equals(jitDebugProperty)) {
3270                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3271            } else if (!"false".equals(jitDebugProperty)) {
3272                // If we didn't force disable by setting false, defer to the dalvik vm options.
3273                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3274                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3275                }
3276            }
3277            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3278            if ("true".equals(genDebugInfoProperty)) {
3279                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3280            }
3281            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3282                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3283            }
3284            if ("1".equals(SystemProperties.get("debug.assert"))) {
3285                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3286            }
3287
3288            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3289            if (requiredAbi == null) {
3290                requiredAbi = Build.SUPPORTED_ABIS[0];
3291            }
3292
3293            String instructionSet = null;
3294            if (app.info.primaryCpuAbi != null) {
3295                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3296            }
3297
3298            app.gids = gids;
3299            app.requiredAbi = requiredAbi;
3300            app.instructionSet = instructionSet;
3301
3302            // Start the process.  It will either succeed and return a result containing
3303            // the PID of the new process, or else throw a RuntimeException.
3304            boolean isActivityProcess = (entryPoint == null);
3305            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3306            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3307                    app.processName);
3308            checkTime(startTime, "startProcess: asking zygote to start proc");
3309            Process.ProcessStartResult startResult = Process.start(entryPoint,
3310                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3311                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3312                    app.info.dataDir, entryPointArgs);
3313            checkTime(startTime, "startProcess: returned from zygote!");
3314            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3315
3316            if (app.isolated) {
3317                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3318            }
3319            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3320            checkTime(startTime, "startProcess: done updating battery stats");
3321
3322            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3323                    UserHandle.getUserId(uid), startResult.pid, uid,
3324                    app.processName, hostingType,
3325                    hostingNameStr != null ? hostingNameStr : "");
3326
3327            if (app.persistent) {
3328                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3329            }
3330
3331            checkTime(startTime, "startProcess: building log message");
3332            StringBuilder buf = mStringBuilder;
3333            buf.setLength(0);
3334            buf.append("Start proc ");
3335            buf.append(startResult.pid);
3336            buf.append(':');
3337            buf.append(app.processName);
3338            buf.append('/');
3339            UserHandle.formatUid(buf, uid);
3340            if (!isActivityProcess) {
3341                buf.append(" [");
3342                buf.append(entryPoint);
3343                buf.append("]");
3344            }
3345            buf.append(" for ");
3346            buf.append(hostingType);
3347            if (hostingNameStr != null) {
3348                buf.append(" ");
3349                buf.append(hostingNameStr);
3350            }
3351            Slog.i(TAG, buf.toString());
3352            app.setPid(startResult.pid);
3353            app.usingWrapper = startResult.usingWrapper;
3354            app.removed = false;
3355            app.killed = false;
3356            app.killedByAm = false;
3357            checkTime(startTime, "startProcess: starting to update pids map");
3358            synchronized (mPidsSelfLocked) {
3359                this.mPidsSelfLocked.put(startResult.pid, app);
3360                if (isActivityProcess) {
3361                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3362                    msg.obj = app;
3363                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3364                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3365                }
3366            }
3367            checkTime(startTime, "startProcess: done updating pids map");
3368        } catch (RuntimeException e) {
3369            // XXX do better error recovery.
3370            app.setPid(0);
3371            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3372            if (app.isolated) {
3373                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3374            }
3375            Slog.e(TAG, "Failure starting process " + app.processName, e);
3376        }
3377    }
3378
3379    void updateUsageStats(ActivityRecord component, boolean resumed) {
3380        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3381                "updateUsageStats: comp=" + component + "res=" + resumed);
3382        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3383        if (resumed) {
3384            if (mUsageStatsService != null) {
3385                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3386                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3387            }
3388            synchronized (stats) {
3389                stats.noteActivityResumedLocked(component.app.uid);
3390            }
3391        } else {
3392            if (mUsageStatsService != null) {
3393                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3394                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3395            }
3396            synchronized (stats) {
3397                stats.noteActivityPausedLocked(component.app.uid);
3398            }
3399        }
3400    }
3401
3402    Intent getHomeIntent() {
3403        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3404        intent.setComponent(mTopComponent);
3405        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3406            intent.addCategory(Intent.CATEGORY_HOME);
3407        }
3408        return intent;
3409    }
3410
3411    boolean startHomeActivityLocked(int userId, String reason) {
3412        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3413                && mTopAction == null) {
3414            // We are running in factory test mode, but unable to find
3415            // the factory test app, so just sit around displaying the
3416            // error message and don't try to start anything.
3417            return false;
3418        }
3419        Intent intent = getHomeIntent();
3420        ActivityInfo aInfo =
3421            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3422        if (aInfo != null) {
3423            intent.setComponent(new ComponentName(
3424                    aInfo.applicationInfo.packageName, aInfo.name));
3425            // Don't do this if the home app is currently being
3426            // instrumented.
3427            aInfo = new ActivityInfo(aInfo);
3428            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3429            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3430                    aInfo.applicationInfo.uid, true);
3431            if (app == null || app.instrumentationClass == null) {
3432                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3433                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3434            }
3435        }
3436
3437        return true;
3438    }
3439
3440    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3441        ActivityInfo ai = null;
3442        ComponentName comp = intent.getComponent();
3443        try {
3444            if (comp != null) {
3445                // Factory test.
3446                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3447            } else {
3448                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3449                        intent,
3450                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3451                        flags, userId);
3452
3453                if (info != null) {
3454                    ai = info.activityInfo;
3455                }
3456            }
3457        } catch (RemoteException e) {
3458            // ignore
3459        }
3460
3461        return ai;
3462    }
3463
3464    /**
3465     * Starts the "new version setup screen" if appropriate.
3466     */
3467    void startSetupActivityLocked() {
3468        // Only do this once per boot.
3469        if (mCheckedForSetup) {
3470            return;
3471        }
3472
3473        // We will show this screen if the current one is a different
3474        // version than the last one shown, and we are not running in
3475        // low-level factory test mode.
3476        final ContentResolver resolver = mContext.getContentResolver();
3477        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3478                Settings.Global.getInt(resolver,
3479                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3480            mCheckedForSetup = true;
3481
3482            // See if we should be showing the platform update setup UI.
3483            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3484            List<ResolveInfo> ris = mContext.getPackageManager()
3485                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3486
3487            // We don't allow third party apps to replace this.
3488            ResolveInfo ri = null;
3489            for (int i=0; ris != null && i<ris.size(); i++) {
3490                if ((ris.get(i).activityInfo.applicationInfo.flags
3491                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3492                    ri = ris.get(i);
3493                    break;
3494                }
3495            }
3496
3497            if (ri != null) {
3498                String vers = ri.activityInfo.metaData != null
3499                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3500                        : null;
3501                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3502                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3503                            Intent.METADATA_SETUP_VERSION);
3504                }
3505                String lastVers = Settings.Secure.getString(
3506                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3507                if (vers != null && !vers.equals(lastVers)) {
3508                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3509                    intent.setComponent(new ComponentName(
3510                            ri.activityInfo.packageName, ri.activityInfo.name));
3511                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3512                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3513                            null);
3514                }
3515            }
3516        }
3517    }
3518
3519    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3520        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3521    }
3522
3523    void enforceNotIsolatedCaller(String caller) {
3524        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3525            throw new SecurityException("Isolated process not allowed to call " + caller);
3526        }
3527    }
3528
3529    void enforceShellRestriction(String restriction, int userHandle) {
3530        if (Binder.getCallingUid() == Process.SHELL_UID) {
3531            if (userHandle < 0
3532                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3533                throw new SecurityException("Shell does not have permission to access user "
3534                        + userHandle);
3535            }
3536        }
3537    }
3538
3539    @Override
3540    public int getFrontActivityScreenCompatMode() {
3541        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3542        synchronized (this) {
3543            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3544        }
3545    }
3546
3547    @Override
3548    public void setFrontActivityScreenCompatMode(int mode) {
3549        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3550                "setFrontActivityScreenCompatMode");
3551        synchronized (this) {
3552            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3553        }
3554    }
3555
3556    @Override
3557    public int getPackageScreenCompatMode(String packageName) {
3558        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3559        synchronized (this) {
3560            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3561        }
3562    }
3563
3564    @Override
3565    public void setPackageScreenCompatMode(String packageName, int mode) {
3566        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3567                "setPackageScreenCompatMode");
3568        synchronized (this) {
3569            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3570        }
3571    }
3572
3573    @Override
3574    public boolean getPackageAskScreenCompat(String packageName) {
3575        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3576        synchronized (this) {
3577            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3578        }
3579    }
3580
3581    @Override
3582    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3583        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3584                "setPackageAskScreenCompat");
3585        synchronized (this) {
3586            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3587        }
3588    }
3589
3590    private boolean hasUsageStatsPermission(String callingPackage) {
3591        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3592                Binder.getCallingUid(), callingPackage);
3593        if (mode == AppOpsManager.MODE_DEFAULT) {
3594            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3595                    == PackageManager.PERMISSION_GRANTED;
3596        }
3597        return mode == AppOpsManager.MODE_ALLOWED;
3598    }
3599
3600    @Override
3601    public int getPackageProcessState(String packageName, String callingPackage) {
3602        if (!hasUsageStatsPermission(callingPackage)) {
3603            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3604                    "getPackageProcessState");
3605        }
3606
3607        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3608        synchronized (this) {
3609            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3610                final ProcessRecord proc = mLruProcesses.get(i);
3611                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3612                        || procState > proc.setProcState) {
3613                    boolean found = false;
3614                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3615                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3616                            procState = proc.setProcState;
3617                            found = true;
3618                        }
3619                    }
3620                    if (proc.pkgDeps != null && !found) {
3621                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3622                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3623                                procState = proc.setProcState;
3624                                break;
3625                            }
3626                        }
3627                    }
3628                }
3629            }
3630        }
3631        return procState;
3632    }
3633
3634    @Override
3635    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3636        synchronized (this) {
3637            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3638            if (app == null) {
3639                return false;
3640            }
3641            if (app.trimMemoryLevel < level && app.thread != null &&
3642                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3643                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3644                try {
3645                    app.thread.scheduleTrimMemory(level);
3646                    app.trimMemoryLevel = level;
3647                    return true;
3648                } catch (RemoteException e) {
3649                    // Fallthrough to failure case.
3650                }
3651            }
3652        }
3653        return false;
3654    }
3655
3656    private void dispatchProcessesChanged() {
3657        int N;
3658        synchronized (this) {
3659            N = mPendingProcessChanges.size();
3660            if (mActiveProcessChanges.length < N) {
3661                mActiveProcessChanges = new ProcessChangeItem[N];
3662            }
3663            mPendingProcessChanges.toArray(mActiveProcessChanges);
3664            mPendingProcessChanges.clear();
3665            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3666                    "*** Delivering " + N + " process changes");
3667        }
3668
3669        int i = mProcessObservers.beginBroadcast();
3670        while (i > 0) {
3671            i--;
3672            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3673            if (observer != null) {
3674                try {
3675                    for (int j=0; j<N; j++) {
3676                        ProcessChangeItem item = mActiveProcessChanges[j];
3677                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3678                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3679                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3680                                    + item.uid + ": " + item.foregroundActivities);
3681                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3682                                    item.foregroundActivities);
3683                        }
3684                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3685                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3686                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3687                                    + ": " + item.processState);
3688                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3689                        }
3690                    }
3691                } catch (RemoteException e) {
3692                }
3693            }
3694        }
3695        mProcessObservers.finishBroadcast();
3696
3697        synchronized (this) {
3698            for (int j=0; j<N; j++) {
3699                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3700            }
3701        }
3702    }
3703
3704    private void dispatchProcessDied(int pid, int uid) {
3705        int i = mProcessObservers.beginBroadcast();
3706        while (i > 0) {
3707            i--;
3708            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3709            if (observer != null) {
3710                try {
3711                    observer.onProcessDied(pid, uid);
3712                } catch (RemoteException e) {
3713                }
3714            }
3715        }
3716        mProcessObservers.finishBroadcast();
3717    }
3718
3719    private void dispatchUidsChanged() {
3720        int N;
3721        synchronized (this) {
3722            N = mPendingUidChanges.size();
3723            if (mActiveUidChanges.length < N) {
3724                mActiveUidChanges = new UidRecord.ChangeItem[N];
3725            }
3726            for (int i=0; i<N; i++) {
3727                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3728                mActiveUidChanges[i] = change;
3729                change.uidRecord.pendingChange = null;
3730                change.uidRecord = null;
3731            }
3732            mPendingUidChanges.clear();
3733            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3734                    "*** Delivering " + N + " uid changes");
3735        }
3736
3737        if (mLocalPowerManager != null) {
3738            for (int j=0; j<N; j++) {
3739                UidRecord.ChangeItem item = mActiveUidChanges[j];
3740                if (item.gone) {
3741                    mLocalPowerManager.uidGone(item.uid);
3742                } else {
3743                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3744                }
3745            }
3746        }
3747
3748        int i = mUidObservers.beginBroadcast();
3749        while (i > 0) {
3750            i--;
3751            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3752            if (observer != null) {
3753                try {
3754                    for (int j=0; j<N; j++) {
3755                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3756                        if (item.gone) {
3757                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3758                                    "UID gone uid=" + item.uid);
3759                            observer.onUidGone(item.uid);
3760                        } else {
3761                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3762                                    "UID CHANGED uid=" + item.uid
3763                                    + ": " + item.processState);
3764                            observer.onUidStateChanged(item.uid, item.processState);
3765                        }
3766                    }
3767                } catch (RemoteException e) {
3768                }
3769            }
3770        }
3771        mUidObservers.finishBroadcast();
3772
3773        synchronized (this) {
3774            for (int j=0; j<N; j++) {
3775                mAvailUidChanges.add(mActiveUidChanges[j]);
3776            }
3777        }
3778    }
3779
3780    @Override
3781    public final int startActivity(IApplicationThread caller, String callingPackage,
3782            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3783            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3784        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3785            resultWho, requestCode, startFlags, profilerInfo, options,
3786            UserHandle.getCallingUserId());
3787    }
3788
3789    @Override
3790    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3791            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3792            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3793        enforceNotIsolatedCaller("startActivity");
3794        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3795                false, ALLOW_FULL_ONLY, "startActivity", null);
3796        // TODO: Switch to user app stacks here.
3797        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3798                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3799                profilerInfo, null, null, options, userId, null, null);
3800    }
3801
3802    @Override
3803    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3804            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3805            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3806
3807        // This is very dangerous -- it allows you to perform a start activity (including
3808        // permission grants) as any app that may launch one of your own activities.  So
3809        // we will only allow this to be done from activities that are part of the core framework,
3810        // and then only when they are running as the system.
3811        final ActivityRecord sourceRecord;
3812        final int targetUid;
3813        final String targetPackage;
3814        synchronized (this) {
3815            if (resultTo == null) {
3816                throw new SecurityException("Must be called from an activity");
3817            }
3818            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3819            if (sourceRecord == null) {
3820                throw new SecurityException("Called with bad activity token: " + resultTo);
3821            }
3822            if (!sourceRecord.info.packageName.equals("android")) {
3823                throw new SecurityException(
3824                        "Must be called from an activity that is declared in the android package");
3825            }
3826            if (sourceRecord.app == null) {
3827                throw new SecurityException("Called without a process attached to activity");
3828            }
3829            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3830                // This is still okay, as long as this activity is running under the
3831                // uid of the original calling activity.
3832                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3833                    throw new SecurityException(
3834                            "Calling activity in uid " + sourceRecord.app.uid
3835                                    + " must be system uid or original calling uid "
3836                                    + sourceRecord.launchedFromUid);
3837                }
3838            }
3839            targetUid = sourceRecord.launchedFromUid;
3840            targetPackage = sourceRecord.launchedFromPackage;
3841        }
3842
3843        if (userId == UserHandle.USER_NULL) {
3844            userId = UserHandle.getUserId(sourceRecord.app.uid);
3845        }
3846
3847        // TODO: Switch to user app stacks here.
3848        try {
3849            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3850                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3851                    null, null, options, userId, null, null);
3852            return ret;
3853        } catch (SecurityException e) {
3854            // XXX need to figure out how to propagate to original app.
3855            // A SecurityException here is generally actually a fault of the original
3856            // calling activity (such as a fairly granting permissions), so propagate it
3857            // back to them.
3858            /*
3859            StringBuilder msg = new StringBuilder();
3860            msg.append("While launching");
3861            msg.append(intent.toString());
3862            msg.append(": ");
3863            msg.append(e.getMessage());
3864            */
3865            throw e;
3866        }
3867    }
3868
3869    @Override
3870    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3871            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3872            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3873        enforceNotIsolatedCaller("startActivityAndWait");
3874        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3875                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3876        WaitResult res = new WaitResult();
3877        // TODO: Switch to user app stacks here.
3878        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3879                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3880                options, userId, null, null);
3881        return res;
3882    }
3883
3884    @Override
3885    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3886            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3887            int startFlags, Configuration config, Bundle options, int userId) {
3888        enforceNotIsolatedCaller("startActivityWithConfig");
3889        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3890                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3891        // TODO: Switch to user app stacks here.
3892        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3893                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3894                null, null, config, options, userId, null, null);
3895        return ret;
3896    }
3897
3898    @Override
3899    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3900            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3901            int requestCode, int flagsMask, int flagsValues, Bundle options)
3902            throws TransactionTooLargeException {
3903        enforceNotIsolatedCaller("startActivityIntentSender");
3904        // Refuse possible leaked file descriptors
3905        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3906            throw new IllegalArgumentException("File descriptors passed in Intent");
3907        }
3908
3909        IIntentSender sender = intent.getTarget();
3910        if (!(sender instanceof PendingIntentRecord)) {
3911            throw new IllegalArgumentException("Bad PendingIntent object");
3912        }
3913
3914        PendingIntentRecord pir = (PendingIntentRecord)sender;
3915
3916        synchronized (this) {
3917            // If this is coming from the currently resumed activity, it is
3918            // effectively saying that app switches are allowed at this point.
3919            final ActivityStack stack = getFocusedStack();
3920            if (stack.mResumedActivity != null &&
3921                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3922                mAppSwitchesAllowedTime = 0;
3923            }
3924        }
3925        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3926                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3927        return ret;
3928    }
3929
3930    @Override
3931    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3932            Intent intent, String resolvedType, IVoiceInteractionSession session,
3933            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3934            Bundle options, int userId) {
3935        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3936                != PackageManager.PERMISSION_GRANTED) {
3937            String msg = "Permission Denial: startVoiceActivity() from pid="
3938                    + Binder.getCallingPid()
3939                    + ", uid=" + Binder.getCallingUid()
3940                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3941            Slog.w(TAG, msg);
3942            throw new SecurityException(msg);
3943        }
3944        if (session == null || interactor == null) {
3945            throw new NullPointerException("null session or interactor");
3946        }
3947        userId = handleIncomingUser(callingPid, callingUid, userId,
3948                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3949        // TODO: Switch to user app stacks here.
3950        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3951                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3952                null, options, userId, null, null);
3953    }
3954
3955    @Override
3956    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3957        synchronized (this) {
3958            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3959                if (keepAwake) {
3960                    mVoiceWakeLock.acquire();
3961                } else {
3962                    mVoiceWakeLock.release();
3963                }
3964            }
3965        }
3966    }
3967
3968    @Override
3969    public boolean startNextMatchingActivity(IBinder callingActivity,
3970            Intent intent, Bundle options) {
3971        // Refuse possible leaked file descriptors
3972        if (intent != null && intent.hasFileDescriptors() == true) {
3973            throw new IllegalArgumentException("File descriptors passed in Intent");
3974        }
3975
3976        synchronized (this) {
3977            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3978            if (r == null) {
3979                ActivityOptions.abort(options);
3980                return false;
3981            }
3982            if (r.app == null || r.app.thread == null) {
3983                // The caller is not running...  d'oh!
3984                ActivityOptions.abort(options);
3985                return false;
3986            }
3987            intent = new Intent(intent);
3988            // The caller is not allowed to change the data.
3989            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3990            // And we are resetting to find the next component...
3991            intent.setComponent(null);
3992
3993            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3994
3995            ActivityInfo aInfo = null;
3996            try {
3997                List<ResolveInfo> resolves =
3998                    AppGlobals.getPackageManager().queryIntentActivities(
3999                            intent, r.resolvedType,
4000                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4001                            UserHandle.getCallingUserId());
4002
4003                // Look for the original activity in the list...
4004                final int N = resolves != null ? resolves.size() : 0;
4005                for (int i=0; i<N; i++) {
4006                    ResolveInfo rInfo = resolves.get(i);
4007                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4008                            && rInfo.activityInfo.name.equals(r.info.name)) {
4009                        // We found the current one...  the next matching is
4010                        // after it.
4011                        i++;
4012                        if (i<N) {
4013                            aInfo = resolves.get(i).activityInfo;
4014                        }
4015                        if (debug) {
4016                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4017                                    + "/" + r.info.name);
4018                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4019                                    + "/" + aInfo.name);
4020                        }
4021                        break;
4022                    }
4023                }
4024            } catch (RemoteException e) {
4025            }
4026
4027            if (aInfo == null) {
4028                // Nobody who is next!
4029                ActivityOptions.abort(options);
4030                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4031                return false;
4032            }
4033
4034            intent.setComponent(new ComponentName(
4035                    aInfo.applicationInfo.packageName, aInfo.name));
4036            intent.setFlags(intent.getFlags()&~(
4037                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4038                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4039                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4040                    Intent.FLAG_ACTIVITY_NEW_TASK));
4041
4042            // Okay now we need to start the new activity, replacing the
4043            // currently running activity.  This is a little tricky because
4044            // we want to start the new one as if the current one is finished,
4045            // but not finish the current one first so that there is no flicker.
4046            // And thus...
4047            final boolean wasFinishing = r.finishing;
4048            r.finishing = true;
4049
4050            // Propagate reply information over to the new activity.
4051            final ActivityRecord resultTo = r.resultTo;
4052            final String resultWho = r.resultWho;
4053            final int requestCode = r.requestCode;
4054            r.resultTo = null;
4055            if (resultTo != null) {
4056                resultTo.removeResultsLocked(r, resultWho, requestCode);
4057            }
4058
4059            final long origId = Binder.clearCallingIdentity();
4060            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4061                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4062                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4063                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4064            Binder.restoreCallingIdentity(origId);
4065
4066            r.finishing = wasFinishing;
4067            if (res != ActivityManager.START_SUCCESS) {
4068                return false;
4069            }
4070            return true;
4071        }
4072    }
4073
4074    @Override
4075    public final int startActivityFromRecents(int taskId, Bundle options) {
4076        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4077            String msg = "Permission Denial: startActivityFromRecents called without " +
4078                    START_TASKS_FROM_RECENTS;
4079            Slog.w(TAG, msg);
4080            throw new SecurityException(msg);
4081        }
4082        return startActivityFromRecentsInner(taskId, options);
4083    }
4084
4085    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4086        final TaskRecord task;
4087        final int callingUid;
4088        final String callingPackage;
4089        final Intent intent;
4090        final int userId;
4091        synchronized (this) {
4092            task = mRecentTasks.taskForIdLocked(taskId);
4093            if (task == null) {
4094                throw new IllegalArgumentException("Task " + taskId + " not found.");
4095            }
4096            if (task.getRootActivity() != null) {
4097                moveTaskToFrontLocked(task.taskId, 0, null);
4098                return ActivityManager.START_TASK_TO_FRONT;
4099            }
4100            callingUid = task.mCallingUid;
4101            callingPackage = task.mCallingPackage;
4102            intent = task.intent;
4103            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4104            userId = task.userId;
4105        }
4106        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4107                options, userId, null, task);
4108    }
4109
4110    final int startActivityInPackage(int uid, String callingPackage,
4111            Intent intent, String resolvedType, IBinder resultTo,
4112            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4113            IActivityContainer container, TaskRecord inTask) {
4114
4115        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4116                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4117
4118        // TODO: Switch to user app stacks here.
4119        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4120                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4121                null, null, null, options, userId, container, inTask);
4122        return ret;
4123    }
4124
4125    @Override
4126    public final int startActivities(IApplicationThread caller, String callingPackage,
4127            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4128            int userId) {
4129        enforceNotIsolatedCaller("startActivities");
4130        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4131                false, ALLOW_FULL_ONLY, "startActivity", null);
4132        // TODO: Switch to user app stacks here.
4133        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4134                resolvedTypes, resultTo, options, userId);
4135        return ret;
4136    }
4137
4138    final int startActivitiesInPackage(int uid, String callingPackage,
4139            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4140            Bundle options, int userId) {
4141
4142        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4143                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4144        // TODO: Switch to user app stacks here.
4145        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4146                resultTo, options, userId);
4147        return ret;
4148    }
4149
4150    @Override
4151    public void reportActivityFullyDrawn(IBinder token) {
4152        synchronized (this) {
4153            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4154            if (r == null) {
4155                return;
4156            }
4157            r.reportFullyDrawnLocked();
4158        }
4159    }
4160
4161    @Override
4162    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4163        synchronized (this) {
4164            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4165            if (r == null) {
4166                return;
4167            }
4168            if (r.task != null && r.task.mResizeable) {
4169                // Fixed screen orientation isn't supported with resizeable activities.
4170                return;
4171            }
4172            final long origId = Binder.clearCallingIdentity();
4173            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4174            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4175                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4176            if (config != null) {
4177                r.frozenBeforeDestroy = true;
4178                if (!updateConfigurationLocked(config, r, false, false)) {
4179                    mStackSupervisor.resumeTopActivitiesLocked();
4180                }
4181            }
4182            Binder.restoreCallingIdentity(origId);
4183        }
4184    }
4185
4186    @Override
4187    public int getRequestedOrientation(IBinder token) {
4188        synchronized (this) {
4189            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4190            if (r == null) {
4191                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4192            }
4193            return mWindowManager.getAppOrientation(r.appToken);
4194        }
4195    }
4196
4197    /**
4198     * This is the internal entry point for handling Activity.finish().
4199     *
4200     * @param token The Binder token referencing the Activity we want to finish.
4201     * @param resultCode Result code, if any, from this Activity.
4202     * @param resultData Result data (Intent), if any, from this Activity.
4203     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4204     *            the root Activity in the task.
4205     *
4206     * @return Returns true if the activity successfully finished, or false if it is still running.
4207     */
4208    @Override
4209    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4210            boolean finishTask) {
4211        // Refuse possible leaked file descriptors
4212        if (resultData != null && resultData.hasFileDescriptors() == true) {
4213            throw new IllegalArgumentException("File descriptors passed in Intent");
4214        }
4215
4216        synchronized(this) {
4217            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218            if (r == null) {
4219                return true;
4220            }
4221            // Keep track of the root activity of the task before we finish it
4222            TaskRecord tr = r.task;
4223            ActivityRecord rootR = tr.getRootActivity();
4224            if (rootR == null) {
4225                Slog.w(TAG, "Finishing task with all activities already finished");
4226            }
4227            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4228            // finish.
4229            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4230                    mStackSupervisor.isLastLockedTask(tr)) {
4231                Slog.i(TAG, "Not finishing task in lock task mode");
4232                mStackSupervisor.showLockTaskToast();
4233                return false;
4234            }
4235            if (mController != null) {
4236                // Find the first activity that is not finishing.
4237                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4238                if (next != null) {
4239                    // ask watcher if this is allowed
4240                    boolean resumeOK = true;
4241                    try {
4242                        resumeOK = mController.activityResuming(next.packageName);
4243                    } catch (RemoteException e) {
4244                        mController = null;
4245                        Watchdog.getInstance().setActivityController(null);
4246                    }
4247
4248                    if (!resumeOK) {
4249                        Slog.i(TAG, "Not finishing activity because controller resumed");
4250                        return false;
4251                    }
4252                }
4253            }
4254            final long origId = Binder.clearCallingIdentity();
4255            try {
4256                boolean res;
4257                if (finishTask && r == rootR) {
4258                    // If requested, remove the task that is associated to this activity only if it
4259                    // was the root activity in the task. The result code and data is ignored
4260                    // because we don't support returning them across task boundaries.
4261                    res = removeTaskByIdLocked(tr.taskId, false);
4262                    if (!res) {
4263                        Slog.i(TAG, "Removing task failed to finish activity");
4264                    }
4265                } else {
4266                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4267                            resultData, "app-request", true);
4268                    if (!res) {
4269                        Slog.i(TAG, "Failed to finish by app-request");
4270                    }
4271                }
4272                return res;
4273            } finally {
4274                Binder.restoreCallingIdentity(origId);
4275            }
4276        }
4277    }
4278
4279    @Override
4280    public final void finishHeavyWeightApp() {
4281        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4282                != PackageManager.PERMISSION_GRANTED) {
4283            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4284                    + Binder.getCallingPid()
4285                    + ", uid=" + Binder.getCallingUid()
4286                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4287            Slog.w(TAG, msg);
4288            throw new SecurityException(msg);
4289        }
4290
4291        synchronized(this) {
4292            if (mHeavyWeightProcess == null) {
4293                return;
4294            }
4295
4296            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4297            for (int i = 0; i < activities.size(); i++) {
4298                ActivityRecord r = activities.get(i);
4299                if (!r.finishing && r.isInStackLocked()) {
4300                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4301                            null, "finish-heavy", true);
4302                }
4303            }
4304
4305            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4306                    mHeavyWeightProcess.userId, 0));
4307            mHeavyWeightProcess = null;
4308        }
4309    }
4310
4311    @Override
4312    public void crashApplication(int uid, int initialPid, String packageName,
4313            String message) {
4314        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4315                != PackageManager.PERMISSION_GRANTED) {
4316            String msg = "Permission Denial: crashApplication() from pid="
4317                    + Binder.getCallingPid()
4318                    + ", uid=" + Binder.getCallingUid()
4319                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4320            Slog.w(TAG, msg);
4321            throw new SecurityException(msg);
4322        }
4323
4324        synchronized(this) {
4325            ProcessRecord proc = null;
4326
4327            // Figure out which process to kill.  We don't trust that initialPid
4328            // still has any relation to current pids, so must scan through the
4329            // list.
4330            synchronized (mPidsSelfLocked) {
4331                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4332                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4333                    if (p.uid != uid) {
4334                        continue;
4335                    }
4336                    if (p.pid == initialPid) {
4337                        proc = p;
4338                        break;
4339                    }
4340                    if (p.pkgList.containsKey(packageName)) {
4341                        proc = p;
4342                    }
4343                }
4344            }
4345
4346            if (proc == null) {
4347                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4348                        + " initialPid=" + initialPid
4349                        + " packageName=" + packageName);
4350                return;
4351            }
4352
4353            if (proc.thread != null) {
4354                if (proc.pid == Process.myPid()) {
4355                    Log.w(TAG, "crashApplication: trying to crash self!");
4356                    return;
4357                }
4358                long ident = Binder.clearCallingIdentity();
4359                try {
4360                    proc.thread.scheduleCrash(message);
4361                } catch (RemoteException e) {
4362                }
4363                Binder.restoreCallingIdentity(ident);
4364            }
4365        }
4366    }
4367
4368    @Override
4369    public final void finishSubActivity(IBinder token, String resultWho,
4370            int requestCode) {
4371        synchronized(this) {
4372            final long origId = Binder.clearCallingIdentity();
4373            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4374            if (r != null) {
4375                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4376            }
4377            Binder.restoreCallingIdentity(origId);
4378        }
4379    }
4380
4381    @Override
4382    public boolean finishActivityAffinity(IBinder token) {
4383        synchronized(this) {
4384            final long origId = Binder.clearCallingIdentity();
4385            try {
4386                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4387                if (r == null) {
4388                    return false;
4389                }
4390
4391                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4392                // can finish.
4393                final TaskRecord task = r.task;
4394                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4395                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4396                    mStackSupervisor.showLockTaskToast();
4397                    return false;
4398                }
4399                return task.stack.finishActivityAffinityLocked(r);
4400            } finally {
4401                Binder.restoreCallingIdentity(origId);
4402            }
4403        }
4404    }
4405
4406    @Override
4407    public void finishVoiceTask(IVoiceInteractionSession session) {
4408        synchronized(this) {
4409            final long origId = Binder.clearCallingIdentity();
4410            try {
4411                mStackSupervisor.finishVoiceTask(session);
4412            } finally {
4413                Binder.restoreCallingIdentity(origId);
4414            }
4415        }
4416
4417    }
4418
4419    @Override
4420    public boolean releaseActivityInstance(IBinder token) {
4421        synchronized(this) {
4422            final long origId = Binder.clearCallingIdentity();
4423            try {
4424                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4425                if (r == null) {
4426                    return false;
4427                }
4428                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public void releaseSomeActivities(IApplicationThread appInt) {
4437        synchronized(this) {
4438            final long origId = Binder.clearCallingIdentity();
4439            try {
4440                ProcessRecord app = getRecordForAppLocked(appInt);
4441                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446    }
4447
4448    @Override
4449    public boolean willActivityBeVisible(IBinder token) {
4450        synchronized(this) {
4451            ActivityStack stack = ActivityRecord.getStackLocked(token);
4452            if (stack != null) {
4453                return stack.willActivityBeVisibleLocked(token);
4454            }
4455            return false;
4456        }
4457    }
4458
4459    @Override
4460    public void overridePendingTransition(IBinder token, String packageName,
4461            int enterAnim, int exitAnim) {
4462        synchronized(this) {
4463            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4464            if (self == null) {
4465                return;
4466            }
4467
4468            final long origId = Binder.clearCallingIdentity();
4469
4470            if (self.state == ActivityState.RESUMED
4471                    || self.state == ActivityState.PAUSING) {
4472                mWindowManager.overridePendingAppTransition(packageName,
4473                        enterAnim, exitAnim, null);
4474            }
4475
4476            Binder.restoreCallingIdentity(origId);
4477        }
4478    }
4479
4480    /**
4481     * Main function for removing an existing process from the activity manager
4482     * as a result of that process going away.  Clears out all connections
4483     * to the process.
4484     */
4485    private final void handleAppDiedLocked(ProcessRecord app,
4486            boolean restarting, boolean allowRestart) {
4487        int pid = app.pid;
4488        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4489        if (!kept && !restarting) {
4490            removeLruProcessLocked(app);
4491            if (pid > 0) {
4492                ProcessList.remove(pid);
4493            }
4494        }
4495
4496        if (mProfileProc == app) {
4497            clearProfilerLocked();
4498        }
4499
4500        // Remove this application's activities from active lists.
4501        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4502
4503        app.activities.clear();
4504
4505        if (app.instrumentationClass != null) {
4506            Slog.w(TAG, "Crash of app " + app.processName
4507                  + " running instrumentation " + app.instrumentationClass);
4508            Bundle info = new Bundle();
4509            info.putString("shortMsg", "Process crashed.");
4510            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4511        }
4512
4513        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4514            // If there was nothing to resume, and we are not already
4515            // restarting this process, but there is a visible activity that
4516            // is hosted by the process...  then make sure all visible
4517            // activities are running, taking care of restarting this
4518            // process.
4519            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4520        }
4521    }
4522
4523    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4524        IBinder threadBinder = thread.asBinder();
4525        // Find the application record.
4526        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4527            ProcessRecord rec = mLruProcesses.get(i);
4528            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4529                return i;
4530            }
4531        }
4532        return -1;
4533    }
4534
4535    final ProcessRecord getRecordForAppLocked(
4536            IApplicationThread thread) {
4537        if (thread == null) {
4538            return null;
4539        }
4540
4541        int appIndex = getLRURecordIndexForAppLocked(thread);
4542        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4543    }
4544
4545    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4546        // If there are no longer any background processes running,
4547        // and the app that died was not running instrumentation,
4548        // then tell everyone we are now low on memory.
4549        boolean haveBg = false;
4550        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4551            ProcessRecord rec = mLruProcesses.get(i);
4552            if (rec.thread != null
4553                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4554                haveBg = true;
4555                break;
4556            }
4557        }
4558
4559        if (!haveBg) {
4560            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4561            if (doReport) {
4562                long now = SystemClock.uptimeMillis();
4563                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4564                    doReport = false;
4565                } else {
4566                    mLastMemUsageReportTime = now;
4567                }
4568            }
4569            final ArrayList<ProcessMemInfo> memInfos
4570                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4571            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4572            long now = SystemClock.uptimeMillis();
4573            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4574                ProcessRecord rec = mLruProcesses.get(i);
4575                if (rec == dyingProc || rec.thread == null) {
4576                    continue;
4577                }
4578                if (doReport) {
4579                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4580                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4581                }
4582                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4583                    // The low memory report is overriding any current
4584                    // state for a GC request.  Make sure to do
4585                    // heavy/important/visible/foreground processes first.
4586                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4587                        rec.lastRequestedGc = 0;
4588                    } else {
4589                        rec.lastRequestedGc = rec.lastLowMemory;
4590                    }
4591                    rec.reportLowMemory = true;
4592                    rec.lastLowMemory = now;
4593                    mProcessesToGc.remove(rec);
4594                    addProcessToGcListLocked(rec);
4595                }
4596            }
4597            if (doReport) {
4598                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4599                mHandler.sendMessage(msg);
4600            }
4601            scheduleAppGcsLocked();
4602        }
4603    }
4604
4605    final void appDiedLocked(ProcessRecord app) {
4606       appDiedLocked(app, app.pid, app.thread, false);
4607    }
4608
4609    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4610            boolean fromBinderDied) {
4611        // First check if this ProcessRecord is actually active for the pid.
4612        synchronized (mPidsSelfLocked) {
4613            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4614            if (curProc != app) {
4615                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4616                return;
4617            }
4618        }
4619
4620        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4621        synchronized (stats) {
4622            stats.noteProcessDiedLocked(app.info.uid, pid);
4623        }
4624
4625        if (!app.killed) {
4626            if (!fromBinderDied) {
4627                Process.killProcessQuiet(pid);
4628            }
4629            killProcessGroup(app.info.uid, pid);
4630            app.killed = true;
4631        }
4632
4633        // Clean up already done if the process has been re-started.
4634        if (app.pid == pid && app.thread != null &&
4635                app.thread.asBinder() == thread.asBinder()) {
4636            boolean doLowMem = app.instrumentationClass == null;
4637            boolean doOomAdj = doLowMem;
4638            if (!app.killedByAm) {
4639                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4640                        + ") has died");
4641                mAllowLowerMemLevel = true;
4642            } else {
4643                // Note that we always want to do oom adj to update our state with the
4644                // new number of procs.
4645                mAllowLowerMemLevel = false;
4646                doLowMem = false;
4647            }
4648            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4649            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4650                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4651            handleAppDiedLocked(app, false, true);
4652
4653            if (doOomAdj) {
4654                updateOomAdjLocked();
4655            }
4656            if (doLowMem) {
4657                doLowMemReportIfNeededLocked(app);
4658            }
4659        } else if (app.pid != pid) {
4660            // A new process has already been started.
4661            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4662                    + ") has died and restarted (pid " + app.pid + ").");
4663            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4664        } else if (DEBUG_PROCESSES) {
4665            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4666                    + thread.asBinder());
4667        }
4668    }
4669
4670    /**
4671     * If a stack trace dump file is configured, dump process stack traces.
4672     * @param clearTraces causes the dump file to be erased prior to the new
4673     *    traces being written, if true; when false, the new traces will be
4674     *    appended to any existing file content.
4675     * @param firstPids of dalvik VM processes to dump stack traces for first
4676     * @param lastPids of dalvik VM processes to dump stack traces for last
4677     * @param nativeProcs optional list of native process names to dump stack crawls
4678     * @return file containing stack traces, or null if no dump file is configured
4679     */
4680    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4681            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4682        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4683        if (tracesPath == null || tracesPath.length() == 0) {
4684            return null;
4685        }
4686
4687        File tracesFile = new File(tracesPath);
4688        try {
4689            File tracesDir = tracesFile.getParentFile();
4690            if (!tracesDir.exists()) {
4691                tracesDir.mkdirs();
4692                if (!SELinux.restorecon(tracesDir)) {
4693                    return null;
4694                }
4695            }
4696            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4697
4698            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4699            tracesFile.createNewFile();
4700            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4701        } catch (IOException e) {
4702            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4703            return null;
4704        }
4705
4706        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4707        return tracesFile;
4708    }
4709
4710    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4711            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4712        // Use a FileObserver to detect when traces finish writing.
4713        // The order of traces is considered important to maintain for legibility.
4714        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4715            @Override
4716            public synchronized void onEvent(int event, String path) { notify(); }
4717        };
4718
4719        try {
4720            observer.startWatching();
4721
4722            // First collect all of the stacks of the most important pids.
4723            if (firstPids != null) {
4724                try {
4725                    int num = firstPids.size();
4726                    for (int i = 0; i < num; i++) {
4727                        synchronized (observer) {
4728                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4729                            observer.wait(200);  // Wait for write-close, give up after 200msec
4730                        }
4731                    }
4732                } catch (InterruptedException e) {
4733                    Slog.wtf(TAG, e);
4734                }
4735            }
4736
4737            // Next collect the stacks of the native pids
4738            if (nativeProcs != null) {
4739                int[] pids = Process.getPidsForCommands(nativeProcs);
4740                if (pids != null) {
4741                    for (int pid : pids) {
4742                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4743                    }
4744                }
4745            }
4746
4747            // Lastly, measure CPU usage.
4748            if (processCpuTracker != null) {
4749                processCpuTracker.init();
4750                System.gc();
4751                processCpuTracker.update();
4752                try {
4753                    synchronized (processCpuTracker) {
4754                        processCpuTracker.wait(500); // measure over 1/2 second.
4755                    }
4756                } catch (InterruptedException e) {
4757                }
4758                processCpuTracker.update();
4759
4760                // We'll take the stack crawls of just the top apps using CPU.
4761                final int N = processCpuTracker.countWorkingStats();
4762                int numProcs = 0;
4763                for (int i=0; i<N && numProcs<5; i++) {
4764                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4765                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4766                        numProcs++;
4767                        try {
4768                            synchronized (observer) {
4769                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4770                                observer.wait(200);  // Wait for write-close, give up after 200msec
4771                            }
4772                        } catch (InterruptedException e) {
4773                            Slog.wtf(TAG, e);
4774                        }
4775
4776                    }
4777                }
4778            }
4779        } finally {
4780            observer.stopWatching();
4781        }
4782    }
4783
4784    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4785        if (true || IS_USER_BUILD) {
4786            return;
4787        }
4788        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4789        if (tracesPath == null || tracesPath.length() == 0) {
4790            return;
4791        }
4792
4793        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4794        StrictMode.allowThreadDiskWrites();
4795        try {
4796            final File tracesFile = new File(tracesPath);
4797            final File tracesDir = tracesFile.getParentFile();
4798            final File tracesTmp = new File(tracesDir, "__tmp__");
4799            try {
4800                if (!tracesDir.exists()) {
4801                    tracesDir.mkdirs();
4802                    if (!SELinux.restorecon(tracesDir.getPath())) {
4803                        return;
4804                    }
4805                }
4806                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4807
4808                if (tracesFile.exists()) {
4809                    tracesTmp.delete();
4810                    tracesFile.renameTo(tracesTmp);
4811                }
4812                StringBuilder sb = new StringBuilder();
4813                Time tobj = new Time();
4814                tobj.set(System.currentTimeMillis());
4815                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4816                sb.append(": ");
4817                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4818                sb.append(" since ");
4819                sb.append(msg);
4820                FileOutputStream fos = new FileOutputStream(tracesFile);
4821                fos.write(sb.toString().getBytes());
4822                if (app == null) {
4823                    fos.write("\n*** No application process!".getBytes());
4824                }
4825                fos.close();
4826                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4827            } catch (IOException e) {
4828                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4829                return;
4830            }
4831
4832            if (app != null) {
4833                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4834                firstPids.add(app.pid);
4835                dumpStackTraces(tracesPath, firstPids, null, null, null);
4836            }
4837
4838            File lastTracesFile = null;
4839            File curTracesFile = null;
4840            for (int i=9; i>=0; i--) {
4841                String name = String.format(Locale.US, "slow%02d.txt", i);
4842                curTracesFile = new File(tracesDir, name);
4843                if (curTracesFile.exists()) {
4844                    if (lastTracesFile != null) {
4845                        curTracesFile.renameTo(lastTracesFile);
4846                    } else {
4847                        curTracesFile.delete();
4848                    }
4849                }
4850                lastTracesFile = curTracesFile;
4851            }
4852            tracesFile.renameTo(curTracesFile);
4853            if (tracesTmp.exists()) {
4854                tracesTmp.renameTo(tracesFile);
4855            }
4856        } finally {
4857            StrictMode.setThreadPolicy(oldPolicy);
4858        }
4859    }
4860
4861    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4862            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4863        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4864        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4865
4866        if (mController != null) {
4867            try {
4868                // 0 == continue, -1 = kill process immediately
4869                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4870                if (res < 0 && app.pid != MY_PID) {
4871                    app.kill("anr", true);
4872                }
4873            } catch (RemoteException e) {
4874                mController = null;
4875                Watchdog.getInstance().setActivityController(null);
4876            }
4877        }
4878
4879        long anrTime = SystemClock.uptimeMillis();
4880        if (MONITOR_CPU_USAGE) {
4881            updateCpuStatsNow();
4882        }
4883
4884        synchronized (this) {
4885            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4886            if (mShuttingDown) {
4887                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4888                return;
4889            } else if (app.notResponding) {
4890                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4891                return;
4892            } else if (app.crashing) {
4893                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4894                return;
4895            }
4896
4897            // In case we come through here for the same app before completing
4898            // this one, mark as anring now so we will bail out.
4899            app.notResponding = true;
4900
4901            // Log the ANR to the event log.
4902            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4903                    app.processName, app.info.flags, annotation);
4904
4905            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4906            firstPids.add(app.pid);
4907
4908            int parentPid = app.pid;
4909            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4910            if (parentPid != app.pid) firstPids.add(parentPid);
4911
4912            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4913
4914            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4915                ProcessRecord r = mLruProcesses.get(i);
4916                if (r != null && r.thread != null) {
4917                    int pid = r.pid;
4918                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4919                        if (r.persistent) {
4920                            firstPids.add(pid);
4921                        } else {
4922                            lastPids.put(pid, Boolean.TRUE);
4923                        }
4924                    }
4925                }
4926            }
4927        }
4928
4929        // Log the ANR to the main log.
4930        StringBuilder info = new StringBuilder();
4931        info.setLength(0);
4932        info.append("ANR in ").append(app.processName);
4933        if (activity != null && activity.shortComponentName != null) {
4934            info.append(" (").append(activity.shortComponentName).append(")");
4935        }
4936        info.append("\n");
4937        info.append("PID: ").append(app.pid).append("\n");
4938        if (annotation != null) {
4939            info.append("Reason: ").append(annotation).append("\n");
4940        }
4941        if (parent != null && parent != activity) {
4942            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4943        }
4944
4945        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4946
4947        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4948                NATIVE_STACKS_OF_INTEREST);
4949
4950        String cpuInfo = null;
4951        if (MONITOR_CPU_USAGE) {
4952            updateCpuStatsNow();
4953            synchronized (mProcessCpuTracker) {
4954                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4955            }
4956            info.append(processCpuTracker.printCurrentLoad());
4957            info.append(cpuInfo);
4958        }
4959
4960        info.append(processCpuTracker.printCurrentState(anrTime));
4961
4962        Slog.e(TAG, info.toString());
4963        if (tracesFile == null) {
4964            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4965            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4966        }
4967
4968        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4969                cpuInfo, tracesFile, null);
4970
4971        if (mController != null) {
4972            try {
4973                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4974                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4975                if (res != 0) {
4976                    if (res < 0 && app.pid != MY_PID) {
4977                        app.kill("anr", true);
4978                    } else {
4979                        synchronized (this) {
4980                            mServices.scheduleServiceTimeoutLocked(app);
4981                        }
4982                    }
4983                    return;
4984                }
4985            } catch (RemoteException e) {
4986                mController = null;
4987                Watchdog.getInstance().setActivityController(null);
4988            }
4989        }
4990
4991        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4992        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4993                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4994
4995        synchronized (this) {
4996            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4997
4998            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4999                app.kill("bg anr", true);
5000                return;
5001            }
5002
5003            // Set the app's notResponding state, and look up the errorReportReceiver
5004            makeAppNotRespondingLocked(app,
5005                    activity != null ? activity.shortComponentName : null,
5006                    annotation != null ? "ANR " + annotation : "ANR",
5007                    info.toString());
5008
5009            // Bring up the infamous App Not Responding dialog
5010            Message msg = Message.obtain();
5011            HashMap<String, Object> map = new HashMap<String, Object>();
5012            msg.what = SHOW_NOT_RESPONDING_MSG;
5013            msg.obj = map;
5014            msg.arg1 = aboveSystem ? 1 : 0;
5015            map.put("app", app);
5016            if (activity != null) {
5017                map.put("activity", activity);
5018            }
5019
5020            mUiHandler.sendMessage(msg);
5021        }
5022    }
5023
5024    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5025        if (!mLaunchWarningShown) {
5026            mLaunchWarningShown = true;
5027            mUiHandler.post(new Runnable() {
5028                @Override
5029                public void run() {
5030                    synchronized (ActivityManagerService.this) {
5031                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5032                        d.show();
5033                        mUiHandler.postDelayed(new Runnable() {
5034                            @Override
5035                            public void run() {
5036                                synchronized (ActivityManagerService.this) {
5037                                    d.dismiss();
5038                                    mLaunchWarningShown = false;
5039                                }
5040                            }
5041                        }, 4000);
5042                    }
5043                }
5044            });
5045        }
5046    }
5047
5048    @Override
5049    public boolean clearApplicationUserData(final String packageName,
5050            final IPackageDataObserver observer, int userId) {
5051        enforceNotIsolatedCaller("clearApplicationUserData");
5052        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5053            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5054        }
5055        int uid = Binder.getCallingUid();
5056        int pid = Binder.getCallingPid();
5057        userId = handleIncomingUser(pid, uid,
5058                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5059        long callingId = Binder.clearCallingIdentity();
5060        try {
5061            IPackageManager pm = AppGlobals.getPackageManager();
5062            int pkgUid = -1;
5063            synchronized(this) {
5064                try {
5065                    pkgUid = pm.getPackageUid(packageName, userId);
5066                } catch (RemoteException e) {
5067                }
5068                if (pkgUid == -1) {
5069                    Slog.w(TAG, "Invalid packageName: " + packageName);
5070                    if (observer != null) {
5071                        try {
5072                            observer.onRemoveCompleted(packageName, false);
5073                        } catch (RemoteException e) {
5074                            Slog.i(TAG, "Observer no longer exists.");
5075                        }
5076                    }
5077                    return false;
5078                }
5079                if (uid == pkgUid || checkComponentPermission(
5080                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5081                        pid, uid, -1, true)
5082                        == PackageManager.PERMISSION_GRANTED) {
5083                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5084                } else {
5085                    throw new SecurityException("PID " + pid + " does not have permission "
5086                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5087                                    + " of package " + packageName);
5088                }
5089
5090                // Remove all tasks match the cleared application package and user
5091                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5092                    final TaskRecord tr = mRecentTasks.get(i);
5093                    final String taskPackageName =
5094                            tr.getBaseIntent().getComponent().getPackageName();
5095                    if (tr.userId != userId) continue;
5096                    if (!taskPackageName.equals(packageName)) continue;
5097                    removeTaskByIdLocked(tr.taskId, false);
5098                }
5099            }
5100
5101            try {
5102                // Clear application user data
5103                pm.clearApplicationUserData(packageName, observer, userId);
5104
5105                synchronized(this) {
5106                    // Remove all permissions granted from/to this package
5107                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5108                }
5109
5110                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5111                        Uri.fromParts("package", packageName, null));
5112                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5113                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5114                        null, null, 0, null, null, null, null, false, false, userId);
5115            } catch (RemoteException e) {
5116            }
5117        } finally {
5118            Binder.restoreCallingIdentity(callingId);
5119        }
5120        return true;
5121    }
5122
5123    @Override
5124    public void killBackgroundProcesses(final String packageName, int userId) {
5125        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5126                != PackageManager.PERMISSION_GRANTED &&
5127                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5128                        != PackageManager.PERMISSION_GRANTED) {
5129            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5130                    + Binder.getCallingPid()
5131                    + ", uid=" + Binder.getCallingUid()
5132                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5133            Slog.w(TAG, msg);
5134            throw new SecurityException(msg);
5135        }
5136
5137        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5138                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5139        long callingId = Binder.clearCallingIdentity();
5140        try {
5141            IPackageManager pm = AppGlobals.getPackageManager();
5142            synchronized(this) {
5143                int appId = -1;
5144                try {
5145                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5146                } catch (RemoteException e) {
5147                }
5148                if (appId == -1) {
5149                    Slog.w(TAG, "Invalid packageName: " + packageName);
5150                    return;
5151                }
5152                killPackageProcessesLocked(packageName, appId, userId,
5153                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5154            }
5155        } finally {
5156            Binder.restoreCallingIdentity(callingId);
5157        }
5158    }
5159
5160    @Override
5161    public void killAllBackgroundProcesses() {
5162        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5163                != PackageManager.PERMISSION_GRANTED) {
5164            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5165                    + Binder.getCallingPid()
5166                    + ", uid=" + Binder.getCallingUid()
5167                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5168            Slog.w(TAG, msg);
5169            throw new SecurityException(msg);
5170        }
5171
5172        long callingId = Binder.clearCallingIdentity();
5173        try {
5174            synchronized(this) {
5175                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5176                final int NP = mProcessNames.getMap().size();
5177                for (int ip=0; ip<NP; ip++) {
5178                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5179                    final int NA = apps.size();
5180                    for (int ia=0; ia<NA; ia++) {
5181                        ProcessRecord app = apps.valueAt(ia);
5182                        if (app.persistent) {
5183                            // we don't kill persistent processes
5184                            continue;
5185                        }
5186                        if (app.removed) {
5187                            procs.add(app);
5188                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5189                            app.removed = true;
5190                            procs.add(app);
5191                        }
5192                    }
5193                }
5194
5195                int N = procs.size();
5196                for (int i=0; i<N; i++) {
5197                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5198                }
5199                mAllowLowerMemLevel = true;
5200                updateOomAdjLocked();
5201                doLowMemReportIfNeededLocked(null);
5202            }
5203        } finally {
5204            Binder.restoreCallingIdentity(callingId);
5205        }
5206    }
5207
5208    @Override
5209    public void forceStopPackage(final String packageName, int userId) {
5210        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5211                != PackageManager.PERMISSION_GRANTED) {
5212            String msg = "Permission Denial: forceStopPackage() from pid="
5213                    + Binder.getCallingPid()
5214                    + ", uid=" + Binder.getCallingUid()
5215                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5216            Slog.w(TAG, msg);
5217            throw new SecurityException(msg);
5218        }
5219        final int callingPid = Binder.getCallingPid();
5220        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5221                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5222        long callingId = Binder.clearCallingIdentity();
5223        try {
5224            IPackageManager pm = AppGlobals.getPackageManager();
5225            synchronized(this) {
5226                int[] users = userId == UserHandle.USER_ALL
5227                        ? getUsersLocked() : new int[] { userId };
5228                for (int user : users) {
5229                    int pkgUid = -1;
5230                    try {
5231                        pkgUid = pm.getPackageUid(packageName, user);
5232                    } catch (RemoteException e) {
5233                    }
5234                    if (pkgUid == -1) {
5235                        Slog.w(TAG, "Invalid packageName: " + packageName);
5236                        continue;
5237                    }
5238                    try {
5239                        pm.setPackageStoppedState(packageName, true, user);
5240                    } catch (RemoteException e) {
5241                    } catch (IllegalArgumentException e) {
5242                        Slog.w(TAG, "Failed trying to unstop package "
5243                                + packageName + ": " + e);
5244                    }
5245                    if (isUserRunningLocked(user, false)) {
5246                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5247                    }
5248                }
5249            }
5250        } finally {
5251            Binder.restoreCallingIdentity(callingId);
5252        }
5253    }
5254
5255    @Override
5256    public void addPackageDependency(String packageName) {
5257        synchronized (this) {
5258            int callingPid = Binder.getCallingPid();
5259            if (callingPid == Process.myPid()) {
5260                //  Yeah, um, no.
5261                return;
5262            }
5263            ProcessRecord proc;
5264            synchronized (mPidsSelfLocked) {
5265                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5266            }
5267            if (proc != null) {
5268                if (proc.pkgDeps == null) {
5269                    proc.pkgDeps = new ArraySet<String>(1);
5270                }
5271                proc.pkgDeps.add(packageName);
5272            }
5273        }
5274    }
5275
5276    /*
5277     * The pkg name and app id have to be specified.
5278     */
5279    @Override
5280    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5281        if (pkg == null) {
5282            return;
5283        }
5284        // Make sure the uid is valid.
5285        if (appid < 0) {
5286            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5287            return;
5288        }
5289        int callerUid = Binder.getCallingUid();
5290        // Only the system server can kill an application
5291        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5292            // Post an aysnc message to kill the application
5293            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5294            msg.arg1 = appid;
5295            msg.arg2 = 0;
5296            Bundle bundle = new Bundle();
5297            bundle.putString("pkg", pkg);
5298            bundle.putString("reason", reason);
5299            msg.obj = bundle;
5300            mHandler.sendMessage(msg);
5301        } else {
5302            throw new SecurityException(callerUid + " cannot kill pkg: " +
5303                    pkg);
5304        }
5305    }
5306
5307    @Override
5308    public void closeSystemDialogs(String reason) {
5309        enforceNotIsolatedCaller("closeSystemDialogs");
5310
5311        final int pid = Binder.getCallingPid();
5312        final int uid = Binder.getCallingUid();
5313        final long origId = Binder.clearCallingIdentity();
5314        try {
5315            synchronized (this) {
5316                // Only allow this from foreground processes, so that background
5317                // applications can't abuse it to prevent system UI from being shown.
5318                if (uid >= Process.FIRST_APPLICATION_UID) {
5319                    ProcessRecord proc;
5320                    synchronized (mPidsSelfLocked) {
5321                        proc = mPidsSelfLocked.get(pid);
5322                    }
5323                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5324                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5325                                + " from background process " + proc);
5326                        return;
5327                    }
5328                }
5329                closeSystemDialogsLocked(reason);
5330            }
5331        } finally {
5332            Binder.restoreCallingIdentity(origId);
5333        }
5334    }
5335
5336    void closeSystemDialogsLocked(String reason) {
5337        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5338        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5339                | Intent.FLAG_RECEIVER_FOREGROUND);
5340        if (reason != null) {
5341            intent.putExtra("reason", reason);
5342        }
5343        mWindowManager.closeSystemDialogs(reason);
5344
5345        mStackSupervisor.closeSystemDialogsLocked();
5346
5347        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5348                AppOpsManager.OP_NONE, null, false, false,
5349                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5350    }
5351
5352    @Override
5353    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5354        enforceNotIsolatedCaller("getProcessMemoryInfo");
5355        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5356        for (int i=pids.length-1; i>=0; i--) {
5357            ProcessRecord proc;
5358            int oomAdj;
5359            synchronized (this) {
5360                synchronized (mPidsSelfLocked) {
5361                    proc = mPidsSelfLocked.get(pids[i]);
5362                    oomAdj = proc != null ? proc.setAdj : 0;
5363                }
5364            }
5365            infos[i] = new Debug.MemoryInfo();
5366            Debug.getMemoryInfo(pids[i], infos[i]);
5367            if (proc != null) {
5368                synchronized (this) {
5369                    if (proc.thread != null && proc.setAdj == oomAdj) {
5370                        // Record this for posterity if the process has been stable.
5371                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5372                                infos[i].getTotalUss(), false, proc.pkgList);
5373                    }
5374                }
5375            }
5376        }
5377        return infos;
5378    }
5379
5380    @Override
5381    public long[] getProcessPss(int[] pids) {
5382        enforceNotIsolatedCaller("getProcessPss");
5383        long[] pss = new long[pids.length];
5384        for (int i=pids.length-1; i>=0; i--) {
5385            ProcessRecord proc;
5386            int oomAdj;
5387            synchronized (this) {
5388                synchronized (mPidsSelfLocked) {
5389                    proc = mPidsSelfLocked.get(pids[i]);
5390                    oomAdj = proc != null ? proc.setAdj : 0;
5391                }
5392            }
5393            long[] tmpUss = new long[1];
5394            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5395            if (proc != null) {
5396                synchronized (this) {
5397                    if (proc.thread != null && proc.setAdj == oomAdj) {
5398                        // Record this for posterity if the process has been stable.
5399                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5400                    }
5401                }
5402            }
5403        }
5404        return pss;
5405    }
5406
5407    @Override
5408    public void killApplicationProcess(String processName, int uid) {
5409        if (processName == null) {
5410            return;
5411        }
5412
5413        int callerUid = Binder.getCallingUid();
5414        // Only the system server can kill an application
5415        if (callerUid == Process.SYSTEM_UID) {
5416            synchronized (this) {
5417                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5418                if (app != null && app.thread != null) {
5419                    try {
5420                        app.thread.scheduleSuicide();
5421                    } catch (RemoteException e) {
5422                        // If the other end already died, then our work here is done.
5423                    }
5424                } else {
5425                    Slog.w(TAG, "Process/uid not found attempting kill of "
5426                            + processName + " / " + uid);
5427                }
5428            }
5429        } else {
5430            throw new SecurityException(callerUid + " cannot kill app process: " +
5431                    processName);
5432        }
5433    }
5434
5435    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5436        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5437                false, true, false, false, UserHandle.getUserId(uid), reason);
5438        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5439                Uri.fromParts("package", packageName, null));
5440        if (!mProcessesReady) {
5441            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5442                    | Intent.FLAG_RECEIVER_FOREGROUND);
5443        }
5444        intent.putExtra(Intent.EXTRA_UID, uid);
5445        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5446        broadcastIntentLocked(null, null, intent,
5447                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5448                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5449    }
5450
5451    private void forceStopUserLocked(int userId, String reason) {
5452        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5453        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5454        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5455                | Intent.FLAG_RECEIVER_FOREGROUND);
5456        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5457        broadcastIntentLocked(null, null, intent,
5458                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5459                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5460    }
5461
5462    private final boolean killPackageProcessesLocked(String packageName, int appId,
5463            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5464            boolean doit, boolean evenPersistent, String reason) {
5465        ArrayList<ProcessRecord> procs = new ArrayList<>();
5466
5467        // Remove all processes this package may have touched: all with the
5468        // same UID (except for the system or root user), and all whose name
5469        // matches the package name.
5470        final int NP = mProcessNames.getMap().size();
5471        for (int ip=0; ip<NP; ip++) {
5472            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5473            final int NA = apps.size();
5474            for (int ia=0; ia<NA; ia++) {
5475                ProcessRecord app = apps.valueAt(ia);
5476                if (app.persistent && !evenPersistent) {
5477                    // we don't kill persistent processes
5478                    continue;
5479                }
5480                if (app.removed) {
5481                    if (doit) {
5482                        procs.add(app);
5483                    }
5484                    continue;
5485                }
5486
5487                // Skip process if it doesn't meet our oom adj requirement.
5488                if (app.setAdj < minOomAdj) {
5489                    continue;
5490                }
5491
5492                // If no package is specified, we call all processes under the
5493                // give user id.
5494                if (packageName == null) {
5495                    if (app.userId != userId) {
5496                        continue;
5497                    }
5498                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5499                        continue;
5500                    }
5501                // Package has been specified, we want to hit all processes
5502                // that match it.  We need to qualify this by the processes
5503                // that are running under the specified app and user ID.
5504                } else {
5505                    final boolean isDep = app.pkgDeps != null
5506                            && app.pkgDeps.contains(packageName);
5507                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5508                        continue;
5509                    }
5510                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5511                        continue;
5512                    }
5513                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5514                        continue;
5515                    }
5516                }
5517
5518                // Process has passed all conditions, kill it!
5519                if (!doit) {
5520                    return true;
5521                }
5522                app.removed = true;
5523                procs.add(app);
5524            }
5525        }
5526
5527        int N = procs.size();
5528        for (int i=0; i<N; i++) {
5529            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5530        }
5531        updateOomAdjLocked();
5532        return N > 0;
5533    }
5534
5535    private void cleanupDisabledPackageComponentsLocked(
5536            String packageName, int userId, String[] changedClasses) {
5537
5538        Set<String> disabledClasses = null;
5539        boolean packageDisabled = false;
5540        IPackageManager pm = AppGlobals.getPackageManager();
5541
5542        if (changedClasses == null) {
5543            // Nothing changed...
5544            return;
5545        }
5546
5547        // Determine enable/disable state of the package and its components.
5548        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5549        for (int i = changedClasses.length - 1; i >= 0; i--) {
5550            final String changedClass = changedClasses[i];
5551
5552            if (changedClass.equals(packageName)) {
5553                try {
5554                    // Entire package setting changed
5555                    enabled = pm.getApplicationEnabledSetting(packageName,
5556                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5557                } catch (Exception e) {
5558                    // No such package/component; probably racing with uninstall.  In any
5559                    // event it means we have nothing further to do here.
5560                    return;
5561                }
5562                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5563                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5564                if (packageDisabled) {
5565                    // Entire package is disabled.
5566                    // No need to continue to check component states.
5567                    disabledClasses = null;
5568                    break;
5569                }
5570            } else {
5571                try {
5572                    enabled = pm.getComponentEnabledSetting(
5573                            new ComponentName(packageName, changedClass),
5574                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5575                } catch (Exception e) {
5576                    // As above, probably racing with uninstall.
5577                    return;
5578                }
5579                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5580                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5581                    if (disabledClasses == null) {
5582                        disabledClasses = new ArraySet<>(changedClasses.length);
5583                    }
5584                    disabledClasses.add(changedClass);
5585                }
5586            }
5587        }
5588
5589        if (!packageDisabled && disabledClasses == null) {
5590            // Nothing to do here...
5591            return;
5592        }
5593
5594        // Clean-up disabled activities.
5595        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5596                packageName, disabledClasses, true, false, userId) && mBooted) {
5597            mStackSupervisor.resumeTopActivitiesLocked();
5598            mStackSupervisor.scheduleIdleLocked();
5599        }
5600
5601        // Clean-up disabled tasks
5602        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5603
5604        // Clean-up disabled services.
5605        mServices.bringDownDisabledPackageServicesLocked(
5606                packageName, disabledClasses, userId, false, true);
5607
5608        // Clean-up disabled providers.
5609        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5610        mProviderMap.collectPackageProvidersLocked(
5611                packageName, disabledClasses, true, false, userId, providers);
5612        for (int i = providers.size() - 1; i >= 0; i--) {
5613            removeDyingProviderLocked(null, providers.get(i), true);
5614        }
5615
5616        // Clean-up disabled broadcast receivers.
5617        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5618            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5619                    packageName, disabledClasses, userId, true);
5620        }
5621
5622    }
5623
5624    private final boolean forceStopPackageLocked(String packageName, int appId,
5625            boolean callerWillRestart, boolean purgeCache, boolean doit,
5626            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5627        int i;
5628
5629        if (userId == UserHandle.USER_ALL && packageName == null) {
5630            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5631        }
5632
5633        if (appId < 0 && packageName != null) {
5634            try {
5635                appId = UserHandle.getAppId(
5636                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5637            } catch (RemoteException e) {
5638            }
5639        }
5640
5641        if (doit) {
5642            if (packageName != null) {
5643                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5644                        + " user=" + userId + ": " + reason);
5645            } else {
5646                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5647            }
5648
5649            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5650            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5651                SparseArray<Long> ba = pmap.valueAt(ip);
5652                for (i = ba.size() - 1; i >= 0; i--) {
5653                    boolean remove = false;
5654                    final int entUid = ba.keyAt(i);
5655                    if (packageName != null) {
5656                        if (userId == UserHandle.USER_ALL) {
5657                            if (UserHandle.getAppId(entUid) == appId) {
5658                                remove = true;
5659                            }
5660                        } else {
5661                            if (entUid == UserHandle.getUid(userId, appId)) {
5662                                remove = true;
5663                            }
5664                        }
5665                    } else if (UserHandle.getUserId(entUid) == userId) {
5666                        remove = true;
5667                    }
5668                    if (remove) {
5669                        ba.removeAt(i);
5670                    }
5671                }
5672                if (ba.size() == 0) {
5673                    pmap.removeAt(ip);
5674                }
5675            }
5676        }
5677
5678        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5679                -100, callerWillRestart, true, doit, evenPersistent,
5680                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5681
5682        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5683                packageName, null, doit, evenPersistent, userId)) {
5684            if (!doit) {
5685                return true;
5686            }
5687            didSomething = true;
5688        }
5689
5690        if (mServices.bringDownDisabledPackageServicesLocked(
5691                packageName, null, userId, evenPersistent, doit)) {
5692            if (!doit) {
5693                return true;
5694            }
5695            didSomething = true;
5696        }
5697
5698        if (packageName == null) {
5699            // Remove all sticky broadcasts from this user.
5700            mStickyBroadcasts.remove(userId);
5701        }
5702
5703        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5704        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5705                userId, providers)) {
5706            if (!doit) {
5707                return true;
5708            }
5709            didSomething = true;
5710        }
5711        for (i = providers.size() - 1; i >= 0; i--) {
5712            removeDyingProviderLocked(null, providers.get(i), true);
5713        }
5714
5715        // Remove transient permissions granted from/to this package/user
5716        removeUriPermissionsForPackageLocked(packageName, userId, false);
5717
5718        if (doit) {
5719            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5720                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5721                        packageName, null, userId, doit);
5722            }
5723        }
5724
5725        if (packageName == null || uninstalling) {
5726            // Remove pending intents.  For now we only do this when force
5727            // stopping users, because we have some problems when doing this
5728            // for packages -- app widgets are not currently cleaned up for
5729            // such packages, so they can be left with bad pending intents.
5730            if (mIntentSenderRecords.size() > 0) {
5731                Iterator<WeakReference<PendingIntentRecord>> it
5732                        = mIntentSenderRecords.values().iterator();
5733                while (it.hasNext()) {
5734                    WeakReference<PendingIntentRecord> wpir = it.next();
5735                    if (wpir == null) {
5736                        it.remove();
5737                        continue;
5738                    }
5739                    PendingIntentRecord pir = wpir.get();
5740                    if (pir == null) {
5741                        it.remove();
5742                        continue;
5743                    }
5744                    if (packageName == null) {
5745                        // Stopping user, remove all objects for the user.
5746                        if (pir.key.userId != userId) {
5747                            // Not the same user, skip it.
5748                            continue;
5749                        }
5750                    } else {
5751                        if (UserHandle.getAppId(pir.uid) != appId) {
5752                            // Different app id, skip it.
5753                            continue;
5754                        }
5755                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5756                            // Different user, skip it.
5757                            continue;
5758                        }
5759                        if (!pir.key.packageName.equals(packageName)) {
5760                            // Different package, skip it.
5761                            continue;
5762                        }
5763                    }
5764                    if (!doit) {
5765                        return true;
5766                    }
5767                    didSomething = true;
5768                    it.remove();
5769                    pir.canceled = true;
5770                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5771                        pir.key.activity.pendingResults.remove(pir.ref);
5772                    }
5773                }
5774            }
5775        }
5776
5777        if (doit) {
5778            if (purgeCache && packageName != null) {
5779                AttributeCache ac = AttributeCache.instance();
5780                if (ac != null) {
5781                    ac.removePackage(packageName);
5782                }
5783            }
5784            if (mBooted) {
5785                mStackSupervisor.resumeTopActivitiesLocked();
5786                mStackSupervisor.scheduleIdleLocked();
5787            }
5788        }
5789
5790        return didSomething;
5791    }
5792
5793    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5794        ProcessRecord old = mProcessNames.remove(name, uid);
5795        if (old != null) {
5796            old.uidRecord.numProcs--;
5797            if (old.uidRecord.numProcs == 0) {
5798                // No more processes using this uid, tell clients it is gone.
5799                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5800                        "No more processes in " + old.uidRecord);
5801                enqueueUidChangeLocked(old.uidRecord, true);
5802                mActiveUids.remove(uid);
5803            }
5804            old.uidRecord = null;
5805        }
5806        mIsolatedProcesses.remove(uid);
5807        return old;
5808    }
5809
5810    private final void addProcessNameLocked(ProcessRecord proc) {
5811        // We shouldn't already have a process under this name, but just in case we
5812        // need to clean up whatever may be there now.
5813        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5814        if (old != null) {
5815            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5816        }
5817        UidRecord uidRec = mActiveUids.get(proc.uid);
5818        if (uidRec == null) {
5819            uidRec = new UidRecord(proc.uid);
5820            // This is the first appearance of the uid, report it now!
5821            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5822                    "Creating new process uid: " + uidRec);
5823            mActiveUids.put(proc.uid, uidRec);
5824            enqueueUidChangeLocked(uidRec, false);
5825        }
5826        proc.uidRecord = uidRec;
5827        uidRec.numProcs++;
5828        mProcessNames.put(proc.processName, proc.uid, proc);
5829        if (proc.isolated) {
5830            mIsolatedProcesses.put(proc.uid, proc);
5831        }
5832    }
5833
5834    private final boolean removeProcessLocked(ProcessRecord app,
5835            boolean callerWillRestart, boolean allowRestart, String reason) {
5836        final String name = app.processName;
5837        final int uid = app.uid;
5838        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5839            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5840
5841        removeProcessNameLocked(name, uid);
5842        if (mHeavyWeightProcess == app) {
5843            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5844                    mHeavyWeightProcess.userId, 0));
5845            mHeavyWeightProcess = null;
5846        }
5847        boolean needRestart = false;
5848        if (app.pid > 0 && app.pid != MY_PID) {
5849            int pid = app.pid;
5850            synchronized (mPidsSelfLocked) {
5851                mPidsSelfLocked.remove(pid);
5852                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5853            }
5854            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5855            if (app.isolated) {
5856                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5857            }
5858            boolean willRestart = false;
5859            if (app.persistent && !app.isolated) {
5860                if (!callerWillRestart) {
5861                    willRestart = true;
5862                } else {
5863                    needRestart = true;
5864                }
5865            }
5866            app.kill(reason, true);
5867            handleAppDiedLocked(app, willRestart, allowRestart);
5868            if (willRestart) {
5869                removeLruProcessLocked(app);
5870                addAppLocked(app.info, false, null /* ABI override */);
5871            }
5872        } else {
5873            mRemovedProcesses.add(app);
5874        }
5875
5876        return needRestart;
5877    }
5878
5879    private final void processStartTimedOutLocked(ProcessRecord app) {
5880        final int pid = app.pid;
5881        boolean gone = false;
5882        synchronized (mPidsSelfLocked) {
5883            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5884            if (knownApp != null && knownApp.thread == null) {
5885                mPidsSelfLocked.remove(pid);
5886                gone = true;
5887            }
5888        }
5889
5890        if (gone) {
5891            Slog.w(TAG, "Process " + app + " failed to attach");
5892            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5893                    pid, app.uid, app.processName);
5894            removeProcessNameLocked(app.processName, app.uid);
5895            if (mHeavyWeightProcess == app) {
5896                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5897                        mHeavyWeightProcess.userId, 0));
5898                mHeavyWeightProcess = null;
5899            }
5900            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5901            if (app.isolated) {
5902                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5903            }
5904            // Take care of any launching providers waiting for this process.
5905            checkAppInLaunchingProvidersLocked(app, true);
5906            // Take care of any services that are waiting for the process.
5907            mServices.processStartTimedOutLocked(app);
5908            app.kill("start timeout", true);
5909            removeLruProcessLocked(app);
5910            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5911                Slog.w(TAG, "Unattached app died before backup, skipping");
5912                try {
5913                    IBackupManager bm = IBackupManager.Stub.asInterface(
5914                            ServiceManager.getService(Context.BACKUP_SERVICE));
5915                    bm.agentDisconnected(app.info.packageName);
5916                } catch (RemoteException e) {
5917                    // Can't happen; the backup manager is local
5918                }
5919            }
5920            if (isPendingBroadcastProcessLocked(pid)) {
5921                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5922                skipPendingBroadcastLocked(pid);
5923            }
5924        } else {
5925            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5926        }
5927    }
5928
5929    private final boolean attachApplicationLocked(IApplicationThread thread,
5930            int pid) {
5931
5932        // Find the application record that is being attached...  either via
5933        // the pid if we are running in multiple processes, or just pull the
5934        // next app record if we are emulating process with anonymous threads.
5935        ProcessRecord app;
5936        if (pid != MY_PID && pid >= 0) {
5937            synchronized (mPidsSelfLocked) {
5938                app = mPidsSelfLocked.get(pid);
5939            }
5940        } else {
5941            app = null;
5942        }
5943
5944        if (app == null) {
5945            Slog.w(TAG, "No pending application record for pid " + pid
5946                    + " (IApplicationThread " + thread + "); dropping process");
5947            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5948            if (pid > 0 && pid != MY_PID) {
5949                Process.killProcessQuiet(pid);
5950                //TODO: killProcessGroup(app.info.uid, pid);
5951            } else {
5952                try {
5953                    thread.scheduleExit();
5954                } catch (Exception e) {
5955                    // Ignore exceptions.
5956                }
5957            }
5958            return false;
5959        }
5960
5961        // If this application record is still attached to a previous
5962        // process, clean it up now.
5963        if (app.thread != null) {
5964            handleAppDiedLocked(app, true, true);
5965        }
5966
5967        // Tell the process all about itself.
5968
5969        if (DEBUG_ALL) Slog.v(
5970                TAG, "Binding process pid " + pid + " to record " + app);
5971
5972        final String processName = app.processName;
5973        try {
5974            AppDeathRecipient adr = new AppDeathRecipient(
5975                    app, pid, thread);
5976            thread.asBinder().linkToDeath(adr, 0);
5977            app.deathRecipient = adr;
5978        } catch (RemoteException e) {
5979            app.resetPackageList(mProcessStats);
5980            startProcessLocked(app, "link fail", processName);
5981            return false;
5982        }
5983
5984        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5985
5986        app.makeActive(thread, mProcessStats);
5987        app.curAdj = app.setAdj = -100;
5988        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5989        app.forcingToForeground = null;
5990        updateProcessForegroundLocked(app, false, false);
5991        app.hasShownUi = false;
5992        app.debugging = false;
5993        app.cached = false;
5994        app.killedByAm = false;
5995
5996        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5997
5998        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5999        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6000
6001        if (!normalMode) {
6002            Slog.i(TAG, "Launching preboot mode app: " + app);
6003        }
6004
6005        if (DEBUG_ALL) Slog.v(
6006            TAG, "New app record " + app
6007            + " thread=" + thread.asBinder() + " pid=" + pid);
6008        try {
6009            int testMode = IApplicationThread.DEBUG_OFF;
6010            if (mDebugApp != null && mDebugApp.equals(processName)) {
6011                testMode = mWaitForDebugger
6012                    ? IApplicationThread.DEBUG_WAIT
6013                    : IApplicationThread.DEBUG_ON;
6014                app.debugging = true;
6015                if (mDebugTransient) {
6016                    mDebugApp = mOrigDebugApp;
6017                    mWaitForDebugger = mOrigWaitForDebugger;
6018                }
6019            }
6020            String profileFile = app.instrumentationProfileFile;
6021            ParcelFileDescriptor profileFd = null;
6022            int samplingInterval = 0;
6023            boolean profileAutoStop = false;
6024            if (mProfileApp != null && mProfileApp.equals(processName)) {
6025                mProfileProc = app;
6026                profileFile = mProfileFile;
6027                profileFd = mProfileFd;
6028                samplingInterval = mSamplingInterval;
6029                profileAutoStop = mAutoStopProfiler;
6030            }
6031            boolean enableOpenGlTrace = false;
6032            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6033                enableOpenGlTrace = true;
6034                mOpenGlTraceApp = null;
6035            }
6036
6037            // If the app is being launched for restore or full backup, set it up specially
6038            boolean isRestrictedBackupMode = false;
6039            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6040                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6041                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6042                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6043            }
6044
6045            ensurePackageDexOpt(app.instrumentationInfo != null
6046                    ? app.instrumentationInfo.packageName
6047                    : app.info.packageName);
6048            if (app.instrumentationClass != null) {
6049                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6050            }
6051            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6052                    + processName + " with config " + mConfiguration);
6053            ApplicationInfo appInfo = app.instrumentationInfo != null
6054                    ? app.instrumentationInfo : app.info;
6055            app.compat = compatibilityInfoForPackageLocked(appInfo);
6056            if (profileFd != null) {
6057                profileFd = profileFd.dup();
6058            }
6059            ProfilerInfo profilerInfo = profileFile == null ? null
6060                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6061            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6062                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6063                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6064                    isRestrictedBackupMode || !normalMode, app.persistent,
6065                    new Configuration(mConfiguration), app.compat,
6066                    getCommonServicesLocked(app.isolated),
6067                    mCoreSettingsObserver.getCoreSettingsLocked());
6068            updateLruProcessLocked(app, false, null);
6069            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6070        } catch (Exception e) {
6071            // todo: Yikes!  What should we do?  For now we will try to
6072            // start another process, but that could easily get us in
6073            // an infinite loop of restarting processes...
6074            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6075
6076            app.resetPackageList(mProcessStats);
6077            app.unlinkDeathRecipient();
6078            startProcessLocked(app, "bind fail", processName);
6079            return false;
6080        }
6081
6082        // Remove this record from the list of starting applications.
6083        mPersistentStartingProcesses.remove(app);
6084        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6085                "Attach application locked removing on hold: " + app);
6086        mProcessesOnHold.remove(app);
6087
6088        boolean badApp = false;
6089        boolean didSomething = false;
6090
6091        // See if the top visible activity is waiting to run in this process...
6092        if (normalMode) {
6093            try {
6094                if (mStackSupervisor.attachApplicationLocked(app)) {
6095                    didSomething = true;
6096                }
6097            } catch (Exception e) {
6098                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6099                badApp = true;
6100            }
6101        }
6102
6103        // Find any services that should be running in this process...
6104        if (!badApp) {
6105            try {
6106                didSomething |= mServices.attachApplicationLocked(app, processName);
6107            } catch (Exception e) {
6108                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6109                badApp = true;
6110            }
6111        }
6112
6113        // Check if a next-broadcast receiver is in this process...
6114        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6115            try {
6116                didSomething |= sendPendingBroadcastsLocked(app);
6117            } catch (Exception e) {
6118                // If the app died trying to launch the receiver we declare it 'bad'
6119                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6120                badApp = true;
6121            }
6122        }
6123
6124        // Check whether the next backup agent is in this process...
6125        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6126            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6127                    "New app is backup target, launching agent for " + app);
6128            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6129            try {
6130                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6131                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6132                        mBackupTarget.backupMode);
6133            } catch (Exception e) {
6134                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6135                badApp = true;
6136            }
6137        }
6138
6139        if (badApp) {
6140            app.kill("error during init", true);
6141            handleAppDiedLocked(app, false, true);
6142            return false;
6143        }
6144
6145        if (!didSomething) {
6146            updateOomAdjLocked();
6147        }
6148
6149        return true;
6150    }
6151
6152    @Override
6153    public final void attachApplication(IApplicationThread thread) {
6154        synchronized (this) {
6155            int callingPid = Binder.getCallingPid();
6156            final long origId = Binder.clearCallingIdentity();
6157            attachApplicationLocked(thread, callingPid);
6158            Binder.restoreCallingIdentity(origId);
6159        }
6160    }
6161
6162    @Override
6163    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6164        final long origId = Binder.clearCallingIdentity();
6165        synchronized (this) {
6166            ActivityStack stack = ActivityRecord.getStackLocked(token);
6167            if (stack != null) {
6168                ActivityRecord r =
6169                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6170                if (stopProfiling) {
6171                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6172                        try {
6173                            mProfileFd.close();
6174                        } catch (IOException e) {
6175                        }
6176                        clearProfilerLocked();
6177                    }
6178                }
6179            }
6180        }
6181        Binder.restoreCallingIdentity(origId);
6182    }
6183
6184    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6185        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6186                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6187    }
6188
6189    void enableScreenAfterBoot() {
6190        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6191                SystemClock.uptimeMillis());
6192        mWindowManager.enableScreenAfterBoot();
6193
6194        synchronized (this) {
6195            updateEventDispatchingLocked();
6196        }
6197    }
6198
6199    @Override
6200    public void showBootMessage(final CharSequence msg, final boolean always) {
6201        if (Binder.getCallingUid() != Process.myUid()) {
6202            // These days only the core system can call this, so apps can't get in
6203            // the way of what we show about running them.
6204        }
6205        mWindowManager.showBootMessage(msg, always);
6206    }
6207
6208    @Override
6209    public void keyguardWaitingForActivityDrawn() {
6210        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6211        final long token = Binder.clearCallingIdentity();
6212        try {
6213            synchronized (this) {
6214                if (DEBUG_LOCKSCREEN) logLockScreen("");
6215                mWindowManager.keyguardWaitingForActivityDrawn();
6216                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6217                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6218                    updateSleepIfNeededLocked();
6219                }
6220            }
6221        } finally {
6222            Binder.restoreCallingIdentity(token);
6223        }
6224    }
6225
6226    @Override
6227    public void keyguardGoingAway(boolean disableWindowAnimations,
6228            boolean keyguardGoingToNotificationShade) {
6229        enforceNotIsolatedCaller("keyguardGoingAway");
6230        final long token = Binder.clearCallingIdentity();
6231        try {
6232            synchronized (this) {
6233                if (DEBUG_LOCKSCREEN) logLockScreen("");
6234                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6235                        keyguardGoingToNotificationShade);
6236                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6237                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6238                    updateSleepIfNeededLocked();
6239                }
6240            }
6241        } finally {
6242            Binder.restoreCallingIdentity(token);
6243        }
6244    }
6245
6246    final void finishBooting() {
6247        synchronized (this) {
6248            if (!mBootAnimationComplete) {
6249                mCallFinishBooting = true;
6250                return;
6251            }
6252            mCallFinishBooting = false;
6253        }
6254
6255        ArraySet<String> completedIsas = new ArraySet<String>();
6256        for (String abi : Build.SUPPORTED_ABIS) {
6257            Process.establishZygoteConnectionForAbi(abi);
6258            final String instructionSet = VMRuntime.getInstructionSet(abi);
6259            if (!completedIsas.contains(instructionSet)) {
6260                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6261                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6262                }
6263                completedIsas.add(instructionSet);
6264            }
6265        }
6266
6267        IntentFilter pkgFilter = new IntentFilter();
6268        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6269        pkgFilter.addDataScheme("package");
6270        mContext.registerReceiver(new BroadcastReceiver() {
6271            @Override
6272            public void onReceive(Context context, Intent intent) {
6273                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6274                if (pkgs != null) {
6275                    for (String pkg : pkgs) {
6276                        synchronized (ActivityManagerService.this) {
6277                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6278                                    0, "query restart")) {
6279                                setResultCode(Activity.RESULT_OK);
6280                                return;
6281                            }
6282                        }
6283                    }
6284                }
6285            }
6286        }, pkgFilter);
6287
6288        IntentFilter dumpheapFilter = new IntentFilter();
6289        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6290        mContext.registerReceiver(new BroadcastReceiver() {
6291            @Override
6292            public void onReceive(Context context, Intent intent) {
6293                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6294                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6295                } else {
6296                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6297                }
6298            }
6299        }, dumpheapFilter);
6300
6301        // Let system services know.
6302        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6303
6304        synchronized (this) {
6305            // Ensure that any processes we had put on hold are now started
6306            // up.
6307            final int NP = mProcessesOnHold.size();
6308            if (NP > 0) {
6309                ArrayList<ProcessRecord> procs =
6310                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6311                for (int ip=0; ip<NP; ip++) {
6312                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6313                            + procs.get(ip));
6314                    startProcessLocked(procs.get(ip), "on-hold", null);
6315                }
6316            }
6317
6318            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6319                // Start looking for apps that are abusing wake locks.
6320                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6321                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6322                // Tell anyone interested that we are done booting!
6323                SystemProperties.set("sys.boot_completed", "1");
6324
6325                // And trigger dev.bootcomplete if we are not showing encryption progress
6326                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6327                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6328                    SystemProperties.set("dev.bootcomplete", "1");
6329                }
6330                for (int i=0; i<mStartedUsers.size(); i++) {
6331                    UserState uss = mStartedUsers.valueAt(i);
6332                    if (uss.mState == UserState.STATE_BOOTING) {
6333                        uss.mState = UserState.STATE_RUNNING;
6334                        final int userId = mStartedUsers.keyAt(i);
6335                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6336                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6337                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6338                        broadcastIntentLocked(null, null, intent, null,
6339                                new IIntentReceiver.Stub() {
6340                                    @Override
6341                                    public void performReceive(Intent intent, int resultCode,
6342                                            String data, Bundle extras, boolean ordered,
6343                                            boolean sticky, int sendingUser) {
6344                                        synchronized (ActivityManagerService.this) {
6345                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6346                                                    true, false);
6347                                        }
6348                                    }
6349                                },
6350                                0, null, null,
6351                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6352                                AppOpsManager.OP_NONE, null, true, false,
6353                                MY_PID, Process.SYSTEM_UID, userId);
6354                    }
6355                }
6356                scheduleStartProfilesLocked();
6357            }
6358        }
6359    }
6360
6361    @Override
6362    public void bootAnimationComplete() {
6363        final boolean callFinishBooting;
6364        synchronized (this) {
6365            callFinishBooting = mCallFinishBooting;
6366            mBootAnimationComplete = true;
6367        }
6368        if (callFinishBooting) {
6369            finishBooting();
6370        }
6371    }
6372
6373    final void ensureBootCompleted() {
6374        boolean booting;
6375        boolean enableScreen;
6376        synchronized (this) {
6377            booting = mBooting;
6378            mBooting = false;
6379            enableScreen = !mBooted;
6380            mBooted = true;
6381        }
6382
6383        if (booting) {
6384            finishBooting();
6385        }
6386
6387        if (enableScreen) {
6388            enableScreenAfterBoot();
6389        }
6390    }
6391
6392    @Override
6393    public final void activityResumed(IBinder token) {
6394        final long origId = Binder.clearCallingIdentity();
6395        synchronized(this) {
6396            ActivityStack stack = ActivityRecord.getStackLocked(token);
6397            if (stack != null) {
6398                ActivityRecord.activityResumedLocked(token);
6399            }
6400        }
6401        Binder.restoreCallingIdentity(origId);
6402    }
6403
6404    @Override
6405    public final void activityPaused(IBinder token) {
6406        final long origId = Binder.clearCallingIdentity();
6407        synchronized(this) {
6408            ActivityStack stack = ActivityRecord.getStackLocked(token);
6409            if (stack != null) {
6410                stack.activityPausedLocked(token, false);
6411            }
6412        }
6413        Binder.restoreCallingIdentity(origId);
6414    }
6415
6416    @Override
6417    public final void activityStopped(IBinder token, Bundle icicle,
6418            PersistableBundle persistentState, CharSequence description) {
6419        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6420
6421        // Refuse possible leaked file descriptors
6422        if (icicle != null && icicle.hasFileDescriptors()) {
6423            throw new IllegalArgumentException("File descriptors passed in Bundle");
6424        }
6425
6426        final long origId = Binder.clearCallingIdentity();
6427
6428        synchronized (this) {
6429            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6430            if (r != null) {
6431                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6432            }
6433        }
6434
6435        trimApplications();
6436
6437        Binder.restoreCallingIdentity(origId);
6438    }
6439
6440    @Override
6441    public final void activityDestroyed(IBinder token) {
6442        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6443        synchronized (this) {
6444            ActivityStack stack = ActivityRecord.getStackLocked(token);
6445            if (stack != null) {
6446                stack.activityDestroyedLocked(token, "activityDestroyed");
6447            }
6448        }
6449    }
6450
6451    @Override
6452    public final void backgroundResourcesReleased(IBinder token) {
6453        final long origId = Binder.clearCallingIdentity();
6454        try {
6455            synchronized (this) {
6456                ActivityStack stack = ActivityRecord.getStackLocked(token);
6457                if (stack != null) {
6458                    stack.backgroundResourcesReleased();
6459                }
6460            }
6461        } finally {
6462            Binder.restoreCallingIdentity(origId);
6463        }
6464    }
6465
6466    @Override
6467    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6468        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6469    }
6470
6471    @Override
6472    public final void notifyEnterAnimationComplete(IBinder token) {
6473        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6474    }
6475
6476    @Override
6477    public String getCallingPackage(IBinder token) {
6478        synchronized (this) {
6479            ActivityRecord r = getCallingRecordLocked(token);
6480            return r != null ? r.info.packageName : null;
6481        }
6482    }
6483
6484    @Override
6485    public ComponentName getCallingActivity(IBinder token) {
6486        synchronized (this) {
6487            ActivityRecord r = getCallingRecordLocked(token);
6488            return r != null ? r.intent.getComponent() : null;
6489        }
6490    }
6491
6492    private ActivityRecord getCallingRecordLocked(IBinder token) {
6493        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6494        if (r == null) {
6495            return null;
6496        }
6497        return r.resultTo;
6498    }
6499
6500    @Override
6501    public ComponentName getActivityClassForToken(IBinder token) {
6502        synchronized(this) {
6503            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6504            if (r == null) {
6505                return null;
6506            }
6507            return r.intent.getComponent();
6508        }
6509    }
6510
6511    @Override
6512    public String getPackageForToken(IBinder token) {
6513        synchronized(this) {
6514            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6515            if (r == null) {
6516                return null;
6517            }
6518            return r.packageName;
6519        }
6520    }
6521
6522    @Override
6523    public IIntentSender getIntentSender(int type,
6524            String packageName, IBinder token, String resultWho,
6525            int requestCode, Intent[] intents, String[] resolvedTypes,
6526            int flags, Bundle options, int userId) {
6527        enforceNotIsolatedCaller("getIntentSender");
6528        // Refuse possible leaked file descriptors
6529        if (intents != null) {
6530            if (intents.length < 1) {
6531                throw new IllegalArgumentException("Intents array length must be >= 1");
6532            }
6533            for (int i=0; i<intents.length; i++) {
6534                Intent intent = intents[i];
6535                if (intent != null) {
6536                    if (intent.hasFileDescriptors()) {
6537                        throw new IllegalArgumentException("File descriptors passed in Intent");
6538                    }
6539                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6540                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6541                        throw new IllegalArgumentException(
6542                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6543                    }
6544                    intents[i] = new Intent(intent);
6545                }
6546            }
6547            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6548                throw new IllegalArgumentException(
6549                        "Intent array length does not match resolvedTypes length");
6550            }
6551        }
6552        if (options != null) {
6553            if (options.hasFileDescriptors()) {
6554                throw new IllegalArgumentException("File descriptors passed in options");
6555            }
6556        }
6557
6558        synchronized(this) {
6559            int callingUid = Binder.getCallingUid();
6560            int origUserId = userId;
6561            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6562                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6563                    ALLOW_NON_FULL, "getIntentSender", null);
6564            if (origUserId == UserHandle.USER_CURRENT) {
6565                // We don't want to evaluate this until the pending intent is
6566                // actually executed.  However, we do want to always do the
6567                // security checking for it above.
6568                userId = UserHandle.USER_CURRENT;
6569            }
6570            try {
6571                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6572                    int uid = AppGlobals.getPackageManager()
6573                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6574                    if (!UserHandle.isSameApp(callingUid, uid)) {
6575                        String msg = "Permission Denial: getIntentSender() from pid="
6576                            + Binder.getCallingPid()
6577                            + ", uid=" + Binder.getCallingUid()
6578                            + ", (need uid=" + uid + ")"
6579                            + " is not allowed to send as package " + packageName;
6580                        Slog.w(TAG, msg);
6581                        throw new SecurityException(msg);
6582                    }
6583                }
6584
6585                return getIntentSenderLocked(type, packageName, callingUid, userId,
6586                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6587
6588            } catch (RemoteException e) {
6589                throw new SecurityException(e);
6590            }
6591        }
6592    }
6593
6594    IIntentSender getIntentSenderLocked(int type, String packageName,
6595            int callingUid, int userId, IBinder token, String resultWho,
6596            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6597            Bundle options) {
6598        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6599        ActivityRecord activity = null;
6600        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6601            activity = ActivityRecord.isInStackLocked(token);
6602            if (activity == null) {
6603                return null;
6604            }
6605            if (activity.finishing) {
6606                return null;
6607            }
6608        }
6609
6610        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6611        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6612        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6613        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6614                |PendingIntent.FLAG_UPDATE_CURRENT);
6615
6616        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6617                type, packageName, activity, resultWho,
6618                requestCode, intents, resolvedTypes, flags, options, userId);
6619        WeakReference<PendingIntentRecord> ref;
6620        ref = mIntentSenderRecords.get(key);
6621        PendingIntentRecord rec = ref != null ? ref.get() : null;
6622        if (rec != null) {
6623            if (!cancelCurrent) {
6624                if (updateCurrent) {
6625                    if (rec.key.requestIntent != null) {
6626                        rec.key.requestIntent.replaceExtras(intents != null ?
6627                                intents[intents.length - 1] : null);
6628                    }
6629                    if (intents != null) {
6630                        intents[intents.length-1] = rec.key.requestIntent;
6631                        rec.key.allIntents = intents;
6632                        rec.key.allResolvedTypes = resolvedTypes;
6633                    } else {
6634                        rec.key.allIntents = null;
6635                        rec.key.allResolvedTypes = null;
6636                    }
6637                }
6638                return rec;
6639            }
6640            rec.canceled = true;
6641            mIntentSenderRecords.remove(key);
6642        }
6643        if (noCreate) {
6644            return rec;
6645        }
6646        rec = new PendingIntentRecord(this, key, callingUid);
6647        mIntentSenderRecords.put(key, rec.ref);
6648        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6649            if (activity.pendingResults == null) {
6650                activity.pendingResults
6651                        = new HashSet<WeakReference<PendingIntentRecord>>();
6652            }
6653            activity.pendingResults.add(rec.ref);
6654        }
6655        return rec;
6656    }
6657
6658    @Override
6659    public void cancelIntentSender(IIntentSender sender) {
6660        if (!(sender instanceof PendingIntentRecord)) {
6661            return;
6662        }
6663        synchronized(this) {
6664            PendingIntentRecord rec = (PendingIntentRecord)sender;
6665            try {
6666                int uid = AppGlobals.getPackageManager()
6667                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6668                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6669                    String msg = "Permission Denial: cancelIntentSender() from pid="
6670                        + Binder.getCallingPid()
6671                        + ", uid=" + Binder.getCallingUid()
6672                        + " is not allowed to cancel packges "
6673                        + rec.key.packageName;
6674                    Slog.w(TAG, msg);
6675                    throw new SecurityException(msg);
6676                }
6677            } catch (RemoteException e) {
6678                throw new SecurityException(e);
6679            }
6680            cancelIntentSenderLocked(rec, true);
6681        }
6682    }
6683
6684    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6685        rec.canceled = true;
6686        mIntentSenderRecords.remove(rec.key);
6687        if (cleanActivity && rec.key.activity != null) {
6688            rec.key.activity.pendingResults.remove(rec.ref);
6689        }
6690    }
6691
6692    @Override
6693    public String getPackageForIntentSender(IIntentSender pendingResult) {
6694        if (!(pendingResult instanceof PendingIntentRecord)) {
6695            return null;
6696        }
6697        try {
6698            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6699            return res.key.packageName;
6700        } catch (ClassCastException e) {
6701        }
6702        return null;
6703    }
6704
6705    @Override
6706    public int getUidForIntentSender(IIntentSender sender) {
6707        if (sender instanceof PendingIntentRecord) {
6708            try {
6709                PendingIntentRecord res = (PendingIntentRecord)sender;
6710                return res.uid;
6711            } catch (ClassCastException e) {
6712            }
6713        }
6714        return -1;
6715    }
6716
6717    @Override
6718    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6719        if (!(pendingResult instanceof PendingIntentRecord)) {
6720            return false;
6721        }
6722        try {
6723            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6724            if (res.key.allIntents == null) {
6725                return false;
6726            }
6727            for (int i=0; i<res.key.allIntents.length; i++) {
6728                Intent intent = res.key.allIntents[i];
6729                if (intent.getPackage() != null && intent.getComponent() != null) {
6730                    return false;
6731                }
6732            }
6733            return true;
6734        } catch (ClassCastException e) {
6735        }
6736        return false;
6737    }
6738
6739    @Override
6740    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6741        if (!(pendingResult instanceof PendingIntentRecord)) {
6742            return false;
6743        }
6744        try {
6745            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6746            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6747                return true;
6748            }
6749            return false;
6750        } catch (ClassCastException e) {
6751        }
6752        return false;
6753    }
6754
6755    @Override
6756    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6757        if (!(pendingResult instanceof PendingIntentRecord)) {
6758            return null;
6759        }
6760        try {
6761            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6762            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6763        } catch (ClassCastException e) {
6764        }
6765        return null;
6766    }
6767
6768    @Override
6769    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6770        if (!(pendingResult instanceof PendingIntentRecord)) {
6771            return null;
6772        }
6773        try {
6774            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6775            synchronized (this) {
6776                return getTagForIntentSenderLocked(res, prefix);
6777            }
6778        } catch (ClassCastException e) {
6779        }
6780        return null;
6781    }
6782
6783    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6784        final Intent intent = res.key.requestIntent;
6785        if (intent != null) {
6786            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6787                    || res.lastTagPrefix.equals(prefix))) {
6788                return res.lastTag;
6789            }
6790            res.lastTagPrefix = prefix;
6791            final StringBuilder sb = new StringBuilder(128);
6792            if (prefix != null) {
6793                sb.append(prefix);
6794            }
6795            if (intent.getAction() != null) {
6796                sb.append(intent.getAction());
6797            } else if (intent.getComponent() != null) {
6798                intent.getComponent().appendShortString(sb);
6799            } else {
6800                sb.append("?");
6801            }
6802            return res.lastTag = sb.toString();
6803        }
6804        return null;
6805    }
6806
6807    @Override
6808    public void setProcessLimit(int max) {
6809        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6810                "setProcessLimit()");
6811        synchronized (this) {
6812            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6813            mProcessLimitOverride = max;
6814        }
6815        trimApplications();
6816    }
6817
6818    @Override
6819    public int getProcessLimit() {
6820        synchronized (this) {
6821            return mProcessLimitOverride;
6822        }
6823    }
6824
6825    void foregroundTokenDied(ForegroundToken token) {
6826        synchronized (ActivityManagerService.this) {
6827            synchronized (mPidsSelfLocked) {
6828                ForegroundToken cur
6829                    = mForegroundProcesses.get(token.pid);
6830                if (cur != token) {
6831                    return;
6832                }
6833                mForegroundProcesses.remove(token.pid);
6834                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6835                if (pr == null) {
6836                    return;
6837                }
6838                pr.forcingToForeground = null;
6839                updateProcessForegroundLocked(pr, false, false);
6840            }
6841            updateOomAdjLocked();
6842        }
6843    }
6844
6845    @Override
6846    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6847        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6848                "setProcessForeground()");
6849        synchronized(this) {
6850            boolean changed = false;
6851
6852            synchronized (mPidsSelfLocked) {
6853                ProcessRecord pr = mPidsSelfLocked.get(pid);
6854                if (pr == null && isForeground) {
6855                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6856                    return;
6857                }
6858                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6859                if (oldToken != null) {
6860                    oldToken.token.unlinkToDeath(oldToken, 0);
6861                    mForegroundProcesses.remove(pid);
6862                    if (pr != null) {
6863                        pr.forcingToForeground = null;
6864                    }
6865                    changed = true;
6866                }
6867                if (isForeground && token != null) {
6868                    ForegroundToken newToken = new ForegroundToken() {
6869                        @Override
6870                        public void binderDied() {
6871                            foregroundTokenDied(this);
6872                        }
6873                    };
6874                    newToken.pid = pid;
6875                    newToken.token = token;
6876                    try {
6877                        token.linkToDeath(newToken, 0);
6878                        mForegroundProcesses.put(pid, newToken);
6879                        pr.forcingToForeground = token;
6880                        changed = true;
6881                    } catch (RemoteException e) {
6882                        // If the process died while doing this, we will later
6883                        // do the cleanup with the process death link.
6884                    }
6885                }
6886            }
6887
6888            if (changed) {
6889                updateOomAdjLocked();
6890            }
6891        }
6892    }
6893
6894    // =========================================================
6895    // PROCESS INFO
6896    // =========================================================
6897
6898    static class ProcessInfoService extends IProcessInfoService.Stub {
6899        final ActivityManagerService mActivityManagerService;
6900        ProcessInfoService(ActivityManagerService activityManagerService) {
6901            mActivityManagerService = activityManagerService;
6902        }
6903
6904        @Override
6905        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6906            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6907        }
6908    }
6909
6910    /**
6911     * For each PID in the given input array, write the current process state
6912     * for that process into the output array, or -1 to indicate that no
6913     * process with the given PID exists.
6914     */
6915    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6916        if (pids == null) {
6917            throw new NullPointerException("pids");
6918        } else if (states == null) {
6919            throw new NullPointerException("states");
6920        } else if (pids.length != states.length) {
6921            throw new IllegalArgumentException("input and output arrays have different lengths!");
6922        }
6923
6924        synchronized (mPidsSelfLocked) {
6925            for (int i = 0; i < pids.length; i++) {
6926                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6927                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6928                        pr.curProcState;
6929            }
6930        }
6931    }
6932
6933    // =========================================================
6934    // PERMISSIONS
6935    // =========================================================
6936
6937    static class PermissionController extends IPermissionController.Stub {
6938        ActivityManagerService mActivityManagerService;
6939        PermissionController(ActivityManagerService activityManagerService) {
6940            mActivityManagerService = activityManagerService;
6941        }
6942
6943        @Override
6944        public boolean checkPermission(String permission, int pid, int uid) {
6945            return mActivityManagerService.checkPermission(permission, pid,
6946                    uid) == PackageManager.PERMISSION_GRANTED;
6947        }
6948
6949        @Override
6950        public String[] getPackagesForUid(int uid) {
6951            return mActivityManagerService.mContext.getPackageManager()
6952                    .getPackagesForUid(uid);
6953        }
6954
6955        @Override
6956        public boolean isRuntimePermission(String permission) {
6957            try {
6958                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6959                        .getPermissionInfo(permission, 0);
6960                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6961            } catch (NameNotFoundException nnfe) {
6962                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6963            }
6964            return false;
6965        }
6966    }
6967
6968    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6969        @Override
6970        public int checkComponentPermission(String permission, int pid, int uid,
6971                int owningUid, boolean exported) {
6972            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6973                    owningUid, exported);
6974        }
6975
6976        @Override
6977        public Object getAMSLock() {
6978            return ActivityManagerService.this;
6979        }
6980    }
6981
6982    /**
6983     * This can be called with or without the global lock held.
6984     */
6985    int checkComponentPermission(String permission, int pid, int uid,
6986            int owningUid, boolean exported) {
6987        if (pid == MY_PID) {
6988            return PackageManager.PERMISSION_GRANTED;
6989        }
6990        return ActivityManager.checkComponentPermission(permission, uid,
6991                owningUid, exported);
6992    }
6993
6994    /**
6995     * As the only public entry point for permissions checking, this method
6996     * can enforce the semantic that requesting a check on a null global
6997     * permission is automatically denied.  (Internally a null permission
6998     * string is used when calling {@link #checkComponentPermission} in cases
6999     * when only uid-based security is needed.)
7000     *
7001     * This can be called with or without the global lock held.
7002     */
7003    @Override
7004    public int checkPermission(String permission, int pid, int uid) {
7005        if (permission == null) {
7006            return PackageManager.PERMISSION_DENIED;
7007        }
7008        return checkComponentPermission(permission, pid, uid, -1, true);
7009    }
7010
7011    @Override
7012    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7013        if (permission == null) {
7014            return PackageManager.PERMISSION_DENIED;
7015        }
7016
7017        // We might be performing an operation on behalf of an indirect binder
7018        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7019        // client identity accordingly before proceeding.
7020        Identity tlsIdentity = sCallerIdentity.get();
7021        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7022            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7023                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7024            uid = tlsIdentity.uid;
7025            pid = tlsIdentity.pid;
7026        }
7027
7028        return checkComponentPermission(permission, pid, uid, -1, true);
7029    }
7030
7031    /**
7032     * Binder IPC calls go through the public entry point.
7033     * This can be called with or without the global lock held.
7034     */
7035    int checkCallingPermission(String permission) {
7036        return checkPermission(permission,
7037                Binder.getCallingPid(),
7038                UserHandle.getAppId(Binder.getCallingUid()));
7039    }
7040
7041    /**
7042     * This can be called with or without the global lock held.
7043     */
7044    void enforceCallingPermission(String permission, String func) {
7045        if (checkCallingPermission(permission)
7046                == PackageManager.PERMISSION_GRANTED) {
7047            return;
7048        }
7049
7050        String msg = "Permission Denial: " + func + " from pid="
7051                + Binder.getCallingPid()
7052                + ", uid=" + Binder.getCallingUid()
7053                + " requires " + permission;
7054        Slog.w(TAG, msg);
7055        throw new SecurityException(msg);
7056    }
7057
7058    /**
7059     * Determine if UID is holding permissions required to access {@link Uri} in
7060     * the given {@link ProviderInfo}. Final permission checking is always done
7061     * in {@link ContentProvider}.
7062     */
7063    private final boolean checkHoldingPermissionsLocked(
7064            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7065        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7066                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7067        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7068            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7069                    != PERMISSION_GRANTED) {
7070                return false;
7071            }
7072        }
7073        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7074    }
7075
7076    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7077            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7078        if (pi.applicationInfo.uid == uid) {
7079            return true;
7080        } else if (!pi.exported) {
7081            return false;
7082        }
7083
7084        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7085        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7086        try {
7087            // check if target holds top-level <provider> permissions
7088            if (!readMet && pi.readPermission != null && considerUidPermissions
7089                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7090                readMet = true;
7091            }
7092            if (!writeMet && pi.writePermission != null && considerUidPermissions
7093                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7094                writeMet = true;
7095            }
7096
7097            // track if unprotected read/write is allowed; any denied
7098            // <path-permission> below removes this ability
7099            boolean allowDefaultRead = pi.readPermission == null;
7100            boolean allowDefaultWrite = pi.writePermission == null;
7101
7102            // check if target holds any <path-permission> that match uri
7103            final PathPermission[] pps = pi.pathPermissions;
7104            if (pps != null) {
7105                final String path = grantUri.uri.getPath();
7106                int i = pps.length;
7107                while (i > 0 && (!readMet || !writeMet)) {
7108                    i--;
7109                    PathPermission pp = pps[i];
7110                    if (pp.match(path)) {
7111                        if (!readMet) {
7112                            final String pprperm = pp.getReadPermission();
7113                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7114                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7115                                    + ": match=" + pp.match(path)
7116                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7117                            if (pprperm != null) {
7118                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7119                                        == PERMISSION_GRANTED) {
7120                                    readMet = true;
7121                                } else {
7122                                    allowDefaultRead = false;
7123                                }
7124                            }
7125                        }
7126                        if (!writeMet) {
7127                            final String ppwperm = pp.getWritePermission();
7128                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7129                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7130                                    + ": match=" + pp.match(path)
7131                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7132                            if (ppwperm != null) {
7133                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7134                                        == PERMISSION_GRANTED) {
7135                                    writeMet = true;
7136                                } else {
7137                                    allowDefaultWrite = false;
7138                                }
7139                            }
7140                        }
7141                    }
7142                }
7143            }
7144
7145            // grant unprotected <provider> read/write, if not blocked by
7146            // <path-permission> above
7147            if (allowDefaultRead) readMet = true;
7148            if (allowDefaultWrite) writeMet = true;
7149
7150        } catch (RemoteException e) {
7151            return false;
7152        }
7153
7154        return readMet && writeMet;
7155    }
7156
7157    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7158        ProviderInfo pi = null;
7159        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7160        if (cpr != null) {
7161            pi = cpr.info;
7162        } else {
7163            try {
7164                pi = AppGlobals.getPackageManager().resolveContentProvider(
7165                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7166            } catch (RemoteException ex) {
7167            }
7168        }
7169        return pi;
7170    }
7171
7172    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7173        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7174        if (targetUris != null) {
7175            return targetUris.get(grantUri);
7176        }
7177        return null;
7178    }
7179
7180    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7181            String targetPkg, int targetUid, GrantUri grantUri) {
7182        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7183        if (targetUris == null) {
7184            targetUris = Maps.newArrayMap();
7185            mGrantedUriPermissions.put(targetUid, targetUris);
7186        }
7187
7188        UriPermission perm = targetUris.get(grantUri);
7189        if (perm == null) {
7190            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7191            targetUris.put(grantUri, perm);
7192        }
7193
7194        return perm;
7195    }
7196
7197    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7198            final int modeFlags) {
7199        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7200        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7201                : UriPermission.STRENGTH_OWNED;
7202
7203        // Root gets to do everything.
7204        if (uid == 0) {
7205            return true;
7206        }
7207
7208        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7209        if (perms == null) return false;
7210
7211        // First look for exact match
7212        final UriPermission exactPerm = perms.get(grantUri);
7213        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7214            return true;
7215        }
7216
7217        // No exact match, look for prefixes
7218        final int N = perms.size();
7219        for (int i = 0; i < N; i++) {
7220            final UriPermission perm = perms.valueAt(i);
7221            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7222                    && perm.getStrength(modeFlags) >= minStrength) {
7223                return true;
7224            }
7225        }
7226
7227        return false;
7228    }
7229
7230    /**
7231     * @param uri This uri must NOT contain an embedded userId.
7232     * @param userId The userId in which the uri is to be resolved.
7233     */
7234    @Override
7235    public int checkUriPermission(Uri uri, int pid, int uid,
7236            final int modeFlags, int userId, IBinder callerToken) {
7237        enforceNotIsolatedCaller("checkUriPermission");
7238
7239        // Another redirected-binder-call permissions check as in
7240        // {@link checkPermissionWithToken}.
7241        Identity tlsIdentity = sCallerIdentity.get();
7242        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7243            uid = tlsIdentity.uid;
7244            pid = tlsIdentity.pid;
7245        }
7246
7247        // Our own process gets to do everything.
7248        if (pid == MY_PID) {
7249            return PackageManager.PERMISSION_GRANTED;
7250        }
7251        synchronized (this) {
7252            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7253                    ? PackageManager.PERMISSION_GRANTED
7254                    : PackageManager.PERMISSION_DENIED;
7255        }
7256    }
7257
7258    /**
7259     * Check if the targetPkg can be granted permission to access uri by
7260     * the callingUid using the given modeFlags.  Throws a security exception
7261     * if callingUid is not allowed to do this.  Returns the uid of the target
7262     * if the URI permission grant should be performed; returns -1 if it is not
7263     * needed (for example targetPkg already has permission to access the URI).
7264     * If you already know the uid of the target, you can supply it in
7265     * lastTargetUid else set that to -1.
7266     */
7267    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7268            final int modeFlags, int lastTargetUid) {
7269        if (!Intent.isAccessUriMode(modeFlags)) {
7270            return -1;
7271        }
7272
7273        if (targetPkg != null) {
7274            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7275                    "Checking grant " + targetPkg + " permission to " + grantUri);
7276        }
7277
7278        final IPackageManager pm = AppGlobals.getPackageManager();
7279
7280        // If this is not a content: uri, we can't do anything with it.
7281        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7282            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7283                    "Can't grant URI permission for non-content URI: " + grantUri);
7284            return -1;
7285        }
7286
7287        final String authority = grantUri.uri.getAuthority();
7288        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7289        if (pi == null) {
7290            Slog.w(TAG, "No content provider found for permission check: " +
7291                    grantUri.uri.toSafeString());
7292            return -1;
7293        }
7294
7295        int targetUid = lastTargetUid;
7296        if (targetUid < 0 && targetPkg != null) {
7297            try {
7298                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7299                if (targetUid < 0) {
7300                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7301                            "Can't grant URI permission no uid for: " + targetPkg);
7302                    return -1;
7303                }
7304            } catch (RemoteException ex) {
7305                return -1;
7306            }
7307        }
7308
7309        if (targetUid >= 0) {
7310            // First...  does the target actually need this permission?
7311            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7312                // No need to grant the target this permission.
7313                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7314                        "Target " + targetPkg + " already has full permission to " + grantUri);
7315                return -1;
7316            }
7317        } else {
7318            // First...  there is no target package, so can anyone access it?
7319            boolean allowed = pi.exported;
7320            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7321                if (pi.readPermission != null) {
7322                    allowed = false;
7323                }
7324            }
7325            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7326                if (pi.writePermission != null) {
7327                    allowed = false;
7328                }
7329            }
7330            if (allowed) {
7331                return -1;
7332            }
7333        }
7334
7335        /* There is a special cross user grant if:
7336         * - The target is on another user.
7337         * - Apps on the current user can access the uri without any uid permissions.
7338         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7339         * grant uri permissions.
7340         */
7341        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7342                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7343                modeFlags, false /*without considering the uid permissions*/);
7344
7345        // Second...  is the provider allowing granting of URI permissions?
7346        if (!specialCrossUserGrant) {
7347            if (!pi.grantUriPermissions) {
7348                throw new SecurityException("Provider " + pi.packageName
7349                        + "/" + pi.name
7350                        + " does not allow granting of Uri permissions (uri "
7351                        + grantUri + ")");
7352            }
7353            if (pi.uriPermissionPatterns != null) {
7354                final int N = pi.uriPermissionPatterns.length;
7355                boolean allowed = false;
7356                for (int i=0; i<N; i++) {
7357                    if (pi.uriPermissionPatterns[i] != null
7358                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7359                        allowed = true;
7360                        break;
7361                    }
7362                }
7363                if (!allowed) {
7364                    throw new SecurityException("Provider " + pi.packageName
7365                            + "/" + pi.name
7366                            + " does not allow granting of permission to path of Uri "
7367                            + grantUri);
7368                }
7369            }
7370        }
7371
7372        // Third...  does the caller itself have permission to access
7373        // this uri?
7374        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7375            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7376                // Require they hold a strong enough Uri permission
7377                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7378                    throw new SecurityException("Uid " + callingUid
7379                            + " does not have permission to uri " + grantUri);
7380                }
7381            }
7382        }
7383        return targetUid;
7384    }
7385
7386    /**
7387     * @param uri This uri must NOT contain an embedded userId.
7388     * @param userId The userId in which the uri is to be resolved.
7389     */
7390    @Override
7391    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7392            final int modeFlags, int userId) {
7393        enforceNotIsolatedCaller("checkGrantUriPermission");
7394        synchronized(this) {
7395            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7396                    new GrantUri(userId, uri, false), modeFlags, -1);
7397        }
7398    }
7399
7400    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7401            final int modeFlags, UriPermissionOwner owner) {
7402        if (!Intent.isAccessUriMode(modeFlags)) {
7403            return;
7404        }
7405
7406        // So here we are: the caller has the assumed permission
7407        // to the uri, and the target doesn't.  Let's now give this to
7408        // the target.
7409
7410        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7411                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7412
7413        final String authority = grantUri.uri.getAuthority();
7414        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7415        if (pi == null) {
7416            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7417            return;
7418        }
7419
7420        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7421            grantUri.prefix = true;
7422        }
7423        final UriPermission perm = findOrCreateUriPermissionLocked(
7424                pi.packageName, targetPkg, targetUid, grantUri);
7425        perm.grantModes(modeFlags, owner);
7426    }
7427
7428    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7429            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7430        if (targetPkg == null) {
7431            throw new NullPointerException("targetPkg");
7432        }
7433        int targetUid;
7434        final IPackageManager pm = AppGlobals.getPackageManager();
7435        try {
7436            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7437        } catch (RemoteException ex) {
7438            return;
7439        }
7440
7441        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7442                targetUid);
7443        if (targetUid < 0) {
7444            return;
7445        }
7446
7447        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7448                owner);
7449    }
7450
7451    static class NeededUriGrants extends ArrayList<GrantUri> {
7452        final String targetPkg;
7453        final int targetUid;
7454        final int flags;
7455
7456        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7457            this.targetPkg = targetPkg;
7458            this.targetUid = targetUid;
7459            this.flags = flags;
7460        }
7461    }
7462
7463    /**
7464     * Like checkGrantUriPermissionLocked, but takes an Intent.
7465     */
7466    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7467            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7468        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7469                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7470                + " clip=" + (intent != null ? intent.getClipData() : null)
7471                + " from " + intent + "; flags=0x"
7472                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7473
7474        if (targetPkg == null) {
7475            throw new NullPointerException("targetPkg");
7476        }
7477
7478        if (intent == null) {
7479            return null;
7480        }
7481        Uri data = intent.getData();
7482        ClipData clip = intent.getClipData();
7483        if (data == null && clip == null) {
7484            return null;
7485        }
7486        // Default userId for uris in the intent (if they don't specify it themselves)
7487        int contentUserHint = intent.getContentUserHint();
7488        if (contentUserHint == UserHandle.USER_CURRENT) {
7489            contentUserHint = UserHandle.getUserId(callingUid);
7490        }
7491        final IPackageManager pm = AppGlobals.getPackageManager();
7492        int targetUid;
7493        if (needed != null) {
7494            targetUid = needed.targetUid;
7495        } else {
7496            try {
7497                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7498            } catch (RemoteException ex) {
7499                return null;
7500            }
7501            if (targetUid < 0) {
7502                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7503                        "Can't grant URI permission no uid for: " + targetPkg
7504                        + " on user " + targetUserId);
7505                return null;
7506            }
7507        }
7508        if (data != null) {
7509            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7510            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7511                    targetUid);
7512            if (targetUid > 0) {
7513                if (needed == null) {
7514                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7515                }
7516                needed.add(grantUri);
7517            }
7518        }
7519        if (clip != null) {
7520            for (int i=0; i<clip.getItemCount(); i++) {
7521                Uri uri = clip.getItemAt(i).getUri();
7522                if (uri != null) {
7523                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7524                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7525                            targetUid);
7526                    if (targetUid > 0) {
7527                        if (needed == null) {
7528                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7529                        }
7530                        needed.add(grantUri);
7531                    }
7532                } else {
7533                    Intent clipIntent = clip.getItemAt(i).getIntent();
7534                    if (clipIntent != null) {
7535                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7536                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7537                        if (newNeeded != null) {
7538                            needed = newNeeded;
7539                        }
7540                    }
7541                }
7542            }
7543        }
7544
7545        return needed;
7546    }
7547
7548    /**
7549     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7550     */
7551    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7552            UriPermissionOwner owner) {
7553        if (needed != null) {
7554            for (int i=0; i<needed.size(); i++) {
7555                GrantUri grantUri = needed.get(i);
7556                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7557                        grantUri, needed.flags, owner);
7558            }
7559        }
7560    }
7561
7562    void grantUriPermissionFromIntentLocked(int callingUid,
7563            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7564        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7565                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7566        if (needed == null) {
7567            return;
7568        }
7569
7570        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7571    }
7572
7573    /**
7574     * @param uri This uri must NOT contain an embedded userId.
7575     * @param userId The userId in which the uri is to be resolved.
7576     */
7577    @Override
7578    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7579            final int modeFlags, int userId) {
7580        enforceNotIsolatedCaller("grantUriPermission");
7581        GrantUri grantUri = new GrantUri(userId, uri, false);
7582        synchronized(this) {
7583            final ProcessRecord r = getRecordForAppLocked(caller);
7584            if (r == null) {
7585                throw new SecurityException("Unable to find app for caller "
7586                        + caller
7587                        + " when granting permission to uri " + grantUri);
7588            }
7589            if (targetPkg == null) {
7590                throw new IllegalArgumentException("null target");
7591            }
7592            if (grantUri == null) {
7593                throw new IllegalArgumentException("null uri");
7594            }
7595
7596            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7597                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7598                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7599                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7600
7601            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7602                    UserHandle.getUserId(r.uid));
7603        }
7604    }
7605
7606    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7607        if (perm.modeFlags == 0) {
7608            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7609                    perm.targetUid);
7610            if (perms != null) {
7611                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7612                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7613
7614                perms.remove(perm.uri);
7615                if (perms.isEmpty()) {
7616                    mGrantedUriPermissions.remove(perm.targetUid);
7617                }
7618            }
7619        }
7620    }
7621
7622    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7623        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7624                "Revoking all granted permissions to " + grantUri);
7625
7626        final IPackageManager pm = AppGlobals.getPackageManager();
7627        final String authority = grantUri.uri.getAuthority();
7628        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7629        if (pi == null) {
7630            Slog.w(TAG, "No content provider found for permission revoke: "
7631                    + grantUri.toSafeString());
7632            return;
7633        }
7634
7635        // Does the caller have this permission on the URI?
7636        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7637            // If they don't have direct access to the URI, then revoke any
7638            // ownerless URI permissions that have been granted to them.
7639            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7640            if (perms != null) {
7641                boolean persistChanged = false;
7642                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7643                    final UriPermission perm = it.next();
7644                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7645                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7646                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7647                                "Revoking non-owned " + perm.targetUid
7648                                + " permission to " + perm.uri);
7649                        persistChanged |= perm.revokeModes(
7650                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7651                        if (perm.modeFlags == 0) {
7652                            it.remove();
7653                        }
7654                    }
7655                }
7656                if (perms.isEmpty()) {
7657                    mGrantedUriPermissions.remove(callingUid);
7658                }
7659                if (persistChanged) {
7660                    schedulePersistUriGrants();
7661                }
7662            }
7663            return;
7664        }
7665
7666        boolean persistChanged = false;
7667
7668        // Go through all of the permissions and remove any that match.
7669        int N = mGrantedUriPermissions.size();
7670        for (int i = 0; i < N; i++) {
7671            final int targetUid = mGrantedUriPermissions.keyAt(i);
7672            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7673
7674            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7675                final UriPermission perm = it.next();
7676                if (perm.uri.sourceUserId == grantUri.sourceUserId
7677                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7678                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7679                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7680                    persistChanged |= perm.revokeModes(
7681                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7682                    if (perm.modeFlags == 0) {
7683                        it.remove();
7684                    }
7685                }
7686            }
7687
7688            if (perms.isEmpty()) {
7689                mGrantedUriPermissions.remove(targetUid);
7690                N--;
7691                i--;
7692            }
7693        }
7694
7695        if (persistChanged) {
7696            schedulePersistUriGrants();
7697        }
7698    }
7699
7700    /**
7701     * @param uri This uri must NOT contain an embedded userId.
7702     * @param userId The userId in which the uri is to be resolved.
7703     */
7704    @Override
7705    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7706            int userId) {
7707        enforceNotIsolatedCaller("revokeUriPermission");
7708        synchronized(this) {
7709            final ProcessRecord r = getRecordForAppLocked(caller);
7710            if (r == null) {
7711                throw new SecurityException("Unable to find app for caller "
7712                        + caller
7713                        + " when revoking permission to uri " + uri);
7714            }
7715            if (uri == null) {
7716                Slog.w(TAG, "revokeUriPermission: null uri");
7717                return;
7718            }
7719
7720            if (!Intent.isAccessUriMode(modeFlags)) {
7721                return;
7722            }
7723
7724            final String authority = uri.getAuthority();
7725            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7726            if (pi == null) {
7727                Slog.w(TAG, "No content provider found for permission revoke: "
7728                        + uri.toSafeString());
7729                return;
7730            }
7731
7732            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7733        }
7734    }
7735
7736    /**
7737     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7738     * given package.
7739     *
7740     * @param packageName Package name to match, or {@code null} to apply to all
7741     *            packages.
7742     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7743     *            to all users.
7744     * @param persistable If persistable grants should be removed.
7745     */
7746    private void removeUriPermissionsForPackageLocked(
7747            String packageName, int userHandle, boolean persistable) {
7748        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7749            throw new IllegalArgumentException("Must narrow by either package or user");
7750        }
7751
7752        boolean persistChanged = false;
7753
7754        int N = mGrantedUriPermissions.size();
7755        for (int i = 0; i < N; i++) {
7756            final int targetUid = mGrantedUriPermissions.keyAt(i);
7757            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7758
7759            // Only inspect grants matching user
7760            if (userHandle == UserHandle.USER_ALL
7761                    || userHandle == UserHandle.getUserId(targetUid)) {
7762                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7763                    final UriPermission perm = it.next();
7764
7765                    // Only inspect grants matching package
7766                    if (packageName == null || perm.sourcePkg.equals(packageName)
7767                            || perm.targetPkg.equals(packageName)) {
7768                        persistChanged |= perm.revokeModes(persistable
7769                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7770
7771                        // Only remove when no modes remain; any persisted grants
7772                        // will keep this alive.
7773                        if (perm.modeFlags == 0) {
7774                            it.remove();
7775                        }
7776                    }
7777                }
7778
7779                if (perms.isEmpty()) {
7780                    mGrantedUriPermissions.remove(targetUid);
7781                    N--;
7782                    i--;
7783                }
7784            }
7785        }
7786
7787        if (persistChanged) {
7788            schedulePersistUriGrants();
7789        }
7790    }
7791
7792    @Override
7793    public IBinder newUriPermissionOwner(String name) {
7794        enforceNotIsolatedCaller("newUriPermissionOwner");
7795        synchronized(this) {
7796            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7797            return owner.getExternalTokenLocked();
7798        }
7799    }
7800
7801    /**
7802     * @param uri This uri must NOT contain an embedded userId.
7803     * @param sourceUserId The userId in which the uri is to be resolved.
7804     * @param targetUserId The userId of the app that receives the grant.
7805     */
7806    @Override
7807    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7808            final int modeFlags, int sourceUserId, int targetUserId) {
7809        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7810                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7811        synchronized(this) {
7812            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7813            if (owner == null) {
7814                throw new IllegalArgumentException("Unknown owner: " + token);
7815            }
7816            if (fromUid != Binder.getCallingUid()) {
7817                if (Binder.getCallingUid() != Process.myUid()) {
7818                    // Only system code can grant URI permissions on behalf
7819                    // of other users.
7820                    throw new SecurityException("nice try");
7821                }
7822            }
7823            if (targetPkg == null) {
7824                throw new IllegalArgumentException("null target");
7825            }
7826            if (uri == null) {
7827                throw new IllegalArgumentException("null uri");
7828            }
7829
7830            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7831                    modeFlags, owner, targetUserId);
7832        }
7833    }
7834
7835    /**
7836     * @param uri This uri must NOT contain an embedded userId.
7837     * @param userId The userId in which the uri is to be resolved.
7838     */
7839    @Override
7840    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7841        synchronized(this) {
7842            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7843            if (owner == null) {
7844                throw new IllegalArgumentException("Unknown owner: " + token);
7845            }
7846
7847            if (uri == null) {
7848                owner.removeUriPermissionsLocked(mode);
7849            } else {
7850                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7851            }
7852        }
7853    }
7854
7855    private void schedulePersistUriGrants() {
7856        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7857            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7858                    10 * DateUtils.SECOND_IN_MILLIS);
7859        }
7860    }
7861
7862    private void writeGrantedUriPermissions() {
7863        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7864
7865        // Snapshot permissions so we can persist without lock
7866        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7867        synchronized (this) {
7868            final int size = mGrantedUriPermissions.size();
7869            for (int i = 0; i < size; i++) {
7870                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7871                for (UriPermission perm : perms.values()) {
7872                    if (perm.persistedModeFlags != 0) {
7873                        persist.add(perm.snapshot());
7874                    }
7875                }
7876            }
7877        }
7878
7879        FileOutputStream fos = null;
7880        try {
7881            fos = mGrantFile.startWrite();
7882
7883            XmlSerializer out = new FastXmlSerializer();
7884            out.setOutput(fos, StandardCharsets.UTF_8.name());
7885            out.startDocument(null, true);
7886            out.startTag(null, TAG_URI_GRANTS);
7887            for (UriPermission.Snapshot perm : persist) {
7888                out.startTag(null, TAG_URI_GRANT);
7889                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7890                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7891                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7892                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7893                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7894                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7895                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7896                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7897                out.endTag(null, TAG_URI_GRANT);
7898            }
7899            out.endTag(null, TAG_URI_GRANTS);
7900            out.endDocument();
7901
7902            mGrantFile.finishWrite(fos);
7903        } catch (IOException e) {
7904            if (fos != null) {
7905                mGrantFile.failWrite(fos);
7906            }
7907        }
7908    }
7909
7910    private void readGrantedUriPermissionsLocked() {
7911        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7912
7913        final long now = System.currentTimeMillis();
7914
7915        FileInputStream fis = null;
7916        try {
7917            fis = mGrantFile.openRead();
7918            final XmlPullParser in = Xml.newPullParser();
7919            in.setInput(fis, StandardCharsets.UTF_8.name());
7920
7921            int type;
7922            while ((type = in.next()) != END_DOCUMENT) {
7923                final String tag = in.getName();
7924                if (type == START_TAG) {
7925                    if (TAG_URI_GRANT.equals(tag)) {
7926                        final int sourceUserId;
7927                        final int targetUserId;
7928                        final int userHandle = readIntAttribute(in,
7929                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7930                        if (userHandle != UserHandle.USER_NULL) {
7931                            // For backwards compatibility.
7932                            sourceUserId = userHandle;
7933                            targetUserId = userHandle;
7934                        } else {
7935                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7936                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7937                        }
7938                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7939                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7940                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7941                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7942                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7943                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7944
7945                        // Sanity check that provider still belongs to source package
7946                        final ProviderInfo pi = getProviderInfoLocked(
7947                                uri.getAuthority(), sourceUserId);
7948                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7949                            int targetUid = -1;
7950                            try {
7951                                targetUid = AppGlobals.getPackageManager()
7952                                        .getPackageUid(targetPkg, targetUserId);
7953                            } catch (RemoteException e) {
7954                            }
7955                            if (targetUid != -1) {
7956                                final UriPermission perm = findOrCreateUriPermissionLocked(
7957                                        sourcePkg, targetPkg, targetUid,
7958                                        new GrantUri(sourceUserId, uri, prefix));
7959                                perm.initPersistedModes(modeFlags, createdTime);
7960                            }
7961                        } else {
7962                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7963                                    + " but instead found " + pi);
7964                        }
7965                    }
7966                }
7967            }
7968        } catch (FileNotFoundException e) {
7969            // Missing grants is okay
7970        } catch (IOException e) {
7971            Slog.wtf(TAG, "Failed reading Uri grants", e);
7972        } catch (XmlPullParserException e) {
7973            Slog.wtf(TAG, "Failed reading Uri grants", e);
7974        } finally {
7975            IoUtils.closeQuietly(fis);
7976        }
7977    }
7978
7979    /**
7980     * @param uri This uri must NOT contain an embedded userId.
7981     * @param userId The userId in which the uri is to be resolved.
7982     */
7983    @Override
7984    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7985        enforceNotIsolatedCaller("takePersistableUriPermission");
7986
7987        Preconditions.checkFlagsArgument(modeFlags,
7988                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7989
7990        synchronized (this) {
7991            final int callingUid = Binder.getCallingUid();
7992            boolean persistChanged = false;
7993            GrantUri grantUri = new GrantUri(userId, uri, false);
7994
7995            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7996                    new GrantUri(userId, uri, false));
7997            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7998                    new GrantUri(userId, uri, true));
7999
8000            final boolean exactValid = (exactPerm != null)
8001                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8002            final boolean prefixValid = (prefixPerm != null)
8003                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8004
8005            if (!(exactValid || prefixValid)) {
8006                throw new SecurityException("No persistable permission grants found for UID "
8007                        + callingUid + " and Uri " + grantUri.toSafeString());
8008            }
8009
8010            if (exactValid) {
8011                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8012            }
8013            if (prefixValid) {
8014                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8015            }
8016
8017            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8018
8019            if (persistChanged) {
8020                schedulePersistUriGrants();
8021            }
8022        }
8023    }
8024
8025    /**
8026     * @param uri This uri must NOT contain an embedded userId.
8027     * @param userId The userId in which the uri is to be resolved.
8028     */
8029    @Override
8030    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8031        enforceNotIsolatedCaller("releasePersistableUriPermission");
8032
8033        Preconditions.checkFlagsArgument(modeFlags,
8034                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8035
8036        synchronized (this) {
8037            final int callingUid = Binder.getCallingUid();
8038            boolean persistChanged = false;
8039
8040            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8041                    new GrantUri(userId, uri, false));
8042            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8043                    new GrantUri(userId, uri, true));
8044            if (exactPerm == null && prefixPerm == null) {
8045                throw new SecurityException("No permission grants found for UID " + callingUid
8046                        + " and Uri " + uri.toSafeString());
8047            }
8048
8049            if (exactPerm != null) {
8050                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8051                removeUriPermissionIfNeededLocked(exactPerm);
8052            }
8053            if (prefixPerm != null) {
8054                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8055                removeUriPermissionIfNeededLocked(prefixPerm);
8056            }
8057
8058            if (persistChanged) {
8059                schedulePersistUriGrants();
8060            }
8061        }
8062    }
8063
8064    /**
8065     * Prune any older {@link UriPermission} for the given UID until outstanding
8066     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8067     *
8068     * @return if any mutations occured that require persisting.
8069     */
8070    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8071        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8072        if (perms == null) return false;
8073        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8074
8075        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8076        for (UriPermission perm : perms.values()) {
8077            if (perm.persistedModeFlags != 0) {
8078                persisted.add(perm);
8079            }
8080        }
8081
8082        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8083        if (trimCount <= 0) return false;
8084
8085        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8086        for (int i = 0; i < trimCount; i++) {
8087            final UriPermission perm = persisted.get(i);
8088
8089            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8090                    "Trimming grant created at " + perm.persistedCreateTime);
8091
8092            perm.releasePersistableModes(~0);
8093            removeUriPermissionIfNeededLocked(perm);
8094        }
8095
8096        return true;
8097    }
8098
8099    @Override
8100    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8101            String packageName, boolean incoming) {
8102        enforceNotIsolatedCaller("getPersistedUriPermissions");
8103        Preconditions.checkNotNull(packageName, "packageName");
8104
8105        final int callingUid = Binder.getCallingUid();
8106        final IPackageManager pm = AppGlobals.getPackageManager();
8107        try {
8108            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8109            if (packageUid != callingUid) {
8110                throw new SecurityException(
8111                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8112            }
8113        } catch (RemoteException e) {
8114            throw new SecurityException("Failed to verify package name ownership");
8115        }
8116
8117        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8118        synchronized (this) {
8119            if (incoming) {
8120                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8121                        callingUid);
8122                if (perms == null) {
8123                    Slog.w(TAG, "No permission grants found for " + packageName);
8124                } else {
8125                    for (UriPermission perm : perms.values()) {
8126                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8127                            result.add(perm.buildPersistedPublicApiObject());
8128                        }
8129                    }
8130                }
8131            } else {
8132                final int size = mGrantedUriPermissions.size();
8133                for (int i = 0; i < size; i++) {
8134                    final ArrayMap<GrantUri, UriPermission> perms =
8135                            mGrantedUriPermissions.valueAt(i);
8136                    for (UriPermission perm : perms.values()) {
8137                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8138                            result.add(perm.buildPersistedPublicApiObject());
8139                        }
8140                    }
8141                }
8142            }
8143        }
8144        return new ParceledListSlice<android.content.UriPermission>(result);
8145    }
8146
8147    @Override
8148    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8149        synchronized (this) {
8150            ProcessRecord app =
8151                who != null ? getRecordForAppLocked(who) : null;
8152            if (app == null) return;
8153
8154            Message msg = Message.obtain();
8155            msg.what = WAIT_FOR_DEBUGGER_MSG;
8156            msg.obj = app;
8157            msg.arg1 = waiting ? 1 : 0;
8158            mUiHandler.sendMessage(msg);
8159        }
8160    }
8161
8162    @Override
8163    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8164        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8165        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8166        outInfo.availMem = Process.getFreeMemory();
8167        outInfo.totalMem = Process.getTotalMemory();
8168        outInfo.threshold = homeAppMem;
8169        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8170        outInfo.hiddenAppThreshold = cachedAppMem;
8171        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8172                ProcessList.SERVICE_ADJ);
8173        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8174                ProcessList.VISIBLE_APP_ADJ);
8175        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8176                ProcessList.FOREGROUND_APP_ADJ);
8177    }
8178
8179    // =========================================================
8180    // TASK MANAGEMENT
8181    // =========================================================
8182
8183    @Override
8184    public List<IAppTask> getAppTasks(String callingPackage) {
8185        int callingUid = Binder.getCallingUid();
8186        long ident = Binder.clearCallingIdentity();
8187
8188        synchronized(this) {
8189            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8190            try {
8191                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8192
8193                final int N = mRecentTasks.size();
8194                for (int i = 0; i < N; i++) {
8195                    TaskRecord tr = mRecentTasks.get(i);
8196                    // Skip tasks that do not match the caller.  We don't need to verify
8197                    // callingPackage, because we are also limiting to callingUid and know
8198                    // that will limit to the correct security sandbox.
8199                    if (tr.effectiveUid != callingUid) {
8200                        continue;
8201                    }
8202                    Intent intent = tr.getBaseIntent();
8203                    if (intent == null ||
8204                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8205                        continue;
8206                    }
8207                    ActivityManager.RecentTaskInfo taskInfo =
8208                            createRecentTaskInfoFromTaskRecord(tr);
8209                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8210                    list.add(taskImpl);
8211                }
8212            } finally {
8213                Binder.restoreCallingIdentity(ident);
8214            }
8215            return list;
8216        }
8217    }
8218
8219    @Override
8220    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8221        final int callingUid = Binder.getCallingUid();
8222        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8223
8224        synchronized(this) {
8225            if (DEBUG_ALL) Slog.v(
8226                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8227
8228            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8229                    callingUid);
8230
8231            // TODO: Improve with MRU list from all ActivityStacks.
8232            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8233        }
8234
8235        return list;
8236    }
8237
8238    /**
8239     * Creates a new RecentTaskInfo from a TaskRecord.
8240     */
8241    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8242        // Update the task description to reflect any changes in the task stack
8243        tr.updateTaskDescription();
8244
8245        // Compose the recent task info
8246        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8247        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8248        rti.persistentId = tr.taskId;
8249        rti.baseIntent = new Intent(tr.getBaseIntent());
8250        rti.origActivity = tr.origActivity;
8251        rti.description = tr.lastDescription;
8252        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8253        rti.userId = tr.userId;
8254        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8255        rti.firstActiveTime = tr.firstActiveTime;
8256        rti.lastActiveTime = tr.lastActiveTime;
8257        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8258        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8259        rti.numActivities = 0;
8260
8261        ActivityRecord base = null;
8262        ActivityRecord top = null;
8263        ActivityRecord tmp;
8264
8265        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8266            tmp = tr.mActivities.get(i);
8267            if (tmp.finishing) {
8268                continue;
8269            }
8270            base = tmp;
8271            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8272                top = base;
8273            }
8274            rti.numActivities++;
8275        }
8276
8277        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8278        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8279
8280        return rti;
8281    }
8282
8283    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8284        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8285                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8286        if (!allowed) {
8287            if (checkPermission(android.Manifest.permission.GET_TASKS,
8288                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8289                // Temporary compatibility: some existing apps on the system image may
8290                // still be requesting the old permission and not switched to the new
8291                // one; if so, we'll still allow them full access.  This means we need
8292                // to see if they are holding the old permission and are a system app.
8293                try {
8294                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8295                        allowed = true;
8296                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8297                                + " is using old GET_TASKS but privileged; allowing");
8298                    }
8299                } catch (RemoteException e) {
8300                }
8301            }
8302        }
8303        if (!allowed) {
8304            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8305                    + " does not hold REAL_GET_TASKS; limiting output");
8306        }
8307        return allowed;
8308    }
8309
8310    @Override
8311    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8312        final int callingUid = Binder.getCallingUid();
8313        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8314                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8315
8316        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8317        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8318        synchronized (this) {
8319            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8320                    callingUid);
8321            final boolean detailed = checkCallingPermission(
8322                    android.Manifest.permission.GET_DETAILED_TASKS)
8323                    == PackageManager.PERMISSION_GRANTED;
8324
8325            final int recentsCount = mRecentTasks.size();
8326            ArrayList<ActivityManager.RecentTaskInfo> res =
8327                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8328
8329            final Set<Integer> includedUsers;
8330            if (includeProfiles) {
8331                includedUsers = getProfileIdsLocked(userId);
8332            } else {
8333                includedUsers = new HashSet<>();
8334            }
8335            includedUsers.add(Integer.valueOf(userId));
8336
8337            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8338                TaskRecord tr = mRecentTasks.get(i);
8339                // Only add calling user or related users recent tasks
8340                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8341                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8342                    continue;
8343                }
8344
8345                // Return the entry if desired by the caller.  We always return
8346                // the first entry, because callers always expect this to be the
8347                // foreground app.  We may filter others if the caller has
8348                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8349                // we should exclude the entry.
8350
8351                if (i == 0
8352                        || withExcluded
8353                        || (tr.intent == null)
8354                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8355                                == 0)) {
8356                    if (!allowed) {
8357                        // If the caller doesn't have the GET_TASKS permission, then only
8358                        // allow them to see a small subset of tasks -- their own and home.
8359                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8360                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8361                            continue;
8362                        }
8363                    }
8364                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8365                        if (tr.stack != null && tr.stack.isHomeStack()) {
8366                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8367                                    "Skipping, home stack task: " + tr);
8368                            continue;
8369                        }
8370                    }
8371                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8372                        // Don't include auto remove tasks that are finished or finishing.
8373                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8374                                "Skipping, auto-remove without activity: " + tr);
8375                        continue;
8376                    }
8377                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8378                            && !tr.isAvailable) {
8379                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8380                                "Skipping, unavail real act: " + tr);
8381                        continue;
8382                    }
8383
8384                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8385                    if (!detailed) {
8386                        rti.baseIntent.replaceExtras((Bundle)null);
8387                    }
8388
8389                    res.add(rti);
8390                    maxNum--;
8391                }
8392            }
8393            return res;
8394        }
8395    }
8396
8397    @Override
8398    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8399        synchronized (this) {
8400            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8401                    "getTaskThumbnail()");
8402            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8403            if (tr != null) {
8404                return tr.getTaskThumbnailLocked();
8405            }
8406        }
8407        return null;
8408    }
8409
8410    @Override
8411    public int addAppTask(IBinder activityToken, Intent intent,
8412            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8413        final int callingUid = Binder.getCallingUid();
8414        final long callingIdent = Binder.clearCallingIdentity();
8415
8416        try {
8417            synchronized (this) {
8418                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8419                if (r == null) {
8420                    throw new IllegalArgumentException("Activity does not exist; token="
8421                            + activityToken);
8422                }
8423                ComponentName comp = intent.getComponent();
8424                if (comp == null) {
8425                    throw new IllegalArgumentException("Intent " + intent
8426                            + " must specify explicit component");
8427                }
8428                if (thumbnail.getWidth() != mThumbnailWidth
8429                        || thumbnail.getHeight() != mThumbnailHeight) {
8430                    throw new IllegalArgumentException("Bad thumbnail size: got "
8431                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8432                            + mThumbnailWidth + "x" + mThumbnailHeight);
8433                }
8434                if (intent.getSelector() != null) {
8435                    intent.setSelector(null);
8436                }
8437                if (intent.getSourceBounds() != null) {
8438                    intent.setSourceBounds(null);
8439                }
8440                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8441                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8442                        // The caller has added this as an auto-remove task...  that makes no
8443                        // sense, so turn off auto-remove.
8444                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8445                    }
8446                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8447                    // Must be a new task.
8448                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8449                }
8450                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8451                    mLastAddedTaskActivity = null;
8452                }
8453                ActivityInfo ainfo = mLastAddedTaskActivity;
8454                if (ainfo == null) {
8455                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8456                            comp, 0, UserHandle.getUserId(callingUid));
8457                    if (ainfo.applicationInfo.uid != callingUid) {
8458                        throw new SecurityException(
8459                                "Can't add task for another application: target uid="
8460                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8461                    }
8462                }
8463
8464                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8465                        intent, description);
8466
8467                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8468                if (trimIdx >= 0) {
8469                    // If this would have caused a trim, then we'll abort because that
8470                    // means it would be added at the end of the list but then just removed.
8471                    return INVALID_TASK_ID;
8472                }
8473
8474                final int N = mRecentTasks.size();
8475                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8476                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8477                    tr.removedFromRecents();
8478                }
8479
8480                task.inRecents = true;
8481                mRecentTasks.add(task);
8482                r.task.stack.addTask(task, false, false);
8483
8484                task.setLastThumbnail(thumbnail);
8485                task.freeLastThumbnail();
8486
8487                return task.taskId;
8488            }
8489        } finally {
8490            Binder.restoreCallingIdentity(callingIdent);
8491        }
8492    }
8493
8494    @Override
8495    public Point getAppTaskThumbnailSize() {
8496        synchronized (this) {
8497            return new Point(mThumbnailWidth,  mThumbnailHeight);
8498        }
8499    }
8500
8501    @Override
8502    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8503        synchronized (this) {
8504            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8505            if (r != null) {
8506                r.setTaskDescription(td);
8507                r.task.updateTaskDescription();
8508            }
8509        }
8510    }
8511
8512    @Override
8513    public void setTaskResizeable(int taskId, boolean resizeable) {
8514        synchronized (this) {
8515            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8516            if (task == null) {
8517                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8518                return;
8519            }
8520            if (task.mResizeable != resizeable) {
8521                task.mResizeable = resizeable;
8522                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8523                mStackSupervisor.resumeTopActivitiesLocked();
8524            }
8525        }
8526    }
8527
8528    @Override
8529    public void resizeTask(int taskId, Rect bounds) {
8530        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8531                "resizeTask()");
8532        long ident = Binder.clearCallingIdentity();
8533        try {
8534            synchronized (this) {
8535                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8536                if (task == null) {
8537                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8538                    return;
8539                }
8540                mStackSupervisor.resizeTaskLocked(task, bounds);
8541            }
8542        } finally {
8543            Binder.restoreCallingIdentity(ident);
8544        }
8545    }
8546
8547    @Override
8548    public Bitmap getTaskDescriptionIcon(String filename) {
8549        if (!FileUtils.isValidExtFilename(filename)
8550                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8551            throw new IllegalArgumentException("Bad filename: " + filename);
8552        }
8553        return mTaskPersister.getTaskDescriptionIcon(filename);
8554    }
8555
8556    @Override
8557    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8558            throws RemoteException {
8559        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8560                opts.getCustomInPlaceResId() == 0) {
8561            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8562                    "with valid animation");
8563        }
8564        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8565        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8566                opts.getCustomInPlaceResId());
8567        mWindowManager.executeAppTransition();
8568    }
8569
8570    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8571        mRecentTasks.remove(tr);
8572        tr.removedFromRecents();
8573        ComponentName component = tr.getBaseIntent().getComponent();
8574        if (component == null) {
8575            Slog.w(TAG, "No component for base intent of task: " + tr);
8576            return;
8577        }
8578
8579        // Find any running services associated with this app and stop if needed.
8580        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8581
8582        if (!killProcess) {
8583            return;
8584        }
8585
8586        // Determine if the process(es) for this task should be killed.
8587        final String pkg = component.getPackageName();
8588        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8589        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8590        for (int i = 0; i < pmap.size(); i++) {
8591
8592            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8593            for (int j = 0; j < uids.size(); j++) {
8594                ProcessRecord proc = uids.valueAt(j);
8595                if (proc.userId != tr.userId) {
8596                    // Don't kill process for a different user.
8597                    continue;
8598                }
8599                if (proc == mHomeProcess) {
8600                    // Don't kill the home process along with tasks from the same package.
8601                    continue;
8602                }
8603                if (!proc.pkgList.containsKey(pkg)) {
8604                    // Don't kill process that is not associated with this task.
8605                    continue;
8606                }
8607
8608                for (int k = 0; k < proc.activities.size(); k++) {
8609                    TaskRecord otherTask = proc.activities.get(k).task;
8610                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8611                        // Don't kill process(es) that has an activity in a different task that is
8612                        // also in recents.
8613                        return;
8614                    }
8615                }
8616
8617                if (proc.foregroundServices) {
8618                    // Don't kill process(es) with foreground service.
8619                    return;
8620                }
8621
8622                // Add process to kill list.
8623                procsToKill.add(proc);
8624            }
8625        }
8626
8627        // Kill the running processes.
8628        for (int i = 0; i < procsToKill.size(); i++) {
8629            ProcessRecord pr = procsToKill.get(i);
8630            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8631                    && pr.curReceiver == null) {
8632                pr.kill("remove task", true);
8633            } else {
8634                // We delay killing processes that are not in the background or running a receiver.
8635                pr.waitingToKill = "remove task";
8636            }
8637        }
8638    }
8639
8640    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8641        // Remove all tasks with activities in the specified package from the list of recent tasks
8642        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8643            TaskRecord tr = mRecentTasks.get(i);
8644            if (tr.userId != userId) continue;
8645
8646            ComponentName cn = tr.intent.getComponent();
8647            if (cn != null && cn.getPackageName().equals(packageName)) {
8648                // If the package name matches, remove the task.
8649                removeTaskByIdLocked(tr.taskId, true);
8650            }
8651        }
8652    }
8653
8654    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8655            int userId) {
8656
8657        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8658            TaskRecord tr = mRecentTasks.get(i);
8659            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8660                continue;
8661            }
8662
8663            ComponentName cn = tr.intent.getComponent();
8664            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8665                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8666            if (sameComponent) {
8667                removeTaskByIdLocked(tr.taskId, false);
8668            }
8669        }
8670    }
8671
8672    /**
8673     * Removes the task with the specified task id.
8674     *
8675     * @param taskId Identifier of the task to be removed.
8676     * @param killProcess Kill any process associated with the task if possible.
8677     * @return Returns true if the given task was found and removed.
8678     */
8679    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8680        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8681        if (tr != null) {
8682            tr.removeTaskActivitiesLocked();
8683            cleanUpRemovedTaskLocked(tr, killProcess);
8684            if (tr.isPersistable) {
8685                notifyTaskPersisterLocked(null, true);
8686            }
8687            return true;
8688        }
8689        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8690        return false;
8691    }
8692
8693    @Override
8694    public boolean removeTask(int taskId) {
8695        synchronized (this) {
8696            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8697                    "removeTask()");
8698            long ident = Binder.clearCallingIdentity();
8699            try {
8700                return removeTaskByIdLocked(taskId, true);
8701            } finally {
8702                Binder.restoreCallingIdentity(ident);
8703            }
8704        }
8705    }
8706
8707    /**
8708     * TODO: Add mController hook
8709     */
8710    @Override
8711    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8712        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8713
8714        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8715        synchronized(this) {
8716            moveTaskToFrontLocked(taskId, flags, options);
8717        }
8718    }
8719
8720    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8721        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8722                Binder.getCallingUid(), -1, -1, "Task to front")) {
8723            ActivityOptions.abort(options);
8724            return;
8725        }
8726        final long origId = Binder.clearCallingIdentity();
8727        try {
8728            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8729            if (task == null) {
8730                Slog.d(TAG, "Could not find task for id: "+ taskId);
8731                return;
8732            }
8733            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8734                mStackSupervisor.showLockTaskToast();
8735                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8736                return;
8737            }
8738            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8739            if (prev != null && prev.isRecentsActivity()) {
8740                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8741            }
8742            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8743        } finally {
8744            Binder.restoreCallingIdentity(origId);
8745        }
8746        ActivityOptions.abort(options);
8747    }
8748
8749    /**
8750     * Moves an activity, and all of the other activities within the same task, to the bottom
8751     * of the history stack.  The activity's order within the task is unchanged.
8752     *
8753     * @param token A reference to the activity we wish to move
8754     * @param nonRoot If false then this only works if the activity is the root
8755     *                of a task; if true it will work for any activity in a task.
8756     * @return Returns true if the move completed, false if not.
8757     */
8758    @Override
8759    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8760        enforceNotIsolatedCaller("moveActivityTaskToBack");
8761        synchronized(this) {
8762            final long origId = Binder.clearCallingIdentity();
8763            try {
8764                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8765                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8766                if (task != null) {
8767                    if (mStackSupervisor.isLockedTask(task)) {
8768                        mStackSupervisor.showLockTaskToast();
8769                        return false;
8770                    }
8771                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8772                }
8773            } finally {
8774                Binder.restoreCallingIdentity(origId);
8775            }
8776        }
8777        return false;
8778    }
8779
8780    @Override
8781    public void moveTaskBackwards(int task) {
8782        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8783                "moveTaskBackwards()");
8784
8785        synchronized(this) {
8786            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8787                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8788                return;
8789            }
8790            final long origId = Binder.clearCallingIdentity();
8791            moveTaskBackwardsLocked(task);
8792            Binder.restoreCallingIdentity(origId);
8793        }
8794    }
8795
8796    private final void moveTaskBackwardsLocked(int task) {
8797        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8798    }
8799
8800    @Override
8801    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8802            IActivityContainerCallback callback) throws RemoteException {
8803        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8804                "createActivityContainer()");
8805        synchronized (this) {
8806            if (parentActivityToken == null) {
8807                throw new IllegalArgumentException("parent token must not be null");
8808            }
8809            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8810            if (r == null) {
8811                return null;
8812            }
8813            if (callback == null) {
8814                throw new IllegalArgumentException("callback must not be null");
8815            }
8816            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8817        }
8818    }
8819
8820    @Override
8821    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8822        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8823                "deleteActivityContainer()");
8824        synchronized (this) {
8825            mStackSupervisor.deleteActivityContainer(container);
8826        }
8827    }
8828
8829    @Override
8830    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8831        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8832                "createStackOnDisplay()");
8833        synchronized (this) {
8834            final int stackId = mStackSupervisor.getNextStackId();
8835            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8836            if (stack == null) {
8837                return null;
8838            }
8839            return stack.mActivityContainer;
8840        }
8841    }
8842
8843    @Override
8844    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8845        synchronized (this) {
8846            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8847            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8848                return stack.mActivityContainer.getDisplayId();
8849            }
8850            return Display.DEFAULT_DISPLAY;
8851        }
8852    }
8853
8854    @Override
8855    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8856        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8857                "moveTaskToStack()");
8858        if (stackId == HOME_STACK_ID) {
8859            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8860                    new RuntimeException("here").fillInStackTrace());
8861        }
8862        synchronized (this) {
8863            long ident = Binder.clearCallingIdentity();
8864            try {
8865                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8866                        + " to stackId=" + stackId + " toTop=" + toTop);
8867                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8868            } finally {
8869                Binder.restoreCallingIdentity(ident);
8870            }
8871        }
8872    }
8873
8874    @Override
8875    public void resizeStack(int stackId, Rect bounds) {
8876        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8877                "resizeStack()");
8878        long ident = Binder.clearCallingIdentity();
8879        try {
8880            synchronized (this) {
8881                mStackSupervisor.resizeStackLocked(stackId, bounds);
8882            }
8883        } finally {
8884            Binder.restoreCallingIdentity(ident);
8885        }
8886    }
8887
8888    @Override
8889    public List<StackInfo> getAllStackInfos() {
8890        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8891                "getAllStackInfos()");
8892        long ident = Binder.clearCallingIdentity();
8893        try {
8894            synchronized (this) {
8895                return mStackSupervisor.getAllStackInfosLocked();
8896            }
8897        } finally {
8898            Binder.restoreCallingIdentity(ident);
8899        }
8900    }
8901
8902    @Override
8903    public StackInfo getStackInfo(int stackId) {
8904        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8905                "getStackInfo()");
8906        long ident = Binder.clearCallingIdentity();
8907        try {
8908            synchronized (this) {
8909                return mStackSupervisor.getStackInfoLocked(stackId);
8910            }
8911        } finally {
8912            Binder.restoreCallingIdentity(ident);
8913        }
8914    }
8915
8916    @Override
8917    public boolean isInHomeStack(int taskId) {
8918        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8919                "getStackInfo()");
8920        long ident = Binder.clearCallingIdentity();
8921        try {
8922            synchronized (this) {
8923                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8924                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8925            }
8926        } finally {
8927            Binder.restoreCallingIdentity(ident);
8928        }
8929    }
8930
8931    @Override
8932    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8933        synchronized(this) {
8934            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8935        }
8936    }
8937
8938    @Override
8939    public void updateDeviceOwner(String packageName) {
8940        final int callingUid = Binder.getCallingUid();
8941        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8942            throw new SecurityException("updateDeviceOwner called from non-system process");
8943        }
8944        synchronized (this) {
8945            mDeviceOwnerName = packageName;
8946        }
8947    }
8948
8949    @Override
8950    public void updateLockTaskPackages(int userId, String[] packages) {
8951        final int callingUid = Binder.getCallingUid();
8952        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8953            throw new SecurityException("updateLockTaskPackage called from non-system process");
8954        }
8955        synchronized (this) {
8956            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8957                    Arrays.toString(packages));
8958            mLockTaskPackages.put(userId, packages);
8959            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8960        }
8961    }
8962
8963
8964    void startLockTaskModeLocked(TaskRecord task) {
8965        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8966        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8967            return;
8968        }
8969
8970        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8971        // is initiated by system after the pinning request was shown and locked mode is initiated
8972        // by an authorized app directly
8973        final int callingUid = Binder.getCallingUid();
8974        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8975        long ident = Binder.clearCallingIdentity();
8976        try {
8977            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8978            if (!isSystemInitiated) {
8979                task.mLockTaskUid = callingUid;
8980                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8981                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8982                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8983                    StatusBarManagerInternal statusBarManager =
8984                            LocalServices.getService(StatusBarManagerInternal.class);
8985                    if (statusBarManager != null) {
8986                        statusBarManager.showScreenPinningRequest();
8987                    }
8988                    return;
8989                }
8990
8991                if (stack == null || task != stack.topTask()) {
8992                    throw new IllegalArgumentException("Invalid task, not in foreground");
8993                }
8994            }
8995            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8996                    "Locking fully");
8997            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8998                    ActivityManager.LOCK_TASK_MODE_PINNED :
8999                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9000                    "startLockTask", true);
9001        } finally {
9002            Binder.restoreCallingIdentity(ident);
9003        }
9004    }
9005
9006    @Override
9007    public void startLockTaskMode(int taskId) {
9008        synchronized (this) {
9009            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9010            if (task != null) {
9011                startLockTaskModeLocked(task);
9012            }
9013        }
9014    }
9015
9016    @Override
9017    public void startLockTaskMode(IBinder token) {
9018        synchronized (this) {
9019            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9020            if (r == null) {
9021                return;
9022            }
9023            final TaskRecord task = r.task;
9024            if (task != null) {
9025                startLockTaskModeLocked(task);
9026            }
9027        }
9028    }
9029
9030    @Override
9031    public void startLockTaskModeOnCurrent() throws RemoteException {
9032        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9033                "startLockTaskModeOnCurrent");
9034        long ident = Binder.clearCallingIdentity();
9035        try {
9036            synchronized (this) {
9037                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9038                if (r != null) {
9039                    startLockTaskModeLocked(r.task);
9040                }
9041            }
9042        } finally {
9043            Binder.restoreCallingIdentity(ident);
9044        }
9045    }
9046
9047    @Override
9048    public void stopLockTaskMode() {
9049        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9050        if (lockTask == null) {
9051            // Our work here is done.
9052            return;
9053        }
9054
9055        final int callingUid = Binder.getCallingUid();
9056        final int lockTaskUid = lockTask.mLockTaskUid;
9057        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9058        // It is possible lockTaskMode was started by the system process because
9059        // android:lockTaskMode is set to a locking value in the application manifest instead of
9060        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9061        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9062        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9063                callingUid != lockTaskUid
9064                && (lockTaskUid != 0
9065                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9066            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9067                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9068        }
9069
9070        long ident = Binder.clearCallingIdentity();
9071        try {
9072            Log.d(TAG, "stopLockTaskMode");
9073            // Stop lock task
9074            synchronized (this) {
9075                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9076                        "stopLockTask", true);
9077            }
9078        } finally {
9079            Binder.restoreCallingIdentity(ident);
9080        }
9081    }
9082
9083    @Override
9084    public void stopLockTaskModeOnCurrent() throws RemoteException {
9085        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9086                "stopLockTaskModeOnCurrent");
9087        long ident = Binder.clearCallingIdentity();
9088        try {
9089            stopLockTaskMode();
9090        } finally {
9091            Binder.restoreCallingIdentity(ident);
9092        }
9093    }
9094
9095    @Override
9096    public boolean isInLockTaskMode() {
9097        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9098    }
9099
9100    @Override
9101    public int getLockTaskModeState() {
9102        synchronized (this) {
9103            return mStackSupervisor.getLockTaskModeState();
9104        }
9105    }
9106
9107    @Override
9108    public void showLockTaskEscapeMessage(IBinder token) {
9109        synchronized (this) {
9110            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9111            if (r == null) {
9112                return;
9113            }
9114            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9115        }
9116    }
9117
9118    // =========================================================
9119    // CONTENT PROVIDERS
9120    // =========================================================
9121
9122    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9123        List<ProviderInfo> providers = null;
9124        try {
9125            providers = AppGlobals.getPackageManager().
9126                queryContentProviders(app.processName, app.uid,
9127                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9128        } catch (RemoteException ex) {
9129        }
9130        if (DEBUG_MU) Slog.v(TAG_MU,
9131                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9132        int userId = app.userId;
9133        if (providers != null) {
9134            int N = providers.size();
9135            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9136            for (int i=0; i<N; i++) {
9137                ProviderInfo cpi =
9138                    (ProviderInfo)providers.get(i);
9139                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9140                        cpi.name, cpi.flags);
9141                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9142                    // This is a singleton provider, but a user besides the
9143                    // default user is asking to initialize a process it runs
9144                    // in...  well, no, it doesn't actually run in this process,
9145                    // it runs in the process of the default user.  Get rid of it.
9146                    providers.remove(i);
9147                    N--;
9148                    i--;
9149                    continue;
9150                }
9151
9152                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9153                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9154                if (cpr == null) {
9155                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9156                    mProviderMap.putProviderByClass(comp, cpr);
9157                }
9158                if (DEBUG_MU) Slog.v(TAG_MU,
9159                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9160                app.pubProviders.put(cpi.name, cpr);
9161                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9162                    // Don't add this if it is a platform component that is marked
9163                    // to run in multiple processes, because this is actually
9164                    // part of the framework so doesn't make sense to track as a
9165                    // separate apk in the process.
9166                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9167                            mProcessStats);
9168                }
9169                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9170            }
9171        }
9172        return providers;
9173    }
9174
9175    /**
9176     * Check if {@link ProcessRecord} has a possible chance at accessing the
9177     * given {@link ProviderInfo}. Final permission checking is always done
9178     * in {@link ContentProvider}.
9179     */
9180    private final String checkContentProviderPermissionLocked(
9181            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9182        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9183        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9184        boolean checkedGrants = false;
9185        if (checkUser) {
9186            // Looking for cross-user grants before enforcing the typical cross-users permissions
9187            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9188            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9189                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9190                    return null;
9191                }
9192                checkedGrants = true;
9193            }
9194            userId = handleIncomingUser(callingPid, callingUid, userId,
9195                    false, ALLOW_NON_FULL,
9196                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9197            if (userId != tmpTargetUserId) {
9198                // When we actually went to determine the final targer user ID, this ended
9199                // up different than our initial check for the authority.  This is because
9200                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9201                // SELF.  So we need to re-check the grants again.
9202                checkedGrants = false;
9203            }
9204        }
9205        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9206                cpi.applicationInfo.uid, cpi.exported)
9207                == PackageManager.PERMISSION_GRANTED) {
9208            return null;
9209        }
9210        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9211                cpi.applicationInfo.uid, cpi.exported)
9212                == PackageManager.PERMISSION_GRANTED) {
9213            return null;
9214        }
9215
9216        PathPermission[] pps = cpi.pathPermissions;
9217        if (pps != null) {
9218            int i = pps.length;
9219            while (i > 0) {
9220                i--;
9221                PathPermission pp = pps[i];
9222                String pprperm = pp.getReadPermission();
9223                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9224                        cpi.applicationInfo.uid, cpi.exported)
9225                        == PackageManager.PERMISSION_GRANTED) {
9226                    return null;
9227                }
9228                String ppwperm = pp.getWritePermission();
9229                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9230                        cpi.applicationInfo.uid, cpi.exported)
9231                        == PackageManager.PERMISSION_GRANTED) {
9232                    return null;
9233                }
9234            }
9235        }
9236        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9237            return null;
9238        }
9239
9240        String msg;
9241        if (!cpi.exported) {
9242            msg = "Permission Denial: opening provider " + cpi.name
9243                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9244                    + ", uid=" + callingUid + ") that is not exported from uid "
9245                    + cpi.applicationInfo.uid;
9246        } else {
9247            msg = "Permission Denial: opening provider " + cpi.name
9248                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9249                    + ", uid=" + callingUid + ") requires "
9250                    + cpi.readPermission + " or " + cpi.writePermission;
9251        }
9252        Slog.w(TAG, msg);
9253        return msg;
9254    }
9255
9256    /**
9257     * Returns if the ContentProvider has granted a uri to callingUid
9258     */
9259    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9260        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9261        if (perms != null) {
9262            for (int i=perms.size()-1; i>=0; i--) {
9263                GrantUri grantUri = perms.keyAt(i);
9264                if (grantUri.sourceUserId == userId || !checkUser) {
9265                    if (matchesProvider(grantUri.uri, cpi)) {
9266                        return true;
9267                    }
9268                }
9269            }
9270        }
9271        return false;
9272    }
9273
9274    /**
9275     * Returns true if the uri authority is one of the authorities specified in the provider.
9276     */
9277    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9278        String uriAuth = uri.getAuthority();
9279        String cpiAuth = cpi.authority;
9280        if (cpiAuth.indexOf(';') == -1) {
9281            return cpiAuth.equals(uriAuth);
9282        }
9283        String[] cpiAuths = cpiAuth.split(";");
9284        int length = cpiAuths.length;
9285        for (int i = 0; i < length; i++) {
9286            if (cpiAuths[i].equals(uriAuth)) return true;
9287        }
9288        return false;
9289    }
9290
9291    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9292            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9293        if (r != null) {
9294            for (int i=0; i<r.conProviders.size(); i++) {
9295                ContentProviderConnection conn = r.conProviders.get(i);
9296                if (conn.provider == cpr) {
9297                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9298                            "Adding provider requested by "
9299                            + r.processName + " from process "
9300                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9301                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9302                    if (stable) {
9303                        conn.stableCount++;
9304                        conn.numStableIncs++;
9305                    } else {
9306                        conn.unstableCount++;
9307                        conn.numUnstableIncs++;
9308                    }
9309                    return conn;
9310                }
9311            }
9312            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9313            if (stable) {
9314                conn.stableCount = 1;
9315                conn.numStableIncs = 1;
9316            } else {
9317                conn.unstableCount = 1;
9318                conn.numUnstableIncs = 1;
9319            }
9320            cpr.connections.add(conn);
9321            r.conProviders.add(conn);
9322            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9323            return conn;
9324        }
9325        cpr.addExternalProcessHandleLocked(externalProcessToken);
9326        return null;
9327    }
9328
9329    boolean decProviderCountLocked(ContentProviderConnection conn,
9330            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9331        if (conn != null) {
9332            cpr = conn.provider;
9333            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9334                    "Removing provider requested by "
9335                    + conn.client.processName + " from process "
9336                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9337                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9338            if (stable) {
9339                conn.stableCount--;
9340            } else {
9341                conn.unstableCount--;
9342            }
9343            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9344                cpr.connections.remove(conn);
9345                conn.client.conProviders.remove(conn);
9346                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9347                return true;
9348            }
9349            return false;
9350        }
9351        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9352        return false;
9353    }
9354
9355    private void checkTime(long startTime, String where) {
9356        long now = SystemClock.elapsedRealtime();
9357        if ((now-startTime) > 1000) {
9358            // If we are taking more than a second, log about it.
9359            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9360        }
9361    }
9362
9363    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9364            String name, IBinder token, boolean stable, int userId) {
9365        ContentProviderRecord cpr;
9366        ContentProviderConnection conn = null;
9367        ProviderInfo cpi = null;
9368
9369        synchronized(this) {
9370            long startTime = SystemClock.elapsedRealtime();
9371
9372            ProcessRecord r = null;
9373            if (caller != null) {
9374                r = getRecordForAppLocked(caller);
9375                if (r == null) {
9376                    throw new SecurityException(
9377                            "Unable to find app for caller " + caller
9378                          + " (pid=" + Binder.getCallingPid()
9379                          + ") when getting content provider " + name);
9380                }
9381            }
9382
9383            boolean checkCrossUser = true;
9384
9385            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9386
9387            // First check if this content provider has been published...
9388            cpr = mProviderMap.getProviderByName(name, userId);
9389            // If that didn't work, check if it exists for user 0 and then
9390            // verify that it's a singleton provider before using it.
9391            if (cpr == null && userId != UserHandle.USER_OWNER) {
9392                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9393                if (cpr != null) {
9394                    cpi = cpr.info;
9395                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9396                            cpi.name, cpi.flags)
9397                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9398                        userId = UserHandle.USER_OWNER;
9399                        checkCrossUser = false;
9400                    } else {
9401                        cpr = null;
9402                        cpi = null;
9403                    }
9404                }
9405            }
9406
9407            boolean providerRunning = cpr != null;
9408            if (providerRunning) {
9409                cpi = cpr.info;
9410                String msg;
9411                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9412                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9413                        != null) {
9414                    throw new SecurityException(msg);
9415                }
9416                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9417
9418                if (r != null && cpr.canRunHere(r)) {
9419                    // This provider has been published or is in the process
9420                    // of being published...  but it is also allowed to run
9421                    // in the caller's process, so don't make a connection
9422                    // and just let the caller instantiate its own instance.
9423                    ContentProviderHolder holder = cpr.newHolder(null);
9424                    // don't give caller the provider object, it needs
9425                    // to make its own.
9426                    holder.provider = null;
9427                    return holder;
9428                }
9429
9430                final long origId = Binder.clearCallingIdentity();
9431
9432                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9433
9434                // In this case the provider instance already exists, so we can
9435                // return it right away.
9436                conn = incProviderCountLocked(r, cpr, token, stable);
9437                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9438                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9439                        // If this is a perceptible app accessing the provider,
9440                        // make sure to count it as being accessed and thus
9441                        // back up on the LRU list.  This is good because
9442                        // content providers are often expensive to start.
9443                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9444                        updateLruProcessLocked(cpr.proc, false, null);
9445                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9446                    }
9447                }
9448
9449                if (cpr.proc != null) {
9450                    if (false) {
9451                        if (cpr.name.flattenToShortString().equals(
9452                                "com.android.providers.calendar/.CalendarProvider2")) {
9453                            Slog.v(TAG, "****************** KILLING "
9454                                + cpr.name.flattenToShortString());
9455                            Process.killProcess(cpr.proc.pid);
9456                        }
9457                    }
9458                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9459                    boolean success = updateOomAdjLocked(cpr.proc);
9460                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9461                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9462                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9463                    // NOTE: there is still a race here where a signal could be
9464                    // pending on the process even though we managed to update its
9465                    // adj level.  Not sure what to do about this, but at least
9466                    // the race is now smaller.
9467                    if (!success) {
9468                        // Uh oh...  it looks like the provider's process
9469                        // has been killed on us.  We need to wait for a new
9470                        // process to be started, and make sure its death
9471                        // doesn't kill our process.
9472                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9473                                + " is crashing; detaching " + r);
9474                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9475                        checkTime(startTime, "getContentProviderImpl: before appDied");
9476                        appDiedLocked(cpr.proc);
9477                        checkTime(startTime, "getContentProviderImpl: after appDied");
9478                        if (!lastRef) {
9479                            // This wasn't the last ref our process had on
9480                            // the provider...  we have now been killed, bail.
9481                            return null;
9482                        }
9483                        providerRunning = false;
9484                        conn = null;
9485                    }
9486                }
9487
9488                Binder.restoreCallingIdentity(origId);
9489            }
9490
9491            boolean singleton;
9492            if (!providerRunning) {
9493                try {
9494                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9495                    cpi = AppGlobals.getPackageManager().
9496                        resolveContentProvider(name,
9497                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9498                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9499                } catch (RemoteException ex) {
9500                }
9501                if (cpi == null) {
9502                    return null;
9503                }
9504                // If the provider is a singleton AND
9505                // (it's a call within the same user || the provider is a
9506                // privileged app)
9507                // Then allow connecting to the singleton provider
9508                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9509                        cpi.name, cpi.flags)
9510                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9511                if (singleton) {
9512                    userId = UserHandle.USER_OWNER;
9513                }
9514                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9515                checkTime(startTime, "getContentProviderImpl: got app info for user");
9516
9517                String msg;
9518                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9519                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9520                        != null) {
9521                    throw new SecurityException(msg);
9522                }
9523                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9524
9525                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9526                        && !cpi.processName.equals("system")) {
9527                    // If this content provider does not run in the system
9528                    // process, and the system is not yet ready to run other
9529                    // processes, then fail fast instead of hanging.
9530                    throw new IllegalArgumentException(
9531                            "Attempt to launch content provider before system ready");
9532                }
9533
9534                // Make sure that the user who owns this provider is running.  If not,
9535                // we don't want to allow it to run.
9536                if (!isUserRunningLocked(userId, false)) {
9537                    Slog.w(TAG, "Unable to launch app "
9538                            + cpi.applicationInfo.packageName + "/"
9539                            + cpi.applicationInfo.uid + " for provider "
9540                            + name + ": user " + userId + " is stopped");
9541                    return null;
9542                }
9543
9544                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9545                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9546                cpr = mProviderMap.getProviderByClass(comp, userId);
9547                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9548                final boolean firstClass = cpr == null;
9549                if (firstClass) {
9550                    final long ident = Binder.clearCallingIdentity();
9551                    try {
9552                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9553                        ApplicationInfo ai =
9554                            AppGlobals.getPackageManager().
9555                                getApplicationInfo(
9556                                        cpi.applicationInfo.packageName,
9557                                        STOCK_PM_FLAGS, userId);
9558                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9559                        if (ai == null) {
9560                            Slog.w(TAG, "No package info for content provider "
9561                                    + cpi.name);
9562                            return null;
9563                        }
9564                        ai = getAppInfoForUser(ai, userId);
9565                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9566                    } catch (RemoteException ex) {
9567                        // pm is in same process, this will never happen.
9568                    } finally {
9569                        Binder.restoreCallingIdentity(ident);
9570                    }
9571                }
9572
9573                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9574
9575                if (r != null && cpr.canRunHere(r)) {
9576                    // If this is a multiprocess provider, then just return its
9577                    // info and allow the caller to instantiate it.  Only do
9578                    // this if the provider is the same user as the caller's
9579                    // process, or can run as root (so can be in any process).
9580                    return cpr.newHolder(null);
9581                }
9582
9583                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9584                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9585                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9586
9587                // This is single process, and our app is now connecting to it.
9588                // See if we are already in the process of launching this
9589                // provider.
9590                final int N = mLaunchingProviders.size();
9591                int i;
9592                for (i = 0; i < N; i++) {
9593                    if (mLaunchingProviders.get(i) == cpr) {
9594                        break;
9595                    }
9596                }
9597
9598                // If the provider is not already being launched, then get it
9599                // started.
9600                if (i >= N) {
9601                    final long origId = Binder.clearCallingIdentity();
9602
9603                    try {
9604                        // Content provider is now in use, its package can't be stopped.
9605                        try {
9606                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9607                            AppGlobals.getPackageManager().setPackageStoppedState(
9608                                    cpr.appInfo.packageName, false, userId);
9609                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9610                        } catch (RemoteException e) {
9611                        } catch (IllegalArgumentException e) {
9612                            Slog.w(TAG, "Failed trying to unstop package "
9613                                    + cpr.appInfo.packageName + ": " + e);
9614                        }
9615
9616                        // Use existing process if already started
9617                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9618                        ProcessRecord proc = getProcessRecordLocked(
9619                                cpi.processName, cpr.appInfo.uid, false);
9620                        if (proc != null && proc.thread != null) {
9621                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9622                                    "Installing in existing process " + proc);
9623                            if (!proc.pubProviders.containsKey(cpi.name)) {
9624                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9625                                proc.pubProviders.put(cpi.name, cpr);
9626                                try {
9627                                    proc.thread.scheduleInstallProvider(cpi);
9628                                } catch (RemoteException e) {
9629                                }
9630                            }
9631                        } else {
9632                            checkTime(startTime, "getContentProviderImpl: before start process");
9633                            proc = startProcessLocked(cpi.processName,
9634                                    cpr.appInfo, false, 0, "content provider",
9635                                    new ComponentName(cpi.applicationInfo.packageName,
9636                                            cpi.name), false, false, false);
9637                            checkTime(startTime, "getContentProviderImpl: after start process");
9638                            if (proc == null) {
9639                                Slog.w(TAG, "Unable to launch app "
9640                                        + cpi.applicationInfo.packageName + "/"
9641                                        + cpi.applicationInfo.uid + " for provider "
9642                                        + name + ": process is bad");
9643                                return null;
9644                            }
9645                        }
9646                        cpr.launchingApp = proc;
9647                        mLaunchingProviders.add(cpr);
9648                    } finally {
9649                        Binder.restoreCallingIdentity(origId);
9650                    }
9651                }
9652
9653                checkTime(startTime, "getContentProviderImpl: updating data structures");
9654
9655                // Make sure the provider is published (the same provider class
9656                // may be published under multiple names).
9657                if (firstClass) {
9658                    mProviderMap.putProviderByClass(comp, cpr);
9659                }
9660
9661                mProviderMap.putProviderByName(name, cpr);
9662                conn = incProviderCountLocked(r, cpr, token, stable);
9663                if (conn != null) {
9664                    conn.waiting = true;
9665                }
9666            }
9667            checkTime(startTime, "getContentProviderImpl: done!");
9668        }
9669
9670        // Wait for the provider to be published...
9671        synchronized (cpr) {
9672            while (cpr.provider == null) {
9673                if (cpr.launchingApp == null) {
9674                    Slog.w(TAG, "Unable to launch app "
9675                            + cpi.applicationInfo.packageName + "/"
9676                            + cpi.applicationInfo.uid + " for provider "
9677                            + name + ": launching app became null");
9678                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9679                            UserHandle.getUserId(cpi.applicationInfo.uid),
9680                            cpi.applicationInfo.packageName,
9681                            cpi.applicationInfo.uid, name);
9682                    return null;
9683                }
9684                try {
9685                    if (DEBUG_MU) Slog.v(TAG_MU,
9686                            "Waiting to start provider " + cpr
9687                            + " launchingApp=" + cpr.launchingApp);
9688                    if (conn != null) {
9689                        conn.waiting = true;
9690                    }
9691                    cpr.wait();
9692                } catch (InterruptedException ex) {
9693                } finally {
9694                    if (conn != null) {
9695                        conn.waiting = false;
9696                    }
9697                }
9698            }
9699        }
9700        return cpr != null ? cpr.newHolder(conn) : null;
9701    }
9702
9703    @Override
9704    public final ContentProviderHolder getContentProvider(
9705            IApplicationThread caller, String name, int userId, boolean stable) {
9706        enforceNotIsolatedCaller("getContentProvider");
9707        if (caller == null) {
9708            String msg = "null IApplicationThread when getting content provider "
9709                    + name;
9710            Slog.w(TAG, msg);
9711            throw new SecurityException(msg);
9712        }
9713        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9714        // with cross-user grant.
9715        return getContentProviderImpl(caller, name, null, stable, userId);
9716    }
9717
9718    public ContentProviderHolder getContentProviderExternal(
9719            String name, int userId, IBinder token) {
9720        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9721            "Do not have permission in call getContentProviderExternal()");
9722        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9723                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9724        return getContentProviderExternalUnchecked(name, token, userId);
9725    }
9726
9727    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9728            IBinder token, int userId) {
9729        return getContentProviderImpl(null, name, token, true, userId);
9730    }
9731
9732    /**
9733     * Drop a content provider from a ProcessRecord's bookkeeping
9734     */
9735    public void removeContentProvider(IBinder connection, boolean stable) {
9736        enforceNotIsolatedCaller("removeContentProvider");
9737        long ident = Binder.clearCallingIdentity();
9738        try {
9739            synchronized (this) {
9740                ContentProviderConnection conn;
9741                try {
9742                    conn = (ContentProviderConnection)connection;
9743                } catch (ClassCastException e) {
9744                    String msg ="removeContentProvider: " + connection
9745                            + " not a ContentProviderConnection";
9746                    Slog.w(TAG, msg);
9747                    throw new IllegalArgumentException(msg);
9748                }
9749                if (conn == null) {
9750                    throw new NullPointerException("connection is null");
9751                }
9752                if (decProviderCountLocked(conn, null, null, stable)) {
9753                    updateOomAdjLocked();
9754                }
9755            }
9756        } finally {
9757            Binder.restoreCallingIdentity(ident);
9758        }
9759    }
9760
9761    public void removeContentProviderExternal(String name, IBinder token) {
9762        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9763            "Do not have permission in call removeContentProviderExternal()");
9764        int userId = UserHandle.getCallingUserId();
9765        long ident = Binder.clearCallingIdentity();
9766        try {
9767            removeContentProviderExternalUnchecked(name, token, userId);
9768        } finally {
9769            Binder.restoreCallingIdentity(ident);
9770        }
9771    }
9772
9773    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9774        synchronized (this) {
9775            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9776            if(cpr == null) {
9777                //remove from mProvidersByClass
9778                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9779                return;
9780            }
9781
9782            //update content provider record entry info
9783            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9784            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9785            if (localCpr.hasExternalProcessHandles()) {
9786                if (localCpr.removeExternalProcessHandleLocked(token)) {
9787                    updateOomAdjLocked();
9788                } else {
9789                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9790                            + " with no external reference for token: "
9791                            + token + ".");
9792                }
9793            } else {
9794                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9795                        + " with no external references.");
9796            }
9797        }
9798    }
9799
9800    public final void publishContentProviders(IApplicationThread caller,
9801            List<ContentProviderHolder> providers) {
9802        if (providers == null) {
9803            return;
9804        }
9805
9806        enforceNotIsolatedCaller("publishContentProviders");
9807        synchronized (this) {
9808            final ProcessRecord r = getRecordForAppLocked(caller);
9809            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9810            if (r == null) {
9811                throw new SecurityException(
9812                        "Unable to find app for caller " + caller
9813                      + " (pid=" + Binder.getCallingPid()
9814                      + ") when publishing content providers");
9815            }
9816
9817            final long origId = Binder.clearCallingIdentity();
9818
9819            final int N = providers.size();
9820            for (int i=0; i<N; i++) {
9821                ContentProviderHolder src = providers.get(i);
9822                if (src == null || src.info == null || src.provider == null) {
9823                    continue;
9824                }
9825                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9826                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9827                if (dst != null) {
9828                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9829                    mProviderMap.putProviderByClass(comp, dst);
9830                    String names[] = dst.info.authority.split(";");
9831                    for (int j = 0; j < names.length; j++) {
9832                        mProviderMap.putProviderByName(names[j], dst);
9833                    }
9834
9835                    int NL = mLaunchingProviders.size();
9836                    int j;
9837                    for (j=0; j<NL; j++) {
9838                        if (mLaunchingProviders.get(j) == dst) {
9839                            mLaunchingProviders.remove(j);
9840                            j--;
9841                            NL--;
9842                        }
9843                    }
9844                    synchronized (dst) {
9845                        dst.provider = src.provider;
9846                        dst.proc = r;
9847                        dst.notifyAll();
9848                    }
9849                    updateOomAdjLocked(r);
9850                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9851                            src.info.authority);
9852                }
9853            }
9854
9855            Binder.restoreCallingIdentity(origId);
9856        }
9857    }
9858
9859    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9860        ContentProviderConnection conn;
9861        try {
9862            conn = (ContentProviderConnection)connection;
9863        } catch (ClassCastException e) {
9864            String msg ="refContentProvider: " + connection
9865                    + " not a ContentProviderConnection";
9866            Slog.w(TAG, msg);
9867            throw new IllegalArgumentException(msg);
9868        }
9869        if (conn == null) {
9870            throw new NullPointerException("connection is null");
9871        }
9872
9873        synchronized (this) {
9874            if (stable > 0) {
9875                conn.numStableIncs += stable;
9876            }
9877            stable = conn.stableCount + stable;
9878            if (stable < 0) {
9879                throw new IllegalStateException("stableCount < 0: " + stable);
9880            }
9881
9882            if (unstable > 0) {
9883                conn.numUnstableIncs += unstable;
9884            }
9885            unstable = conn.unstableCount + unstable;
9886            if (unstable < 0) {
9887                throw new IllegalStateException("unstableCount < 0: " + unstable);
9888            }
9889
9890            if ((stable+unstable) <= 0) {
9891                throw new IllegalStateException("ref counts can't go to zero here: stable="
9892                        + stable + " unstable=" + unstable);
9893            }
9894            conn.stableCount = stable;
9895            conn.unstableCount = unstable;
9896            return !conn.dead;
9897        }
9898    }
9899
9900    public void unstableProviderDied(IBinder connection) {
9901        ContentProviderConnection conn;
9902        try {
9903            conn = (ContentProviderConnection)connection;
9904        } catch (ClassCastException e) {
9905            String msg ="refContentProvider: " + connection
9906                    + " not a ContentProviderConnection";
9907            Slog.w(TAG, msg);
9908            throw new IllegalArgumentException(msg);
9909        }
9910        if (conn == null) {
9911            throw new NullPointerException("connection is null");
9912        }
9913
9914        // Safely retrieve the content provider associated with the connection.
9915        IContentProvider provider;
9916        synchronized (this) {
9917            provider = conn.provider.provider;
9918        }
9919
9920        if (provider == null) {
9921            // Um, yeah, we're way ahead of you.
9922            return;
9923        }
9924
9925        // Make sure the caller is being honest with us.
9926        if (provider.asBinder().pingBinder()) {
9927            // Er, no, still looks good to us.
9928            synchronized (this) {
9929                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9930                        + " says " + conn + " died, but we don't agree");
9931                return;
9932            }
9933        }
9934
9935        // Well look at that!  It's dead!
9936        synchronized (this) {
9937            if (conn.provider.provider != provider) {
9938                // But something changed...  good enough.
9939                return;
9940            }
9941
9942            ProcessRecord proc = conn.provider.proc;
9943            if (proc == null || proc.thread == null) {
9944                // Seems like the process is already cleaned up.
9945                return;
9946            }
9947
9948            // As far as we're concerned, this is just like receiving a
9949            // death notification...  just a bit prematurely.
9950            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9951                    + ") early provider death");
9952            final long ident = Binder.clearCallingIdentity();
9953            try {
9954                appDiedLocked(proc);
9955            } finally {
9956                Binder.restoreCallingIdentity(ident);
9957            }
9958        }
9959    }
9960
9961    @Override
9962    public void appNotRespondingViaProvider(IBinder connection) {
9963        enforceCallingPermission(
9964                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9965
9966        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9967        if (conn == null) {
9968            Slog.w(TAG, "ContentProviderConnection is null");
9969            return;
9970        }
9971
9972        final ProcessRecord host = conn.provider.proc;
9973        if (host == null) {
9974            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9975            return;
9976        }
9977
9978        final long token = Binder.clearCallingIdentity();
9979        try {
9980            appNotResponding(host, null, null, false, "ContentProvider not responding");
9981        } finally {
9982            Binder.restoreCallingIdentity(token);
9983        }
9984    }
9985
9986    public final void installSystemProviders() {
9987        List<ProviderInfo> providers;
9988        synchronized (this) {
9989            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9990            providers = generateApplicationProvidersLocked(app);
9991            if (providers != null) {
9992                for (int i=providers.size()-1; i>=0; i--) {
9993                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9994                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9995                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9996                                + ": not system .apk");
9997                        providers.remove(i);
9998                    }
9999                }
10000            }
10001        }
10002        if (providers != null) {
10003            mSystemThread.installSystemProviders(providers);
10004        }
10005
10006        mCoreSettingsObserver = new CoreSettingsObserver(this);
10007
10008        //mUsageStatsService.monitorPackages();
10009    }
10010
10011    /**
10012     * Allows apps to retrieve the MIME type of a URI.
10013     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10014     * users, then it does not need permission to access the ContentProvider.
10015     * Either, it needs cross-user uri grants.
10016     *
10017     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10018     *
10019     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10020     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10021     */
10022    public String getProviderMimeType(Uri uri, int userId) {
10023        enforceNotIsolatedCaller("getProviderMimeType");
10024        final String name = uri.getAuthority();
10025        int callingUid = Binder.getCallingUid();
10026        int callingPid = Binder.getCallingPid();
10027        long ident = 0;
10028        boolean clearedIdentity = false;
10029        userId = unsafeConvertIncomingUser(userId);
10030        if (canClearIdentity(callingPid, callingUid, userId)) {
10031            clearedIdentity = true;
10032            ident = Binder.clearCallingIdentity();
10033        }
10034        ContentProviderHolder holder = null;
10035        try {
10036            holder = getContentProviderExternalUnchecked(name, null, userId);
10037            if (holder != null) {
10038                return holder.provider.getType(uri);
10039            }
10040        } catch (RemoteException e) {
10041            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10042            return null;
10043        } finally {
10044            // We need to clear the identity to call removeContentProviderExternalUnchecked
10045            if (!clearedIdentity) {
10046                ident = Binder.clearCallingIdentity();
10047            }
10048            try {
10049                if (holder != null) {
10050                    removeContentProviderExternalUnchecked(name, null, userId);
10051                }
10052            } finally {
10053                Binder.restoreCallingIdentity(ident);
10054            }
10055        }
10056
10057        return null;
10058    }
10059
10060    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10061        if (UserHandle.getUserId(callingUid) == userId) {
10062            return true;
10063        }
10064        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10065                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10066                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10067                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10068                return true;
10069        }
10070        return false;
10071    }
10072
10073    // =========================================================
10074    // GLOBAL MANAGEMENT
10075    // =========================================================
10076
10077    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10078            boolean isolated, int isolatedUid) {
10079        String proc = customProcess != null ? customProcess : info.processName;
10080        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10081        final int userId = UserHandle.getUserId(info.uid);
10082        int uid = info.uid;
10083        if (isolated) {
10084            if (isolatedUid == 0) {
10085                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10086                while (true) {
10087                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10088                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10089                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10090                    }
10091                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10092                    mNextIsolatedProcessUid++;
10093                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10094                        // No process for this uid, use it.
10095                        break;
10096                    }
10097                    stepsLeft--;
10098                    if (stepsLeft <= 0) {
10099                        return null;
10100                    }
10101                }
10102            } else {
10103                // Special case for startIsolatedProcess (internal only), where
10104                // the uid of the isolated process is specified by the caller.
10105                uid = isolatedUid;
10106            }
10107        }
10108        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10109        if (!mBooted && !mBooting
10110                && userId == UserHandle.USER_OWNER
10111                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10112            r.persistent = true;
10113        }
10114        addProcessNameLocked(r);
10115        return r;
10116    }
10117
10118    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10119            String abiOverride) {
10120        ProcessRecord app;
10121        if (!isolated) {
10122            app = getProcessRecordLocked(info.processName, info.uid, true);
10123        } else {
10124            app = null;
10125        }
10126
10127        if (app == null) {
10128            app = newProcessRecordLocked(info, null, isolated, 0);
10129            updateLruProcessLocked(app, false, null);
10130            updateOomAdjLocked();
10131        }
10132
10133        // This package really, really can not be stopped.
10134        try {
10135            AppGlobals.getPackageManager().setPackageStoppedState(
10136                    info.packageName, false, UserHandle.getUserId(app.uid));
10137        } catch (RemoteException e) {
10138        } catch (IllegalArgumentException e) {
10139            Slog.w(TAG, "Failed trying to unstop package "
10140                    + info.packageName + ": " + e);
10141        }
10142
10143        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10144            app.persistent = true;
10145            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10146        }
10147        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10148            mPersistentStartingProcesses.add(app);
10149            startProcessLocked(app, "added application", app.processName, abiOverride,
10150                    null /* entryPoint */, null /* entryPointArgs */);
10151        }
10152
10153        return app;
10154    }
10155
10156    public void unhandledBack() {
10157        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10158                "unhandledBack()");
10159
10160        synchronized(this) {
10161            final long origId = Binder.clearCallingIdentity();
10162            try {
10163                getFocusedStack().unhandledBackLocked();
10164            } finally {
10165                Binder.restoreCallingIdentity(origId);
10166            }
10167        }
10168    }
10169
10170    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10171        enforceNotIsolatedCaller("openContentUri");
10172        final int userId = UserHandle.getCallingUserId();
10173        String name = uri.getAuthority();
10174        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10175        ParcelFileDescriptor pfd = null;
10176        if (cph != null) {
10177            // We record the binder invoker's uid in thread-local storage before
10178            // going to the content provider to open the file.  Later, in the code
10179            // that handles all permissions checks, we look for this uid and use
10180            // that rather than the Activity Manager's own uid.  The effect is that
10181            // we do the check against the caller's permissions even though it looks
10182            // to the content provider like the Activity Manager itself is making
10183            // the request.
10184            Binder token = new Binder();
10185            sCallerIdentity.set(new Identity(
10186                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10187            try {
10188                pfd = cph.provider.openFile(null, uri, "r", null, token);
10189            } catch (FileNotFoundException e) {
10190                // do nothing; pfd will be returned null
10191            } finally {
10192                // Ensure that whatever happens, we clean up the identity state
10193                sCallerIdentity.remove();
10194                // Ensure we're done with the provider.
10195                removeContentProviderExternalUnchecked(name, null, userId);
10196            }
10197        } else {
10198            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10199        }
10200        return pfd;
10201    }
10202
10203    // Actually is sleeping or shutting down or whatever else in the future
10204    // is an inactive state.
10205    public boolean isSleepingOrShuttingDown() {
10206        return isSleeping() || mShuttingDown;
10207    }
10208
10209    public boolean isSleeping() {
10210        return mSleeping;
10211    }
10212
10213    void onWakefulnessChanged(int wakefulness) {
10214        synchronized(this) {
10215            mWakefulness = wakefulness;
10216            updateSleepIfNeededLocked();
10217        }
10218    }
10219
10220    void finishRunningVoiceLocked() {
10221        if (mRunningVoice != null) {
10222            mRunningVoice = null;
10223            mVoiceWakeLock.release();
10224            updateSleepIfNeededLocked();
10225        }
10226    }
10227
10228    void startTimeTrackingFocusedActivityLocked() {
10229        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10230            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10231        }
10232    }
10233
10234    void updateSleepIfNeededLocked() {
10235        if (mSleeping && !shouldSleepLocked()) {
10236            mSleeping = false;
10237            startTimeTrackingFocusedActivityLocked();
10238            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10239            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10240            updateOomAdjLocked();
10241        } else if (!mSleeping && shouldSleepLocked()) {
10242            mSleeping = true;
10243            if (mCurAppTimeTracker != null) {
10244                mCurAppTimeTracker.stop();
10245            }
10246            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10247            mStackSupervisor.goingToSleepLocked();
10248            updateOomAdjLocked();
10249
10250            // Initialize the wake times of all processes.
10251            checkExcessivePowerUsageLocked(false);
10252            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10253            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10254            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10255        }
10256    }
10257
10258    private boolean shouldSleepLocked() {
10259        // Resume applications while running a voice interactor.
10260        if (mRunningVoice != null) {
10261            return false;
10262        }
10263
10264        // TODO: Transform the lock screen state into a sleep token instead.
10265        switch (mWakefulness) {
10266            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10267            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10268            case PowerManagerInternal.WAKEFULNESS_DOZING:
10269                // Pause applications whenever the lock screen is shown or any sleep
10270                // tokens have been acquired.
10271                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10272            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10273            default:
10274                // If we're asleep then pause applications unconditionally.
10275                return true;
10276        }
10277    }
10278
10279    /** Pokes the task persister. */
10280    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10281        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10282            // Never persist the home stack.
10283            return;
10284        }
10285        mTaskPersister.wakeup(task, flush);
10286    }
10287
10288    /** Notifies all listeners when the task stack has changed. */
10289    void notifyTaskStackChangedLocked() {
10290        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10291        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10292        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10293    }
10294
10295    @Override
10296    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10297        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10298    }
10299
10300    @Override
10301    public boolean shutdown(int timeout) {
10302        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10303                != PackageManager.PERMISSION_GRANTED) {
10304            throw new SecurityException("Requires permission "
10305                    + android.Manifest.permission.SHUTDOWN);
10306        }
10307
10308        boolean timedout = false;
10309
10310        synchronized(this) {
10311            mShuttingDown = true;
10312            updateEventDispatchingLocked();
10313            timedout = mStackSupervisor.shutdownLocked(timeout);
10314        }
10315
10316        mAppOpsService.shutdown();
10317        if (mUsageStatsService != null) {
10318            mUsageStatsService.prepareShutdown();
10319        }
10320        mBatteryStatsService.shutdown();
10321        synchronized (this) {
10322            mProcessStats.shutdownLocked();
10323            notifyTaskPersisterLocked(null, true);
10324        }
10325
10326        return timedout;
10327    }
10328
10329    public final void activitySlept(IBinder token) {
10330        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10331
10332        final long origId = Binder.clearCallingIdentity();
10333
10334        synchronized (this) {
10335            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10336            if (r != null) {
10337                mStackSupervisor.activitySleptLocked(r);
10338            }
10339        }
10340
10341        Binder.restoreCallingIdentity(origId);
10342    }
10343
10344    private String lockScreenShownToString() {
10345        switch (mLockScreenShown) {
10346            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10347            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10348            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10349            default: return "Unknown=" + mLockScreenShown;
10350        }
10351    }
10352
10353    void logLockScreen(String msg) {
10354        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10355                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10356                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10357                + " mSleeping=" + mSleeping);
10358    }
10359
10360    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10361        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10362        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10363            boolean wasRunningVoice = mRunningVoice != null;
10364            mRunningVoice = session;
10365            if (!wasRunningVoice) {
10366                mVoiceWakeLock.acquire();
10367                updateSleepIfNeededLocked();
10368            }
10369        }
10370    }
10371
10372    private void updateEventDispatchingLocked() {
10373        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10374    }
10375
10376    public void setLockScreenShown(boolean shown) {
10377        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10378                != PackageManager.PERMISSION_GRANTED) {
10379            throw new SecurityException("Requires permission "
10380                    + android.Manifest.permission.DEVICE_POWER);
10381        }
10382
10383        synchronized(this) {
10384            long ident = Binder.clearCallingIdentity();
10385            try {
10386                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10387                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10388                updateSleepIfNeededLocked();
10389            } finally {
10390                Binder.restoreCallingIdentity(ident);
10391            }
10392        }
10393    }
10394
10395    @Override
10396    public void stopAppSwitches() {
10397        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10398                != PackageManager.PERMISSION_GRANTED) {
10399            throw new SecurityException("Requires permission "
10400                    + android.Manifest.permission.STOP_APP_SWITCHES);
10401        }
10402
10403        synchronized(this) {
10404            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10405                    + APP_SWITCH_DELAY_TIME;
10406            mDidAppSwitch = false;
10407            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10408            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10409            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10410        }
10411    }
10412
10413    public void resumeAppSwitches() {
10414        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10415                != PackageManager.PERMISSION_GRANTED) {
10416            throw new SecurityException("Requires permission "
10417                    + android.Manifest.permission.STOP_APP_SWITCHES);
10418        }
10419
10420        synchronized(this) {
10421            // Note that we don't execute any pending app switches... we will
10422            // let those wait until either the timeout, or the next start
10423            // activity request.
10424            mAppSwitchesAllowedTime = 0;
10425        }
10426    }
10427
10428    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10429            int callingPid, int callingUid, String name) {
10430        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10431            return true;
10432        }
10433
10434        int perm = checkComponentPermission(
10435                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10436                sourceUid, -1, true);
10437        if (perm == PackageManager.PERMISSION_GRANTED) {
10438            return true;
10439        }
10440
10441        // If the actual IPC caller is different from the logical source, then
10442        // also see if they are allowed to control app switches.
10443        if (callingUid != -1 && callingUid != sourceUid) {
10444            perm = checkComponentPermission(
10445                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10446                    callingUid, -1, true);
10447            if (perm == PackageManager.PERMISSION_GRANTED) {
10448                return true;
10449            }
10450        }
10451
10452        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10453        return false;
10454    }
10455
10456    public void setDebugApp(String packageName, boolean waitForDebugger,
10457            boolean persistent) {
10458        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10459                "setDebugApp()");
10460
10461        long ident = Binder.clearCallingIdentity();
10462        try {
10463            // Note that this is not really thread safe if there are multiple
10464            // callers into it at the same time, but that's not a situation we
10465            // care about.
10466            if (persistent) {
10467                final ContentResolver resolver = mContext.getContentResolver();
10468                Settings.Global.putString(
10469                    resolver, Settings.Global.DEBUG_APP,
10470                    packageName);
10471                Settings.Global.putInt(
10472                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10473                    waitForDebugger ? 1 : 0);
10474            }
10475
10476            synchronized (this) {
10477                if (!persistent) {
10478                    mOrigDebugApp = mDebugApp;
10479                    mOrigWaitForDebugger = mWaitForDebugger;
10480                }
10481                mDebugApp = packageName;
10482                mWaitForDebugger = waitForDebugger;
10483                mDebugTransient = !persistent;
10484                if (packageName != null) {
10485                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10486                            false, UserHandle.USER_ALL, "set debug app");
10487                }
10488            }
10489        } finally {
10490            Binder.restoreCallingIdentity(ident);
10491        }
10492    }
10493
10494    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10495        synchronized (this) {
10496            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10497            if (!isDebuggable) {
10498                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10499                    throw new SecurityException("Process not debuggable: " + app.packageName);
10500                }
10501            }
10502
10503            mOpenGlTraceApp = processName;
10504        }
10505    }
10506
10507    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10508        synchronized (this) {
10509            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10510            if (!isDebuggable) {
10511                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10512                    throw new SecurityException("Process not debuggable: " + app.packageName);
10513                }
10514            }
10515            mProfileApp = processName;
10516            mProfileFile = profilerInfo.profileFile;
10517            if (mProfileFd != null) {
10518                try {
10519                    mProfileFd.close();
10520                } catch (IOException e) {
10521                }
10522                mProfileFd = null;
10523            }
10524            mProfileFd = profilerInfo.profileFd;
10525            mSamplingInterval = profilerInfo.samplingInterval;
10526            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10527            mProfileType = 0;
10528        }
10529    }
10530
10531    @Override
10532    public void setAlwaysFinish(boolean enabled) {
10533        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10534                "setAlwaysFinish()");
10535
10536        Settings.Global.putInt(
10537                mContext.getContentResolver(),
10538                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10539
10540        synchronized (this) {
10541            mAlwaysFinishActivities = enabled;
10542        }
10543    }
10544
10545    @Override
10546    public void setActivityController(IActivityController controller) {
10547        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10548                "setActivityController()");
10549        synchronized (this) {
10550            mController = controller;
10551            Watchdog.getInstance().setActivityController(controller);
10552        }
10553    }
10554
10555    @Override
10556    public void setUserIsMonkey(boolean userIsMonkey) {
10557        synchronized (this) {
10558            synchronized (mPidsSelfLocked) {
10559                final int callingPid = Binder.getCallingPid();
10560                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10561                if (precessRecord == null) {
10562                    throw new SecurityException("Unknown process: " + callingPid);
10563                }
10564                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10565                    throw new SecurityException("Only an instrumentation process "
10566                            + "with a UiAutomation can call setUserIsMonkey");
10567                }
10568            }
10569            mUserIsMonkey = userIsMonkey;
10570        }
10571    }
10572
10573    @Override
10574    public boolean isUserAMonkey() {
10575        synchronized (this) {
10576            // If there is a controller also implies the user is a monkey.
10577            return (mUserIsMonkey || mController != null);
10578        }
10579    }
10580
10581    public void requestBugReport() {
10582        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10583        SystemProperties.set("ctl.start", "bugreport");
10584    }
10585
10586    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10587        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10588    }
10589
10590    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10591        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10592            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10593        }
10594        return KEY_DISPATCHING_TIMEOUT;
10595    }
10596
10597    @Override
10598    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10599        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10600                != PackageManager.PERMISSION_GRANTED) {
10601            throw new SecurityException("Requires permission "
10602                    + android.Manifest.permission.FILTER_EVENTS);
10603        }
10604        ProcessRecord proc;
10605        long timeout;
10606        synchronized (this) {
10607            synchronized (mPidsSelfLocked) {
10608                proc = mPidsSelfLocked.get(pid);
10609            }
10610            timeout = getInputDispatchingTimeoutLocked(proc);
10611        }
10612
10613        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10614            return -1;
10615        }
10616
10617        return timeout;
10618    }
10619
10620    /**
10621     * Handle input dispatching timeouts.
10622     * Returns whether input dispatching should be aborted or not.
10623     */
10624    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10625            final ActivityRecord activity, final ActivityRecord parent,
10626            final boolean aboveSystem, String reason) {
10627        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10628                != PackageManager.PERMISSION_GRANTED) {
10629            throw new SecurityException("Requires permission "
10630                    + android.Manifest.permission.FILTER_EVENTS);
10631        }
10632
10633        final String annotation;
10634        if (reason == null) {
10635            annotation = "Input dispatching timed out";
10636        } else {
10637            annotation = "Input dispatching timed out (" + reason + ")";
10638        }
10639
10640        if (proc != null) {
10641            synchronized (this) {
10642                if (proc.debugging) {
10643                    return false;
10644                }
10645
10646                if (mDidDexOpt) {
10647                    // Give more time since we were dexopting.
10648                    mDidDexOpt = false;
10649                    return false;
10650                }
10651
10652                if (proc.instrumentationClass != null) {
10653                    Bundle info = new Bundle();
10654                    info.putString("shortMsg", "keyDispatchingTimedOut");
10655                    info.putString("longMsg", annotation);
10656                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10657                    return true;
10658                }
10659            }
10660            mHandler.post(new Runnable() {
10661                @Override
10662                public void run() {
10663                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10664                }
10665            });
10666        }
10667
10668        return true;
10669    }
10670
10671    @Override
10672    public Bundle getAssistContextExtras(int requestType) {
10673        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10674                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10675        if (pae == null) {
10676            return null;
10677        }
10678        synchronized (pae) {
10679            while (!pae.haveResult) {
10680                try {
10681                    pae.wait();
10682                } catch (InterruptedException e) {
10683                }
10684            }
10685        }
10686        synchronized (this) {
10687            buildAssistBundleLocked(pae, pae.result);
10688            mPendingAssistExtras.remove(pae);
10689            mHandler.removeCallbacks(pae);
10690        }
10691        return pae.extras;
10692    }
10693
10694    @Override
10695    public boolean isScreenCaptureAllowedOnCurrentActivity() {
10696        int userId = mCurrentUserId;
10697        synchronized (this) {
10698            ActivityRecord activity = getFocusedStack().topActivity();
10699            if (activity == null) {
10700                return false;
10701            }
10702            userId = activity.userId;
10703        }
10704        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10705                Context.DEVICE_POLICY_SERVICE);
10706        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10707    }
10708
10709    @Override
10710    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10711        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10712                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10713    }
10714
10715    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10716            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
10717        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10718                "enqueueAssistContext()");
10719        synchronized (this) {
10720            ActivityRecord activity = getFocusedStack().topActivity();
10721            if (activity == null) {
10722                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10723                return null;
10724            }
10725            if (activity.app == null || activity.app.thread == null) {
10726                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10727                return null;
10728            }
10729            if (activity.app.pid == Binder.getCallingPid()) {
10730                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10731                return null;
10732            }
10733            PendingAssistExtras pae;
10734            Bundle extras = new Bundle();
10735            if (args != null) {
10736                extras.putAll(args);
10737            }
10738            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10739            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10740            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10741            try {
10742                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10743                        requestType);
10744                mPendingAssistExtras.add(pae);
10745                mHandler.postDelayed(pae, timeout);
10746            } catch (RemoteException e) {
10747                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10748                return null;
10749            }
10750            return pae;
10751        }
10752    }
10753
10754    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10755        mPendingAssistExtras.remove(pae);
10756        if (pae.receiver != null) {
10757            // Caller wants result sent back to them.
10758            try {
10759                pae.receiver.send(0, null);
10760            } catch (RemoteException e) {
10761            }
10762        }
10763    }
10764
10765    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10766        if (result != null) {
10767            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10768        }
10769        if (pae.hint != null) {
10770            pae.extras.putBoolean(pae.hint, true);
10771        }
10772    }
10773
10774    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10775            AssistContent content, Uri referrer) {
10776        PendingAssistExtras pae = (PendingAssistExtras)token;
10777        synchronized (pae) {
10778            pae.result = extras;
10779            pae.structure = structure;
10780            pae.content = content;
10781            if (referrer != null) {
10782                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10783            }
10784            pae.haveResult = true;
10785            pae.notifyAll();
10786            if (pae.intent == null && pae.receiver == null) {
10787                // Caller is just waiting for the result.
10788                return;
10789            }
10790        }
10791
10792        // We are now ready to launch the assist activity.
10793        synchronized (this) {
10794            buildAssistBundleLocked(pae, extras);
10795            boolean exists = mPendingAssistExtras.remove(pae);
10796            mHandler.removeCallbacks(pae);
10797            if (!exists) {
10798                // Timed out.
10799                return;
10800            }
10801            if (pae.receiver != null) {
10802                // Caller wants result sent back to them.
10803                Bundle topBundle = new Bundle();
10804                topBundle.putBundle("data", pae.extras);
10805                topBundle.putParcelable("structure", pae.structure);
10806                topBundle.putParcelable("content", pae.content);
10807                try {
10808                    pae.receiver.send(0, topBundle);
10809                } catch (RemoteException e) {
10810                }
10811                return;
10812            }
10813        }
10814
10815        long ident = Binder.clearCallingIdentity();
10816        try {
10817            pae.intent.replaceExtras(pae.extras);
10818            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10819                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10820                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10821            closeSystemDialogs("assist");
10822            try {
10823                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10824            } catch (ActivityNotFoundException e) {
10825                Slog.w(TAG, "No activity to handle assist action.", e);
10826            }
10827        } finally {
10828            Binder.restoreCallingIdentity(ident);
10829        }
10830    }
10831
10832    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10833            Bundle args) {
10834        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
10835                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10836    }
10837
10838    public void registerProcessObserver(IProcessObserver observer) {
10839        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10840                "registerProcessObserver()");
10841        synchronized (this) {
10842            mProcessObservers.register(observer);
10843        }
10844    }
10845
10846    @Override
10847    public void unregisterProcessObserver(IProcessObserver observer) {
10848        synchronized (this) {
10849            mProcessObservers.unregister(observer);
10850        }
10851    }
10852
10853    public void registerUidObserver(IUidObserver observer) {
10854        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10855                "registerUidObserver()");
10856        synchronized (this) {
10857            mUidObservers.register(observer);
10858        }
10859    }
10860
10861    @Override
10862    public void unregisterUidObserver(IUidObserver observer) {
10863        synchronized (this) {
10864            mUidObservers.unregister(observer);
10865        }
10866    }
10867
10868    @Override
10869    public boolean convertFromTranslucent(IBinder token) {
10870        final long origId = Binder.clearCallingIdentity();
10871        try {
10872            synchronized (this) {
10873                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10874                if (r == null) {
10875                    return false;
10876                }
10877                final boolean translucentChanged = r.changeWindowTranslucency(true);
10878                if (translucentChanged) {
10879                    r.task.stack.releaseBackgroundResources(r);
10880                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10881                }
10882                mWindowManager.setAppFullscreen(token, true);
10883                return translucentChanged;
10884            }
10885        } finally {
10886            Binder.restoreCallingIdentity(origId);
10887        }
10888    }
10889
10890    @Override
10891    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10892        final long origId = Binder.clearCallingIdentity();
10893        try {
10894            synchronized (this) {
10895                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10896                if (r == null) {
10897                    return false;
10898                }
10899                int index = r.task.mActivities.lastIndexOf(r);
10900                if (index > 0) {
10901                    ActivityRecord under = r.task.mActivities.get(index - 1);
10902                    under.returningOptions = options;
10903                }
10904                final boolean translucentChanged = r.changeWindowTranslucency(false);
10905                if (translucentChanged) {
10906                    r.task.stack.convertActivityToTranslucent(r);
10907                }
10908                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10909                mWindowManager.setAppFullscreen(token, false);
10910                return translucentChanged;
10911            }
10912        } finally {
10913            Binder.restoreCallingIdentity(origId);
10914        }
10915    }
10916
10917    @Override
10918    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10919        final long origId = Binder.clearCallingIdentity();
10920        try {
10921            synchronized (this) {
10922                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10923                if (r != null) {
10924                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10925                }
10926            }
10927            return false;
10928        } finally {
10929            Binder.restoreCallingIdentity(origId);
10930        }
10931    }
10932
10933    @Override
10934    public boolean isBackgroundVisibleBehind(IBinder token) {
10935        final long origId = Binder.clearCallingIdentity();
10936        try {
10937            synchronized (this) {
10938                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10939                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10940                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
10941                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10942                return visible;
10943            }
10944        } finally {
10945            Binder.restoreCallingIdentity(origId);
10946        }
10947    }
10948
10949    @Override
10950    public ActivityOptions getActivityOptions(IBinder token) {
10951        final long origId = Binder.clearCallingIdentity();
10952        try {
10953            synchronized (this) {
10954                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10955                if (r != null) {
10956                    final ActivityOptions activityOptions = r.pendingOptions;
10957                    r.pendingOptions = null;
10958                    return activityOptions;
10959                }
10960                return null;
10961            }
10962        } finally {
10963            Binder.restoreCallingIdentity(origId);
10964        }
10965    }
10966
10967    @Override
10968    public void setImmersive(IBinder token, boolean immersive) {
10969        synchronized(this) {
10970            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10971            if (r == null) {
10972                throw new IllegalArgumentException();
10973            }
10974            r.immersive = immersive;
10975
10976            // update associated state if we're frontmost
10977            if (r == mFocusedActivity) {
10978                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10979                applyUpdateLockStateLocked(r);
10980            }
10981        }
10982    }
10983
10984    @Override
10985    public boolean isImmersive(IBinder token) {
10986        synchronized (this) {
10987            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10988            if (r == null) {
10989                throw new IllegalArgumentException();
10990            }
10991            return r.immersive;
10992        }
10993    }
10994
10995    public boolean isTopActivityImmersive() {
10996        enforceNotIsolatedCaller("startActivity");
10997        synchronized (this) {
10998            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10999            return (r != null) ? r.immersive : false;
11000        }
11001    }
11002
11003    @Override
11004    public boolean isTopOfTask(IBinder token) {
11005        synchronized (this) {
11006            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11007            if (r == null) {
11008                throw new IllegalArgumentException();
11009            }
11010            return r.task.getTopActivity() == r;
11011        }
11012    }
11013
11014    public final void enterSafeMode() {
11015        synchronized(this) {
11016            // It only makes sense to do this before the system is ready
11017            // and started launching other packages.
11018            if (!mSystemReady) {
11019                try {
11020                    AppGlobals.getPackageManager().enterSafeMode();
11021                } catch (RemoteException e) {
11022                }
11023            }
11024
11025            mSafeMode = true;
11026        }
11027    }
11028
11029    public final void showSafeModeOverlay() {
11030        View v = LayoutInflater.from(mContext).inflate(
11031                com.android.internal.R.layout.safe_mode, null);
11032        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11033        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11034        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11035        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11036        lp.gravity = Gravity.BOTTOM | Gravity.START;
11037        lp.format = v.getBackground().getOpacity();
11038        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11039                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11040        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11041        ((WindowManager)mContext.getSystemService(
11042                Context.WINDOW_SERVICE)).addView(v, lp);
11043    }
11044
11045    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11046        if (!(sender instanceof PendingIntentRecord)) {
11047            return;
11048        }
11049        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11050        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11051        synchronized (stats) {
11052            if (mBatteryStatsService.isOnBattery()) {
11053                mBatteryStatsService.enforceCallingPermission();
11054                int MY_UID = Binder.getCallingUid();
11055                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11056                BatteryStatsImpl.Uid.Pkg pkg =
11057                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11058                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11059                pkg.noteWakeupAlarmLocked(tag);
11060            }
11061        }
11062    }
11063
11064    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11065        if (!(sender instanceof PendingIntentRecord)) {
11066            return;
11067        }
11068        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11069        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11070        synchronized (stats) {
11071            mBatteryStatsService.enforceCallingPermission();
11072            int MY_UID = Binder.getCallingUid();
11073            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11074            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11075        }
11076    }
11077
11078    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11079        if (!(sender instanceof PendingIntentRecord)) {
11080            return;
11081        }
11082        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11083        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11084        synchronized (stats) {
11085            mBatteryStatsService.enforceCallingPermission();
11086            int MY_UID = Binder.getCallingUid();
11087            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11088            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11089        }
11090    }
11091
11092    public boolean killPids(int[] pids, String pReason, boolean secure) {
11093        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11094            throw new SecurityException("killPids only available to the system");
11095        }
11096        String reason = (pReason == null) ? "Unknown" : pReason;
11097        // XXX Note: don't acquire main activity lock here, because the window
11098        // manager calls in with its locks held.
11099
11100        boolean killed = false;
11101        synchronized (mPidsSelfLocked) {
11102            int[] types = new int[pids.length];
11103            int worstType = 0;
11104            for (int i=0; i<pids.length; i++) {
11105                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11106                if (proc != null) {
11107                    int type = proc.setAdj;
11108                    types[i] = type;
11109                    if (type > worstType) {
11110                        worstType = type;
11111                    }
11112                }
11113            }
11114
11115            // If the worst oom_adj is somewhere in the cached proc LRU range,
11116            // then constrain it so we will kill all cached procs.
11117            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11118                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11119                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11120            }
11121
11122            // If this is not a secure call, don't let it kill processes that
11123            // are important.
11124            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11125                worstType = ProcessList.SERVICE_ADJ;
11126            }
11127
11128            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11129            for (int i=0; i<pids.length; i++) {
11130                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11131                if (proc == null) {
11132                    continue;
11133                }
11134                int adj = proc.setAdj;
11135                if (adj >= worstType && !proc.killedByAm) {
11136                    proc.kill(reason, true);
11137                    killed = true;
11138                }
11139            }
11140        }
11141        return killed;
11142    }
11143
11144    @Override
11145    public void killUid(int uid, String reason) {
11146        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11147        synchronized (this) {
11148            final long identity = Binder.clearCallingIdentity();
11149            try {
11150                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11151                        UserHandle.getUserId(uid),
11152                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11153                        reason != null ? reason : "kill uid");
11154            } finally {
11155                Binder.restoreCallingIdentity(identity);
11156            }
11157        }
11158    }
11159
11160    @Override
11161    public boolean killProcessesBelowForeground(String reason) {
11162        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11163            throw new SecurityException("killProcessesBelowForeground() only available to system");
11164        }
11165
11166        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11167    }
11168
11169    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11170        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11171            throw new SecurityException("killProcessesBelowAdj() only available to system");
11172        }
11173
11174        boolean killed = false;
11175        synchronized (mPidsSelfLocked) {
11176            final int size = mPidsSelfLocked.size();
11177            for (int i = 0; i < size; i++) {
11178                final int pid = mPidsSelfLocked.keyAt(i);
11179                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11180                if (proc == null) continue;
11181
11182                final int adj = proc.setAdj;
11183                if (adj > belowAdj && !proc.killedByAm) {
11184                    proc.kill(reason, true);
11185                    killed = true;
11186                }
11187            }
11188        }
11189        return killed;
11190    }
11191
11192    @Override
11193    public void hang(final IBinder who, boolean allowRestart) {
11194        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11195                != PackageManager.PERMISSION_GRANTED) {
11196            throw new SecurityException("Requires permission "
11197                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11198        }
11199
11200        final IBinder.DeathRecipient death = new DeathRecipient() {
11201            @Override
11202            public void binderDied() {
11203                synchronized (this) {
11204                    notifyAll();
11205                }
11206            }
11207        };
11208
11209        try {
11210            who.linkToDeath(death, 0);
11211        } catch (RemoteException e) {
11212            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11213            return;
11214        }
11215
11216        synchronized (this) {
11217            Watchdog.getInstance().setAllowRestart(allowRestart);
11218            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11219            synchronized (death) {
11220                while (who.isBinderAlive()) {
11221                    try {
11222                        death.wait();
11223                    } catch (InterruptedException e) {
11224                    }
11225                }
11226            }
11227            Watchdog.getInstance().setAllowRestart(true);
11228        }
11229    }
11230
11231    @Override
11232    public void restart() {
11233        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11234                != PackageManager.PERMISSION_GRANTED) {
11235            throw new SecurityException("Requires permission "
11236                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11237        }
11238
11239        Log.i(TAG, "Sending shutdown broadcast...");
11240
11241        BroadcastReceiver br = new BroadcastReceiver() {
11242            @Override public void onReceive(Context context, Intent intent) {
11243                // Now the broadcast is done, finish up the low-level shutdown.
11244                Log.i(TAG, "Shutting down activity manager...");
11245                shutdown(10000);
11246                Log.i(TAG, "Shutdown complete, restarting!");
11247                Process.killProcess(Process.myPid());
11248                System.exit(10);
11249            }
11250        };
11251
11252        // First send the high-level shut down broadcast.
11253        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11254        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11255        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11256        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11257        mContext.sendOrderedBroadcastAsUser(intent,
11258                UserHandle.ALL, null, br, mHandler, 0, null, null);
11259        */
11260        br.onReceive(mContext, intent);
11261    }
11262
11263    private long getLowRamTimeSinceIdle(long now) {
11264        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11265    }
11266
11267    @Override
11268    public void performIdleMaintenance() {
11269        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11270                != PackageManager.PERMISSION_GRANTED) {
11271            throw new SecurityException("Requires permission "
11272                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11273        }
11274
11275        synchronized (this) {
11276            final long now = SystemClock.uptimeMillis();
11277            final long timeSinceLastIdle = now - mLastIdleTime;
11278            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11279            mLastIdleTime = now;
11280            mLowRamTimeSinceLastIdle = 0;
11281            if (mLowRamStartTime != 0) {
11282                mLowRamStartTime = now;
11283            }
11284
11285            StringBuilder sb = new StringBuilder(128);
11286            sb.append("Idle maintenance over ");
11287            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11288            sb.append(" low RAM for ");
11289            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11290            Slog.i(TAG, sb.toString());
11291
11292            // If at least 1/3 of our time since the last idle period has been spent
11293            // with RAM low, then we want to kill processes.
11294            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11295
11296            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11297                ProcessRecord proc = mLruProcesses.get(i);
11298                if (proc.notCachedSinceIdle) {
11299                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11300                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11301                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11302                        if (doKilling && proc.initialIdlePss != 0
11303                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11304                            sb = new StringBuilder(128);
11305                            sb.append("Kill");
11306                            sb.append(proc.processName);
11307                            sb.append(" in idle maint: pss=");
11308                            sb.append(proc.lastPss);
11309                            sb.append(", initialPss=");
11310                            sb.append(proc.initialIdlePss);
11311                            sb.append(", period=");
11312                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11313                            sb.append(", lowRamPeriod=");
11314                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11315                            Slog.wtfQuiet(TAG, sb.toString());
11316                            proc.kill("idle maint (pss " + proc.lastPss
11317                                    + " from " + proc.initialIdlePss + ")", true);
11318                        }
11319                    }
11320                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11321                    proc.notCachedSinceIdle = true;
11322                    proc.initialIdlePss = 0;
11323                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11324                            mTestPssMode, isSleeping(), now);
11325                }
11326            }
11327
11328            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11329            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11330        }
11331    }
11332
11333    private void retrieveSettings() {
11334        final ContentResolver resolver = mContext.getContentResolver();
11335        String debugApp = Settings.Global.getString(
11336            resolver, Settings.Global.DEBUG_APP);
11337        boolean waitForDebugger = Settings.Global.getInt(
11338            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11339        boolean alwaysFinishActivities = Settings.Global.getInt(
11340            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11341        boolean forceRtl = Settings.Global.getInt(
11342                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11343        // Transfer any global setting for forcing RTL layout, into a System Property
11344        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11345
11346        Configuration configuration = new Configuration();
11347        Settings.System.getConfiguration(resolver, configuration);
11348        if (forceRtl) {
11349            // This will take care of setting the correct layout direction flags
11350            configuration.setLayoutDirection(configuration.locale);
11351        }
11352
11353        synchronized (this) {
11354            mDebugApp = mOrigDebugApp = debugApp;
11355            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11356            mAlwaysFinishActivities = alwaysFinishActivities;
11357            // This happens before any activities are started, so we can
11358            // change mConfiguration in-place.
11359            updateConfigurationLocked(configuration, null, false, true);
11360            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11361                    "Initial config: " + mConfiguration);
11362        }
11363    }
11364
11365    /** Loads resources after the current configuration has been set. */
11366    private void loadResourcesOnSystemReady() {
11367        final Resources res = mContext.getResources();
11368        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11369        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11370        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11371    }
11372
11373    public boolean testIsSystemReady() {
11374        // no need to synchronize(this) just to read & return the value
11375        return mSystemReady;
11376    }
11377
11378    private static File getCalledPreBootReceiversFile() {
11379        File dataDir = Environment.getDataDirectory();
11380        File systemDir = new File(dataDir, "system");
11381        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11382        return fname;
11383    }
11384
11385    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11386        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11387        File file = getCalledPreBootReceiversFile();
11388        FileInputStream fis = null;
11389        try {
11390            fis = new FileInputStream(file);
11391            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11392            int fvers = dis.readInt();
11393            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11394                String vers = dis.readUTF();
11395                String codename = dis.readUTF();
11396                String build = dis.readUTF();
11397                if (android.os.Build.VERSION.RELEASE.equals(vers)
11398                        && android.os.Build.VERSION.CODENAME.equals(codename)
11399                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11400                    int num = dis.readInt();
11401                    while (num > 0) {
11402                        num--;
11403                        String pkg = dis.readUTF();
11404                        String cls = dis.readUTF();
11405                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11406                    }
11407                }
11408            }
11409        } catch (FileNotFoundException e) {
11410        } catch (IOException e) {
11411            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11412        } finally {
11413            if (fis != null) {
11414                try {
11415                    fis.close();
11416                } catch (IOException e) {
11417                }
11418            }
11419        }
11420        return lastDoneReceivers;
11421    }
11422
11423    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11424        File file = getCalledPreBootReceiversFile();
11425        FileOutputStream fos = null;
11426        DataOutputStream dos = null;
11427        try {
11428            fos = new FileOutputStream(file);
11429            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11430            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11431            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11432            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11433            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11434            dos.writeInt(list.size());
11435            for (int i=0; i<list.size(); i++) {
11436                dos.writeUTF(list.get(i).getPackageName());
11437                dos.writeUTF(list.get(i).getClassName());
11438            }
11439        } catch (IOException e) {
11440            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11441            file.delete();
11442        } finally {
11443            FileUtils.sync(fos);
11444            if (dos != null) {
11445                try {
11446                    dos.close();
11447                } catch (IOException e) {
11448                    // TODO Auto-generated catch block
11449                    e.printStackTrace();
11450                }
11451            }
11452        }
11453    }
11454
11455    final class PreBootContinuation extends IIntentReceiver.Stub {
11456        final Intent intent;
11457        final Runnable onFinishCallback;
11458        final ArrayList<ComponentName> doneReceivers;
11459        final List<ResolveInfo> ris;
11460        final int[] users;
11461        int lastRi = -1;
11462        int curRi = 0;
11463        int curUser = 0;
11464
11465        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11466                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11467            intent = _intent;
11468            onFinishCallback = _onFinishCallback;
11469            doneReceivers = _doneReceivers;
11470            ris = _ris;
11471            users = _users;
11472        }
11473
11474        void go() {
11475            if (lastRi != curRi) {
11476                ActivityInfo ai = ris.get(curRi).activityInfo;
11477                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11478                intent.setComponent(comp);
11479                doneReceivers.add(comp);
11480                lastRi = curRi;
11481                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11482                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11483            }
11484            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11485                    + " for user " + users[curUser]);
11486            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11487            broadcastIntentLocked(null, null, intent, null, this,
11488                    0, null, null, null, AppOpsManager.OP_NONE,
11489                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11490        }
11491
11492        public void performReceive(Intent intent, int resultCode,
11493                String data, Bundle extras, boolean ordered,
11494                boolean sticky, int sendingUser) {
11495            curUser++;
11496            if (curUser >= users.length) {
11497                curUser = 0;
11498                curRi++;
11499                if (curRi >= ris.size()) {
11500                    // All done sending broadcasts!
11501                    if (onFinishCallback != null) {
11502                        // The raw IIntentReceiver interface is called
11503                        // with the AM lock held, so redispatch to
11504                        // execute our code without the lock.
11505                        mHandler.post(onFinishCallback);
11506                    }
11507                    return;
11508                }
11509            }
11510            go();
11511        }
11512    }
11513
11514    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11515            ArrayList<ComponentName> doneReceivers, int userId) {
11516        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11517        List<ResolveInfo> ris = null;
11518        try {
11519            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11520                    intent, null, 0, userId);
11521        } catch (RemoteException e) {
11522        }
11523        if (ris == null) {
11524            return false;
11525        }
11526        for (int i=ris.size()-1; i>=0; i--) {
11527            if ((ris.get(i).activityInfo.applicationInfo.flags
11528                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11529                ris.remove(i);
11530            }
11531        }
11532        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11533
11534        // For User 0, load the version number. When delivering to a new user, deliver
11535        // to all receivers.
11536        if (userId == UserHandle.USER_OWNER) {
11537            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11538            for (int i=0; i<ris.size(); i++) {
11539                ActivityInfo ai = ris.get(i).activityInfo;
11540                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11541                if (lastDoneReceivers.contains(comp)) {
11542                    // We already did the pre boot receiver for this app with the current
11543                    // platform version, so don't do it again...
11544                    ris.remove(i);
11545                    i--;
11546                    // ...however, do keep it as one that has been done, so we don't
11547                    // forget about it when rewriting the file of last done receivers.
11548                    doneReceivers.add(comp);
11549                }
11550            }
11551        }
11552
11553        if (ris.size() <= 0) {
11554            return false;
11555        }
11556
11557        // If primary user, send broadcast to all available users, else just to userId
11558        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11559                : new int[] { userId };
11560        if (users.length <= 0) {
11561            return false;
11562        }
11563
11564        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11565                ris, users);
11566        cont.go();
11567        return true;
11568    }
11569
11570    public void systemReady(final Runnable goingCallback) {
11571        synchronized(this) {
11572            if (mSystemReady) {
11573                // If we're done calling all the receivers, run the next "boot phase" passed in
11574                // by the SystemServer
11575                if (goingCallback != null) {
11576                    goingCallback.run();
11577                }
11578                return;
11579            }
11580
11581            mLocalDeviceIdleController
11582                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11583
11584            // Make sure we have the current profile info, since it is needed for
11585            // security checks.
11586            updateCurrentProfileIdsLocked();
11587
11588            mRecentTasks.clear();
11589            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11590            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11591            mTaskPersister.startPersisting();
11592
11593            // Check to see if there are any update receivers to run.
11594            if (!mDidUpdate) {
11595                if (mWaitingUpdate) {
11596                    return;
11597                }
11598                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11599                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11600                    public void run() {
11601                        synchronized (ActivityManagerService.this) {
11602                            mDidUpdate = true;
11603                        }
11604                        showBootMessage(mContext.getText(
11605                                R.string.android_upgrading_complete),
11606                                false);
11607                        writeLastDonePreBootReceivers(doneReceivers);
11608                        systemReady(goingCallback);
11609                    }
11610                }, doneReceivers, UserHandle.USER_OWNER);
11611
11612                if (mWaitingUpdate) {
11613                    return;
11614                }
11615                mDidUpdate = true;
11616            }
11617
11618            mAppOpsService.systemReady();
11619            mSystemReady = true;
11620        }
11621
11622        ArrayList<ProcessRecord> procsToKill = null;
11623        synchronized(mPidsSelfLocked) {
11624            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11625                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11626                if (!isAllowedWhileBooting(proc.info)){
11627                    if (procsToKill == null) {
11628                        procsToKill = new ArrayList<ProcessRecord>();
11629                    }
11630                    procsToKill.add(proc);
11631                }
11632            }
11633        }
11634
11635        synchronized(this) {
11636            if (procsToKill != null) {
11637                for (int i=procsToKill.size()-1; i>=0; i--) {
11638                    ProcessRecord proc = procsToKill.get(i);
11639                    Slog.i(TAG, "Removing system update proc: " + proc);
11640                    removeProcessLocked(proc, true, false, "system update done");
11641                }
11642            }
11643
11644            // Now that we have cleaned up any update processes, we
11645            // are ready to start launching real processes and know that
11646            // we won't trample on them any more.
11647            mProcessesReady = true;
11648        }
11649
11650        Slog.i(TAG, "System now ready");
11651        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11652            SystemClock.uptimeMillis());
11653
11654        synchronized(this) {
11655            // Make sure we have no pre-ready processes sitting around.
11656
11657            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11658                ResolveInfo ri = mContext.getPackageManager()
11659                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11660                                STOCK_PM_FLAGS);
11661                CharSequence errorMsg = null;
11662                if (ri != null) {
11663                    ActivityInfo ai = ri.activityInfo;
11664                    ApplicationInfo app = ai.applicationInfo;
11665                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11666                        mTopAction = Intent.ACTION_FACTORY_TEST;
11667                        mTopData = null;
11668                        mTopComponent = new ComponentName(app.packageName,
11669                                ai.name);
11670                    } else {
11671                        errorMsg = mContext.getResources().getText(
11672                                com.android.internal.R.string.factorytest_not_system);
11673                    }
11674                } else {
11675                    errorMsg = mContext.getResources().getText(
11676                            com.android.internal.R.string.factorytest_no_action);
11677                }
11678                if (errorMsg != null) {
11679                    mTopAction = null;
11680                    mTopData = null;
11681                    mTopComponent = null;
11682                    Message msg = Message.obtain();
11683                    msg.what = SHOW_FACTORY_ERROR_MSG;
11684                    msg.getData().putCharSequence("msg", errorMsg);
11685                    mUiHandler.sendMessage(msg);
11686                }
11687            }
11688        }
11689
11690        retrieveSettings();
11691        loadResourcesOnSystemReady();
11692
11693        synchronized (this) {
11694            readGrantedUriPermissionsLocked();
11695        }
11696
11697        if (goingCallback != null) goingCallback.run();
11698
11699        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11700                Integer.toString(mCurrentUserId), mCurrentUserId);
11701        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11702                Integer.toString(mCurrentUserId), mCurrentUserId);
11703        mSystemServiceManager.startUser(mCurrentUserId);
11704
11705        synchronized (this) {
11706            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11707                try {
11708                    List apps = AppGlobals.getPackageManager().
11709                        getPersistentApplications(STOCK_PM_FLAGS);
11710                    if (apps != null) {
11711                        int N = apps.size();
11712                        int i;
11713                        for (i=0; i<N; i++) {
11714                            ApplicationInfo info
11715                                = (ApplicationInfo)apps.get(i);
11716                            if (info != null &&
11717                                    !info.packageName.equals("android")) {
11718                                addAppLocked(info, false, null /* ABI override */);
11719                            }
11720                        }
11721                    }
11722                } catch (RemoteException ex) {
11723                    // pm is in same process, this will never happen.
11724                }
11725            }
11726
11727            // Start up initial activity.
11728            mBooting = true;
11729            startHomeActivityLocked(mCurrentUserId, "systemReady");
11730
11731            try {
11732                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11733                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11734                            + " data partition or your device will be unstable.");
11735                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11736                }
11737            } catch (RemoteException e) {
11738            }
11739
11740            if (!Build.isBuildConsistent()) {
11741                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11742                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11743            }
11744
11745            long ident = Binder.clearCallingIdentity();
11746            try {
11747                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11748                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11749                        | Intent.FLAG_RECEIVER_FOREGROUND);
11750                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11751                broadcastIntentLocked(null, null, intent,
11752                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11753                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11754                intent = new Intent(Intent.ACTION_USER_STARTING);
11755                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11756                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11757                broadcastIntentLocked(null, null, intent,
11758                        null, new IIntentReceiver.Stub() {
11759                            @Override
11760                            public void performReceive(Intent intent, int resultCode, String data,
11761                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11762                                    throws RemoteException {
11763                            }
11764                        }, 0, null, null,
11765                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11766                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11767            } catch (Throwable t) {
11768                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11769            } finally {
11770                Binder.restoreCallingIdentity(ident);
11771            }
11772            mStackSupervisor.resumeTopActivitiesLocked();
11773            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11774        }
11775    }
11776
11777    private boolean makeAppCrashingLocked(ProcessRecord app,
11778            String shortMsg, String longMsg, String stackTrace) {
11779        app.crashing = true;
11780        app.crashingReport = generateProcessError(app,
11781                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11782        startAppProblemLocked(app);
11783        app.stopFreezingAllLocked();
11784        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11785    }
11786
11787    private void makeAppNotRespondingLocked(ProcessRecord app,
11788            String activity, String shortMsg, String longMsg) {
11789        app.notResponding = true;
11790        app.notRespondingReport = generateProcessError(app,
11791                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11792                activity, shortMsg, longMsg, null);
11793        startAppProblemLocked(app);
11794        app.stopFreezingAllLocked();
11795    }
11796
11797    /**
11798     * Generate a process error record, suitable for attachment to a ProcessRecord.
11799     *
11800     * @param app The ProcessRecord in which the error occurred.
11801     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11802     *                      ActivityManager.AppErrorStateInfo
11803     * @param activity The activity associated with the crash, if known.
11804     * @param shortMsg Short message describing the crash.
11805     * @param longMsg Long message describing the crash.
11806     * @param stackTrace Full crash stack trace, may be null.
11807     *
11808     * @return Returns a fully-formed AppErrorStateInfo record.
11809     */
11810    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11811            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11812        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11813
11814        report.condition = condition;
11815        report.processName = app.processName;
11816        report.pid = app.pid;
11817        report.uid = app.info.uid;
11818        report.tag = activity;
11819        report.shortMsg = shortMsg;
11820        report.longMsg = longMsg;
11821        report.stackTrace = stackTrace;
11822
11823        return report;
11824    }
11825
11826    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11827        synchronized (this) {
11828            app.crashing = false;
11829            app.crashingReport = null;
11830            app.notResponding = false;
11831            app.notRespondingReport = null;
11832            if (app.anrDialog == fromDialog) {
11833                app.anrDialog = null;
11834            }
11835            if (app.waitDialog == fromDialog) {
11836                app.waitDialog = null;
11837            }
11838            if (app.pid > 0 && app.pid != MY_PID) {
11839                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11840                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11841                app.kill("user request after error", true);
11842            }
11843        }
11844    }
11845
11846    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11847            String shortMsg, String longMsg, String stackTrace) {
11848        long now = SystemClock.uptimeMillis();
11849
11850        Long crashTime;
11851        if (!app.isolated) {
11852            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11853        } else {
11854            crashTime = null;
11855        }
11856        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11857            // This process loses!
11858            Slog.w(TAG, "Process " + app.info.processName
11859                    + " has crashed too many times: killing!");
11860            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11861                    app.userId, app.info.processName, app.uid);
11862            mStackSupervisor.handleAppCrashLocked(app);
11863            if (!app.persistent) {
11864                // We don't want to start this process again until the user
11865                // explicitly does so...  but for persistent process, we really
11866                // need to keep it running.  If a persistent process is actually
11867                // repeatedly crashing, then badness for everyone.
11868                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11869                        app.info.processName);
11870                if (!app.isolated) {
11871                    // XXX We don't have a way to mark isolated processes
11872                    // as bad, since they don't have a peristent identity.
11873                    mBadProcesses.put(app.info.processName, app.uid,
11874                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11875                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11876                }
11877                app.bad = true;
11878                app.removed = true;
11879                // Don't let services in this process be restarted and potentially
11880                // annoy the user repeatedly.  Unless it is persistent, since those
11881                // processes run critical code.
11882                removeProcessLocked(app, false, false, "crash");
11883                mStackSupervisor.resumeTopActivitiesLocked();
11884                return false;
11885            }
11886            mStackSupervisor.resumeTopActivitiesLocked();
11887        } else {
11888            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11889        }
11890
11891        // Bump up the crash count of any services currently running in the proc.
11892        for (int i=app.services.size()-1; i>=0; i--) {
11893            // Any services running in the application need to be placed
11894            // back in the pending list.
11895            ServiceRecord sr = app.services.valueAt(i);
11896            sr.crashCount++;
11897        }
11898
11899        // If the crashing process is what we consider to be the "home process" and it has been
11900        // replaced by a third-party app, clear the package preferred activities from packages
11901        // with a home activity running in the process to prevent a repeatedly crashing app
11902        // from blocking the user to manually clear the list.
11903        final ArrayList<ActivityRecord> activities = app.activities;
11904        if (app == mHomeProcess && activities.size() > 0
11905                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11906            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11907                final ActivityRecord r = activities.get(activityNdx);
11908                if (r.isHomeActivity()) {
11909                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11910                    try {
11911                        ActivityThread.getPackageManager()
11912                                .clearPackagePreferredActivities(r.packageName);
11913                    } catch (RemoteException c) {
11914                        // pm is in same process, this will never happen.
11915                    }
11916                }
11917            }
11918        }
11919
11920        if (!app.isolated) {
11921            // XXX Can't keep track of crash times for isolated processes,
11922            // because they don't have a perisistent identity.
11923            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11924        }
11925
11926        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11927        return true;
11928    }
11929
11930    void startAppProblemLocked(ProcessRecord app) {
11931        // If this app is not running under the current user, then we
11932        // can't give it a report button because that would require
11933        // launching the report UI under a different user.
11934        app.errorReportReceiver = null;
11935
11936        for (int userId : mCurrentProfileIds) {
11937            if (app.userId == userId) {
11938                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11939                        mContext, app.info.packageName, app.info.flags);
11940            }
11941        }
11942        skipCurrentReceiverLocked(app);
11943    }
11944
11945    void skipCurrentReceiverLocked(ProcessRecord app) {
11946        for (BroadcastQueue queue : mBroadcastQueues) {
11947            queue.skipCurrentReceiverLocked(app);
11948        }
11949    }
11950
11951    /**
11952     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11953     * The application process will exit immediately after this call returns.
11954     * @param app object of the crashing app, null for the system server
11955     * @param crashInfo describing the exception
11956     */
11957    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11958        ProcessRecord r = findAppProcess(app, "Crash");
11959        final String processName = app == null ? "system_server"
11960                : (r == null ? "unknown" : r.processName);
11961
11962        handleApplicationCrashInner("crash", r, processName, crashInfo);
11963    }
11964
11965    /* Native crash reporting uses this inner version because it needs to be somewhat
11966     * decoupled from the AM-managed cleanup lifecycle
11967     */
11968    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11969            ApplicationErrorReport.CrashInfo crashInfo) {
11970        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11971                UserHandle.getUserId(Binder.getCallingUid()), processName,
11972                r == null ? -1 : r.info.flags,
11973                crashInfo.exceptionClassName,
11974                crashInfo.exceptionMessage,
11975                crashInfo.throwFileName,
11976                crashInfo.throwLineNumber);
11977
11978        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11979
11980        crashApplication(r, crashInfo);
11981    }
11982
11983    public void handleApplicationStrictModeViolation(
11984            IBinder app,
11985            int violationMask,
11986            StrictMode.ViolationInfo info) {
11987        ProcessRecord r = findAppProcess(app, "StrictMode");
11988        if (r == null) {
11989            return;
11990        }
11991
11992        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11993            Integer stackFingerprint = info.hashCode();
11994            boolean logIt = true;
11995            synchronized (mAlreadyLoggedViolatedStacks) {
11996                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11997                    logIt = false;
11998                    // TODO: sub-sample into EventLog for these, with
11999                    // the info.durationMillis?  Then we'd get
12000                    // the relative pain numbers, without logging all
12001                    // the stack traces repeatedly.  We'd want to do
12002                    // likewise in the client code, which also does
12003                    // dup suppression, before the Binder call.
12004                } else {
12005                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12006                        mAlreadyLoggedViolatedStacks.clear();
12007                    }
12008                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12009                }
12010            }
12011            if (logIt) {
12012                logStrictModeViolationToDropBox(r, info);
12013            }
12014        }
12015
12016        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12017            AppErrorResult result = new AppErrorResult();
12018            synchronized (this) {
12019                final long origId = Binder.clearCallingIdentity();
12020
12021                Message msg = Message.obtain();
12022                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12023                HashMap<String, Object> data = new HashMap<String, Object>();
12024                data.put("result", result);
12025                data.put("app", r);
12026                data.put("violationMask", violationMask);
12027                data.put("info", info);
12028                msg.obj = data;
12029                mUiHandler.sendMessage(msg);
12030
12031                Binder.restoreCallingIdentity(origId);
12032            }
12033            int res = result.get();
12034            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12035        }
12036    }
12037
12038    // Depending on the policy in effect, there could be a bunch of
12039    // these in quick succession so we try to batch these together to
12040    // minimize disk writes, number of dropbox entries, and maximize
12041    // compression, by having more fewer, larger records.
12042    private void logStrictModeViolationToDropBox(
12043            ProcessRecord process,
12044            StrictMode.ViolationInfo info) {
12045        if (info == null) {
12046            return;
12047        }
12048        final boolean isSystemApp = process == null ||
12049                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12050                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12051        final String processName = process == null ? "unknown" : process.processName;
12052        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12053        final DropBoxManager dbox = (DropBoxManager)
12054                mContext.getSystemService(Context.DROPBOX_SERVICE);
12055
12056        // Exit early if the dropbox isn't configured to accept this report type.
12057        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12058
12059        boolean bufferWasEmpty;
12060        boolean needsFlush;
12061        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12062        synchronized (sb) {
12063            bufferWasEmpty = sb.length() == 0;
12064            appendDropBoxProcessHeaders(process, processName, sb);
12065            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12066            sb.append("System-App: ").append(isSystemApp).append("\n");
12067            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12068            if (info.violationNumThisLoop != 0) {
12069                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12070            }
12071            if (info.numAnimationsRunning != 0) {
12072                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12073            }
12074            if (info.broadcastIntentAction != null) {
12075                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12076            }
12077            if (info.durationMillis != -1) {
12078                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12079            }
12080            if (info.numInstances != -1) {
12081                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12082            }
12083            if (info.tags != null) {
12084                for (String tag : info.tags) {
12085                    sb.append("Span-Tag: ").append(tag).append("\n");
12086                }
12087            }
12088            sb.append("\n");
12089            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12090                sb.append(info.crashInfo.stackTrace);
12091                sb.append("\n");
12092            }
12093            if (info.message != null) {
12094                sb.append(info.message);
12095                sb.append("\n");
12096            }
12097
12098            // Only buffer up to ~64k.  Various logging bits truncate
12099            // things at 128k.
12100            needsFlush = (sb.length() > 64 * 1024);
12101        }
12102
12103        // Flush immediately if the buffer's grown too large, or this
12104        // is a non-system app.  Non-system apps are isolated with a
12105        // different tag & policy and not batched.
12106        //
12107        // Batching is useful during internal testing with
12108        // StrictMode settings turned up high.  Without batching,
12109        // thousands of separate files could be created on boot.
12110        if (!isSystemApp || needsFlush) {
12111            new Thread("Error dump: " + dropboxTag) {
12112                @Override
12113                public void run() {
12114                    String report;
12115                    synchronized (sb) {
12116                        report = sb.toString();
12117                        sb.delete(0, sb.length());
12118                        sb.trimToSize();
12119                    }
12120                    if (report.length() != 0) {
12121                        dbox.addText(dropboxTag, report);
12122                    }
12123                }
12124            }.start();
12125            return;
12126        }
12127
12128        // System app batching:
12129        if (!bufferWasEmpty) {
12130            // An existing dropbox-writing thread is outstanding, so
12131            // we don't need to start it up.  The existing thread will
12132            // catch the buffer appends we just did.
12133            return;
12134        }
12135
12136        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12137        // (After this point, we shouldn't access AMS internal data structures.)
12138        new Thread("Error dump: " + dropboxTag) {
12139            @Override
12140            public void run() {
12141                // 5 second sleep to let stacks arrive and be batched together
12142                try {
12143                    Thread.sleep(5000);  // 5 seconds
12144                } catch (InterruptedException e) {}
12145
12146                String errorReport;
12147                synchronized (mStrictModeBuffer) {
12148                    errorReport = mStrictModeBuffer.toString();
12149                    if (errorReport.length() == 0) {
12150                        return;
12151                    }
12152                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12153                    mStrictModeBuffer.trimToSize();
12154                }
12155                dbox.addText(dropboxTag, errorReport);
12156            }
12157        }.start();
12158    }
12159
12160    /**
12161     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12162     * @param app object of the crashing app, null for the system server
12163     * @param tag reported by the caller
12164     * @param system whether this wtf is coming from the system
12165     * @param crashInfo describing the context of the error
12166     * @return true if the process should exit immediately (WTF is fatal)
12167     */
12168    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12169            final ApplicationErrorReport.CrashInfo crashInfo) {
12170        final int callingUid = Binder.getCallingUid();
12171        final int callingPid = Binder.getCallingPid();
12172
12173        if (system) {
12174            // If this is coming from the system, we could very well have low-level
12175            // system locks held, so we want to do this all asynchronously.  And we
12176            // never want this to become fatal, so there is that too.
12177            mHandler.post(new Runnable() {
12178                @Override public void run() {
12179                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12180                }
12181            });
12182            return false;
12183        }
12184
12185        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12186                crashInfo);
12187
12188        if (r != null && r.pid != Process.myPid() &&
12189                Settings.Global.getInt(mContext.getContentResolver(),
12190                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12191            crashApplication(r, crashInfo);
12192            return true;
12193        } else {
12194            return false;
12195        }
12196    }
12197
12198    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12199            final ApplicationErrorReport.CrashInfo crashInfo) {
12200        final ProcessRecord r = findAppProcess(app, "WTF");
12201        final String processName = app == null ? "system_server"
12202                : (r == null ? "unknown" : r.processName);
12203
12204        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12205                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12206
12207        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12208
12209        return r;
12210    }
12211
12212    /**
12213     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12214     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12215     */
12216    private ProcessRecord findAppProcess(IBinder app, String reason) {
12217        if (app == null) {
12218            return null;
12219        }
12220
12221        synchronized (this) {
12222            final int NP = mProcessNames.getMap().size();
12223            for (int ip=0; ip<NP; ip++) {
12224                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12225                final int NA = apps.size();
12226                for (int ia=0; ia<NA; ia++) {
12227                    ProcessRecord p = apps.valueAt(ia);
12228                    if (p.thread != null && p.thread.asBinder() == app) {
12229                        return p;
12230                    }
12231                }
12232            }
12233
12234            Slog.w(TAG, "Can't find mystery application for " + reason
12235                    + " from pid=" + Binder.getCallingPid()
12236                    + " uid=" + Binder.getCallingUid() + ": " + app);
12237            return null;
12238        }
12239    }
12240
12241    /**
12242     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12243     * to append various headers to the dropbox log text.
12244     */
12245    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12246            StringBuilder sb) {
12247        // Watchdog thread ends up invoking this function (with
12248        // a null ProcessRecord) to add the stack file to dropbox.
12249        // Do not acquire a lock on this (am) in such cases, as it
12250        // could cause a potential deadlock, if and when watchdog
12251        // is invoked due to unavailability of lock on am and it
12252        // would prevent watchdog from killing system_server.
12253        if (process == null) {
12254            sb.append("Process: ").append(processName).append("\n");
12255            return;
12256        }
12257        // Note: ProcessRecord 'process' is guarded by the service
12258        // instance.  (notably process.pkgList, which could otherwise change
12259        // concurrently during execution of this method)
12260        synchronized (this) {
12261            sb.append("Process: ").append(processName).append("\n");
12262            int flags = process.info.flags;
12263            IPackageManager pm = AppGlobals.getPackageManager();
12264            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12265            for (int ip=0; ip<process.pkgList.size(); ip++) {
12266                String pkg = process.pkgList.keyAt(ip);
12267                sb.append("Package: ").append(pkg);
12268                try {
12269                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12270                    if (pi != null) {
12271                        sb.append(" v").append(pi.versionCode);
12272                        if (pi.versionName != null) {
12273                            sb.append(" (").append(pi.versionName).append(")");
12274                        }
12275                    }
12276                } catch (RemoteException e) {
12277                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12278                }
12279                sb.append("\n");
12280            }
12281        }
12282    }
12283
12284    private static String processClass(ProcessRecord process) {
12285        if (process == null || process.pid == MY_PID) {
12286            return "system_server";
12287        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12288            return "system_app";
12289        } else {
12290            return "data_app";
12291        }
12292    }
12293
12294    /**
12295     * Write a description of an error (crash, WTF, ANR) to the drop box.
12296     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12297     * @param process which caused the error, null means the system server
12298     * @param activity which triggered the error, null if unknown
12299     * @param parent activity related to the error, null if unknown
12300     * @param subject line related to the error, null if absent
12301     * @param report in long form describing the error, null if absent
12302     * @param logFile to include in the report, null if none
12303     * @param crashInfo giving an application stack trace, null if absent
12304     */
12305    public void addErrorToDropBox(String eventType,
12306            ProcessRecord process, String processName, ActivityRecord activity,
12307            ActivityRecord parent, String subject,
12308            final String report, final File logFile,
12309            final ApplicationErrorReport.CrashInfo crashInfo) {
12310        // NOTE -- this must never acquire the ActivityManagerService lock,
12311        // otherwise the watchdog may be prevented from resetting the system.
12312
12313        final String dropboxTag = processClass(process) + "_" + eventType;
12314        final DropBoxManager dbox = (DropBoxManager)
12315                mContext.getSystemService(Context.DROPBOX_SERVICE);
12316
12317        // Exit early if the dropbox isn't configured to accept this report type.
12318        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12319
12320        final StringBuilder sb = new StringBuilder(1024);
12321        appendDropBoxProcessHeaders(process, processName, sb);
12322        if (activity != null) {
12323            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12324        }
12325        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12326            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12327        }
12328        if (parent != null && parent != activity) {
12329            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12330        }
12331        if (subject != null) {
12332            sb.append("Subject: ").append(subject).append("\n");
12333        }
12334        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12335        if (Debug.isDebuggerConnected()) {
12336            sb.append("Debugger: Connected\n");
12337        }
12338        sb.append("\n");
12339
12340        // Do the rest in a worker thread to avoid blocking the caller on I/O
12341        // (After this point, we shouldn't access AMS internal data structures.)
12342        Thread worker = new Thread("Error dump: " + dropboxTag) {
12343            @Override
12344            public void run() {
12345                if (report != null) {
12346                    sb.append(report);
12347                }
12348                if (logFile != null) {
12349                    try {
12350                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12351                                    "\n\n[[TRUNCATED]]"));
12352                    } catch (IOException e) {
12353                        Slog.e(TAG, "Error reading " + logFile, e);
12354                    }
12355                }
12356                if (crashInfo != null && crashInfo.stackTrace != null) {
12357                    sb.append(crashInfo.stackTrace);
12358                }
12359
12360                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12361                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12362                if (lines > 0) {
12363                    sb.append("\n");
12364
12365                    // Merge several logcat streams, and take the last N lines
12366                    InputStreamReader input = null;
12367                    try {
12368                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12369                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12370                                "-b", "crash",
12371                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12372
12373                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12374                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12375                        input = new InputStreamReader(logcat.getInputStream());
12376
12377                        int num;
12378                        char[] buf = new char[8192];
12379                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12380                    } catch (IOException e) {
12381                        Slog.e(TAG, "Error running logcat", e);
12382                    } finally {
12383                        if (input != null) try { input.close(); } catch (IOException e) {}
12384                    }
12385                }
12386
12387                dbox.addText(dropboxTag, sb.toString());
12388            }
12389        };
12390
12391        if (process == null) {
12392            // If process is null, we are being called from some internal code
12393            // and may be about to die -- run this synchronously.
12394            worker.run();
12395        } else {
12396            worker.start();
12397        }
12398    }
12399
12400    /**
12401     * Bring up the "unexpected error" dialog box for a crashing app.
12402     * Deal with edge cases (intercepts from instrumented applications,
12403     * ActivityController, error intent receivers, that sort of thing).
12404     * @param r the application crashing
12405     * @param crashInfo describing the failure
12406     */
12407    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12408        long timeMillis = System.currentTimeMillis();
12409        String shortMsg = crashInfo.exceptionClassName;
12410        String longMsg = crashInfo.exceptionMessage;
12411        String stackTrace = crashInfo.stackTrace;
12412        if (shortMsg != null && longMsg != null) {
12413            longMsg = shortMsg + ": " + longMsg;
12414        } else if (shortMsg != null) {
12415            longMsg = shortMsg;
12416        }
12417
12418        AppErrorResult result = new AppErrorResult();
12419        synchronized (this) {
12420            if (mController != null) {
12421                try {
12422                    String name = r != null ? r.processName : null;
12423                    int pid = r != null ? r.pid : Binder.getCallingPid();
12424                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12425                    if (!mController.appCrashed(name, pid,
12426                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12427                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12428                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12429                            Slog.w(TAG, "Skip killing native crashed app " + name
12430                                    + "(" + pid + ") during testing");
12431                        } else {
12432                            Slog.w(TAG, "Force-killing crashed app " + name
12433                                    + " at watcher's request");
12434                            if (r != null) {
12435                                r.kill("crash", true);
12436                            } else {
12437                                // Huh.
12438                                Process.killProcess(pid);
12439                                killProcessGroup(uid, pid);
12440                            }
12441                        }
12442                        return;
12443                    }
12444                } catch (RemoteException e) {
12445                    mController = null;
12446                    Watchdog.getInstance().setActivityController(null);
12447                }
12448            }
12449
12450            final long origId = Binder.clearCallingIdentity();
12451
12452            // If this process is running instrumentation, finish it.
12453            if (r != null && r.instrumentationClass != null) {
12454                Slog.w(TAG, "Error in app " + r.processName
12455                      + " running instrumentation " + r.instrumentationClass + ":");
12456                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12457                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12458                Bundle info = new Bundle();
12459                info.putString("shortMsg", shortMsg);
12460                info.putString("longMsg", longMsg);
12461                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12462                Binder.restoreCallingIdentity(origId);
12463                return;
12464            }
12465
12466            // Log crash in battery stats.
12467            if (r != null) {
12468                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12469            }
12470
12471            // If we can't identify the process or it's already exceeded its crash quota,
12472            // quit right away without showing a crash dialog.
12473            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12474                Binder.restoreCallingIdentity(origId);
12475                return;
12476            }
12477
12478            Message msg = Message.obtain();
12479            msg.what = SHOW_ERROR_MSG;
12480            HashMap data = new HashMap();
12481            data.put("result", result);
12482            data.put("app", r);
12483            msg.obj = data;
12484            mUiHandler.sendMessage(msg);
12485
12486            Binder.restoreCallingIdentity(origId);
12487        }
12488
12489        int res = result.get();
12490
12491        Intent appErrorIntent = null;
12492        synchronized (this) {
12493            if (r != null && !r.isolated) {
12494                // XXX Can't keep track of crash time for isolated processes,
12495                // since they don't have a persistent identity.
12496                mProcessCrashTimes.put(r.info.processName, r.uid,
12497                        SystemClock.uptimeMillis());
12498            }
12499            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12500                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12501            }
12502        }
12503
12504        if (appErrorIntent != null) {
12505            try {
12506                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12507            } catch (ActivityNotFoundException e) {
12508                Slog.w(TAG, "bug report receiver dissappeared", e);
12509            }
12510        }
12511    }
12512
12513    Intent createAppErrorIntentLocked(ProcessRecord r,
12514            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12515        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12516        if (report == null) {
12517            return null;
12518        }
12519        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12520        result.setComponent(r.errorReportReceiver);
12521        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12522        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12523        return result;
12524    }
12525
12526    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12527            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12528        if (r.errorReportReceiver == null) {
12529            return null;
12530        }
12531
12532        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12533            return null;
12534        }
12535
12536        ApplicationErrorReport report = new ApplicationErrorReport();
12537        report.packageName = r.info.packageName;
12538        report.installerPackageName = r.errorReportReceiver.getPackageName();
12539        report.processName = r.processName;
12540        report.time = timeMillis;
12541        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12542
12543        if (r.crashing || r.forceCrashReport) {
12544            report.type = ApplicationErrorReport.TYPE_CRASH;
12545            report.crashInfo = crashInfo;
12546        } else if (r.notResponding) {
12547            report.type = ApplicationErrorReport.TYPE_ANR;
12548            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12549
12550            report.anrInfo.activity = r.notRespondingReport.tag;
12551            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12552            report.anrInfo.info = r.notRespondingReport.longMsg;
12553        }
12554
12555        return report;
12556    }
12557
12558    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12559        enforceNotIsolatedCaller("getProcessesInErrorState");
12560        // assume our apps are happy - lazy create the list
12561        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12562
12563        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12564                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12565        int userId = UserHandle.getUserId(Binder.getCallingUid());
12566
12567        synchronized (this) {
12568
12569            // iterate across all processes
12570            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12571                ProcessRecord app = mLruProcesses.get(i);
12572                if (!allUsers && app.userId != userId) {
12573                    continue;
12574                }
12575                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12576                    // This one's in trouble, so we'll generate a report for it
12577                    // crashes are higher priority (in case there's a crash *and* an anr)
12578                    ActivityManager.ProcessErrorStateInfo report = null;
12579                    if (app.crashing) {
12580                        report = app.crashingReport;
12581                    } else if (app.notResponding) {
12582                        report = app.notRespondingReport;
12583                    }
12584
12585                    if (report != null) {
12586                        if (errList == null) {
12587                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12588                        }
12589                        errList.add(report);
12590                    } else {
12591                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12592                                " crashing = " + app.crashing +
12593                                " notResponding = " + app.notResponding);
12594                    }
12595                }
12596            }
12597        }
12598
12599        return errList;
12600    }
12601
12602    static int procStateToImportance(int procState, int memAdj,
12603            ActivityManager.RunningAppProcessInfo currApp) {
12604        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12605        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12606            currApp.lru = memAdj;
12607        } else {
12608            currApp.lru = 0;
12609        }
12610        return imp;
12611    }
12612
12613    private void fillInProcMemInfo(ProcessRecord app,
12614            ActivityManager.RunningAppProcessInfo outInfo) {
12615        outInfo.pid = app.pid;
12616        outInfo.uid = app.info.uid;
12617        if (mHeavyWeightProcess == app) {
12618            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12619        }
12620        if (app.persistent) {
12621            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12622        }
12623        if (app.activities.size() > 0) {
12624            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12625        }
12626        outInfo.lastTrimLevel = app.trimMemoryLevel;
12627        int adj = app.curAdj;
12628        int procState = app.curProcState;
12629        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12630        outInfo.importanceReasonCode = app.adjTypeCode;
12631        outInfo.processState = app.curProcState;
12632    }
12633
12634    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12635        enforceNotIsolatedCaller("getRunningAppProcesses");
12636
12637        final int callingUid = Binder.getCallingUid();
12638
12639        // Lazy instantiation of list
12640        List<ActivityManager.RunningAppProcessInfo> runList = null;
12641        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12642                callingUid) == PackageManager.PERMISSION_GRANTED;
12643        final int userId = UserHandle.getUserId(callingUid);
12644        final boolean allUids = isGetTasksAllowed(
12645                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12646
12647        synchronized (this) {
12648            // Iterate across all processes
12649            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12650                ProcessRecord app = mLruProcesses.get(i);
12651                if ((!allUsers && app.userId != userId)
12652                        || (!allUids && app.uid != callingUid)) {
12653                    continue;
12654                }
12655                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12656                    // Generate process state info for running application
12657                    ActivityManager.RunningAppProcessInfo currApp =
12658                        new ActivityManager.RunningAppProcessInfo(app.processName,
12659                                app.pid, app.getPackageList());
12660                    fillInProcMemInfo(app, currApp);
12661                    if (app.adjSource instanceof ProcessRecord) {
12662                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12663                        currApp.importanceReasonImportance =
12664                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12665                                        app.adjSourceProcState);
12666                    } else if (app.adjSource instanceof ActivityRecord) {
12667                        ActivityRecord r = (ActivityRecord)app.adjSource;
12668                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12669                    }
12670                    if (app.adjTarget instanceof ComponentName) {
12671                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12672                    }
12673                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12674                    //        + " lru=" + currApp.lru);
12675                    if (runList == null) {
12676                        runList = new ArrayList<>();
12677                    }
12678                    runList.add(currApp);
12679                }
12680            }
12681        }
12682        return runList;
12683    }
12684
12685    public List<ApplicationInfo> getRunningExternalApplications() {
12686        enforceNotIsolatedCaller("getRunningExternalApplications");
12687        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12688        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12689        if (runningApps != null && runningApps.size() > 0) {
12690            Set<String> extList = new HashSet<String>();
12691            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12692                if (app.pkgList != null) {
12693                    for (String pkg : app.pkgList) {
12694                        extList.add(pkg);
12695                    }
12696                }
12697            }
12698            IPackageManager pm = AppGlobals.getPackageManager();
12699            for (String pkg : extList) {
12700                try {
12701                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12702                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12703                        retList.add(info);
12704                    }
12705                } catch (RemoteException e) {
12706                }
12707            }
12708        }
12709        return retList;
12710    }
12711
12712    @Override
12713    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12714        enforceNotIsolatedCaller("getMyMemoryState");
12715        synchronized (this) {
12716            ProcessRecord proc;
12717            synchronized (mPidsSelfLocked) {
12718                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12719            }
12720            fillInProcMemInfo(proc, outInfo);
12721        }
12722    }
12723
12724    @Override
12725    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12726        if (checkCallingPermission(android.Manifest.permission.DUMP)
12727                != PackageManager.PERMISSION_GRANTED) {
12728            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12729                    + Binder.getCallingPid()
12730                    + ", uid=" + Binder.getCallingUid()
12731                    + " without permission "
12732                    + android.Manifest.permission.DUMP);
12733            return;
12734        }
12735
12736        boolean dumpAll = false;
12737        boolean dumpClient = false;
12738        String dumpPackage = null;
12739
12740        int opti = 0;
12741        while (opti < args.length) {
12742            String opt = args[opti];
12743            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12744                break;
12745            }
12746            opti++;
12747            if ("-a".equals(opt)) {
12748                dumpAll = true;
12749            } else if ("-c".equals(opt)) {
12750                dumpClient = true;
12751            } else if ("-p".equals(opt)) {
12752                if (opti < args.length) {
12753                    dumpPackage = args[opti];
12754                    opti++;
12755                } else {
12756                    pw.println("Error: -p option requires package argument");
12757                    return;
12758                }
12759                dumpClient = true;
12760            } else if ("-h".equals(opt)) {
12761                pw.println("Activity manager dump options:");
12762                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12763                pw.println("  cmd may be one of:");
12764                pw.println("    a[ctivities]: activity stack state");
12765                pw.println("    r[recents]: recent activities state");
12766                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12767                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12768                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12769                pw.println("    o[om]: out of memory management");
12770                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12771                pw.println("    provider [COMP_SPEC]: provider client-side state");
12772                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12773                pw.println("    as[sociations]: tracked app associations");
12774                pw.println("    service [COMP_SPEC]: service client-side state");
12775                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12776                pw.println("    all: dump all activities");
12777                pw.println("    top: dump the top activity");
12778                pw.println("    write: write all pending state to storage");
12779                pw.println("    track-associations: enable association tracking");
12780                pw.println("    untrack-associations: disable and clear association tracking");
12781                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12782                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12783                pw.println("    a partial substring in a component name, a");
12784                pw.println("    hex object identifier.");
12785                pw.println("  -a: include all available server state.");
12786                pw.println("  -c: include client state.");
12787                pw.println("  -p: limit output to given package.");
12788                return;
12789            } else {
12790                pw.println("Unknown argument: " + opt + "; use -h for help");
12791            }
12792        }
12793
12794        long origId = Binder.clearCallingIdentity();
12795        boolean more = false;
12796        // Is the caller requesting to dump a particular piece of data?
12797        if (opti < args.length) {
12798            String cmd = args[opti];
12799            opti++;
12800            if ("activities".equals(cmd) || "a".equals(cmd)) {
12801                synchronized (this) {
12802                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12803                }
12804            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12805                synchronized (this) {
12806                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12807                }
12808            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12809                String[] newArgs;
12810                String name;
12811                if (opti >= args.length) {
12812                    name = null;
12813                    newArgs = EMPTY_STRING_ARRAY;
12814                } else {
12815                    dumpPackage = args[opti];
12816                    opti++;
12817                    newArgs = new String[args.length - opti];
12818                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12819                            args.length - opti);
12820                }
12821                synchronized (this) {
12822                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12823                }
12824            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12825                String[] newArgs;
12826                String name;
12827                if (opti >= args.length) {
12828                    name = null;
12829                    newArgs = EMPTY_STRING_ARRAY;
12830                } else {
12831                    dumpPackage = args[opti];
12832                    opti++;
12833                    newArgs = new String[args.length - opti];
12834                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12835                            args.length - opti);
12836                }
12837                synchronized (this) {
12838                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12839                }
12840            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12841                String[] newArgs;
12842                String name;
12843                if (opti >= args.length) {
12844                    name = null;
12845                    newArgs = EMPTY_STRING_ARRAY;
12846                } else {
12847                    dumpPackage = args[opti];
12848                    opti++;
12849                    newArgs = new String[args.length - opti];
12850                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12851                            args.length - opti);
12852                }
12853                synchronized (this) {
12854                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12855                }
12856            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12857                synchronized (this) {
12858                    dumpOomLocked(fd, pw, args, opti, true);
12859                }
12860            } else if ("provider".equals(cmd)) {
12861                String[] newArgs;
12862                String name;
12863                if (opti >= args.length) {
12864                    name = null;
12865                    newArgs = EMPTY_STRING_ARRAY;
12866                } else {
12867                    name = args[opti];
12868                    opti++;
12869                    newArgs = new String[args.length - opti];
12870                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12871                }
12872                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12873                    pw.println("No providers match: " + name);
12874                    pw.println("Use -h for help.");
12875                }
12876            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12877                synchronized (this) {
12878                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12879                }
12880            } else if ("service".equals(cmd)) {
12881                String[] newArgs;
12882                String name;
12883                if (opti >= args.length) {
12884                    name = null;
12885                    newArgs = EMPTY_STRING_ARRAY;
12886                } else {
12887                    name = args[opti];
12888                    opti++;
12889                    newArgs = new String[args.length - opti];
12890                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12891                            args.length - opti);
12892                }
12893                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12894                    pw.println("No services match: " + name);
12895                    pw.println("Use -h for help.");
12896                }
12897            } else if ("package".equals(cmd)) {
12898                String[] newArgs;
12899                if (opti >= args.length) {
12900                    pw.println("package: no package name specified");
12901                    pw.println("Use -h for help.");
12902                } else {
12903                    dumpPackage = args[opti];
12904                    opti++;
12905                    newArgs = new String[args.length - opti];
12906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12907                            args.length - opti);
12908                    args = newArgs;
12909                    opti = 0;
12910                    more = true;
12911                }
12912            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12913                synchronized (this) {
12914                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12915                }
12916            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12917                synchronized (this) {
12918                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12919                }
12920            } else if ("write".equals(cmd)) {
12921                mTaskPersister.flush();
12922                pw.println("All tasks persisted.");
12923                return;
12924            } else if ("track-associations".equals(cmd)) {
12925                synchronized (this) {
12926                    if (!mTrackingAssociations) {
12927                        mTrackingAssociations = true;
12928                        pw.println("Association tracking started.");
12929                    } else {
12930                        pw.println("Association tracking already enabled.");
12931                    }
12932                }
12933                return;
12934            } else if ("untrack-associations".equals(cmd)) {
12935                synchronized (this) {
12936                    if (mTrackingAssociations) {
12937                        mTrackingAssociations = false;
12938                        mAssociations.clear();
12939                        pw.println("Association tracking stopped.");
12940                    } else {
12941                        pw.println("Association tracking not running.");
12942                    }
12943                }
12944                return;
12945            } else {
12946                // Dumping a single activity?
12947                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12948                    pw.println("Bad activity command, or no activities match: " + cmd);
12949                    pw.println("Use -h for help.");
12950                }
12951            }
12952            if (!more) {
12953                Binder.restoreCallingIdentity(origId);
12954                return;
12955            }
12956        }
12957
12958        // No piece of data specified, dump everything.
12959        synchronized (this) {
12960            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12961            pw.println();
12962            if (dumpAll) {
12963                pw.println("-------------------------------------------------------------------------------");
12964            }
12965            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12966            pw.println();
12967            if (dumpAll) {
12968                pw.println("-------------------------------------------------------------------------------");
12969            }
12970            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12971            pw.println();
12972            if (dumpAll) {
12973                pw.println("-------------------------------------------------------------------------------");
12974            }
12975            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12976            pw.println();
12977            if (dumpAll) {
12978                pw.println("-------------------------------------------------------------------------------");
12979            }
12980            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12981            pw.println();
12982            if (dumpAll) {
12983                pw.println("-------------------------------------------------------------------------------");
12984            }
12985            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12986            if (mAssociations.size() > 0) {
12987                pw.println();
12988                if (dumpAll) {
12989                    pw.println("-------------------------------------------------------------------------------");
12990                }
12991                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12992            }
12993            pw.println();
12994            if (dumpAll) {
12995                pw.println("-------------------------------------------------------------------------------");
12996            }
12997            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12998        }
12999        Binder.restoreCallingIdentity(origId);
13000    }
13001
13002    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13003            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13004        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13005
13006        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13007                dumpPackage);
13008        boolean needSep = printedAnything;
13009
13010        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13011                dumpPackage, needSep, "  mFocusedActivity: ");
13012        if (printed) {
13013            printedAnything = true;
13014            needSep = false;
13015        }
13016
13017        if (dumpPackage == null) {
13018            if (needSep) {
13019                pw.println();
13020            }
13021            needSep = true;
13022            printedAnything = true;
13023            mStackSupervisor.dump(pw, "  ");
13024        }
13025
13026        if (!printedAnything) {
13027            pw.println("  (nothing)");
13028        }
13029    }
13030
13031    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13032            int opti, boolean dumpAll, String dumpPackage) {
13033        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13034
13035        boolean printedAnything = false;
13036
13037        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13038            boolean printedHeader = false;
13039
13040            final int N = mRecentTasks.size();
13041            for (int i=0; i<N; i++) {
13042                TaskRecord tr = mRecentTasks.get(i);
13043                if (dumpPackage != null) {
13044                    if (tr.realActivity == null ||
13045                            !dumpPackage.equals(tr.realActivity)) {
13046                        continue;
13047                    }
13048                }
13049                if (!printedHeader) {
13050                    pw.println("  Recent tasks:");
13051                    printedHeader = true;
13052                    printedAnything = true;
13053                }
13054                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13055                        pw.println(tr);
13056                if (dumpAll) {
13057                    mRecentTasks.get(i).dump(pw, "    ");
13058                }
13059            }
13060        }
13061
13062        if (!printedAnything) {
13063            pw.println("  (nothing)");
13064        }
13065    }
13066
13067    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13068            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13069        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13070
13071        int dumpUid = 0;
13072        if (dumpPackage != null) {
13073            IPackageManager pm = AppGlobals.getPackageManager();
13074            try {
13075                dumpUid = pm.getPackageUid(dumpPackage, 0);
13076            } catch (RemoteException e) {
13077            }
13078        }
13079
13080        boolean printedAnything = false;
13081
13082        final long now = SystemClock.uptimeMillis();
13083
13084        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13085            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13086                    = mAssociations.valueAt(i1);
13087            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13088                SparseArray<ArrayMap<String, Association>> sourceUids
13089                        = targetComponents.valueAt(i2);
13090                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13091                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13092                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13093                        Association ass = sourceProcesses.valueAt(i4);
13094                        if (dumpPackage != null) {
13095                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13096                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13097                                continue;
13098                            }
13099                        }
13100                        printedAnything = true;
13101                        pw.print("  ");
13102                        pw.print(ass.mTargetProcess);
13103                        pw.print("/");
13104                        UserHandle.formatUid(pw, ass.mTargetUid);
13105                        pw.print(" <- ");
13106                        pw.print(ass.mSourceProcess);
13107                        pw.print("/");
13108                        UserHandle.formatUid(pw, ass.mSourceUid);
13109                        pw.println();
13110                        pw.print("    via ");
13111                        pw.print(ass.mTargetComponent.flattenToShortString());
13112                        pw.println();
13113                        pw.print("    ");
13114                        long dur = ass.mTime;
13115                        if (ass.mNesting > 0) {
13116                            dur += now - ass.mStartTime;
13117                        }
13118                        TimeUtils.formatDuration(dur, pw);
13119                        pw.print(" (");
13120                        pw.print(ass.mCount);
13121                        pw.println(" times)");
13122                        if (ass.mNesting > 0) {
13123                            pw.print("    ");
13124                            pw.print(" Currently active: ");
13125                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13126                            pw.println();
13127                        }
13128                    }
13129                }
13130            }
13131
13132        }
13133
13134        if (!printedAnything) {
13135            pw.println("  (nothing)");
13136        }
13137    }
13138
13139    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13140            int opti, boolean dumpAll, String dumpPackage) {
13141        boolean needSep = false;
13142        boolean printedAnything = false;
13143        int numPers = 0;
13144
13145        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13146
13147        if (dumpAll) {
13148            final int NP = mProcessNames.getMap().size();
13149            for (int ip=0; ip<NP; ip++) {
13150                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13151                final int NA = procs.size();
13152                for (int ia=0; ia<NA; ia++) {
13153                    ProcessRecord r = procs.valueAt(ia);
13154                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13155                        continue;
13156                    }
13157                    if (!needSep) {
13158                        pw.println("  All known processes:");
13159                        needSep = true;
13160                        printedAnything = true;
13161                    }
13162                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13163                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13164                        pw.print(" "); pw.println(r);
13165                    r.dump(pw, "    ");
13166                    if (r.persistent) {
13167                        numPers++;
13168                    }
13169                }
13170            }
13171        }
13172
13173        if (mIsolatedProcesses.size() > 0) {
13174            boolean printed = false;
13175            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13176                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13177                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13178                    continue;
13179                }
13180                if (!printed) {
13181                    if (needSep) {
13182                        pw.println();
13183                    }
13184                    pw.println("  Isolated process list (sorted by uid):");
13185                    printedAnything = true;
13186                    printed = true;
13187                    needSep = true;
13188                }
13189                pw.println(String.format("%sIsolated #%2d: %s",
13190                        "    ", i, r.toString()));
13191            }
13192        }
13193
13194        if (mActiveUids.size() > 0) {
13195            if (needSep) {
13196                pw.println();
13197            }
13198            pw.println("  UID states:");
13199            for (int i=0; i<mActiveUids.size(); i++) {
13200                UidRecord uidRec = mActiveUids.valueAt(i);
13201                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13202                pw.print(": "); pw.println(uidRec);
13203            }
13204            needSep = true;
13205            printedAnything = true;
13206        }
13207
13208        if (mLruProcesses.size() > 0) {
13209            if (needSep) {
13210                pw.println();
13211            }
13212            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13213                    pw.print(" total, non-act at ");
13214                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13215                    pw.print(", non-svc at ");
13216                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13217                    pw.println("):");
13218            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13219            needSep = true;
13220            printedAnything = true;
13221        }
13222
13223        if (dumpAll || dumpPackage != null) {
13224            synchronized (mPidsSelfLocked) {
13225                boolean printed = false;
13226                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13227                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13228                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13229                        continue;
13230                    }
13231                    if (!printed) {
13232                        if (needSep) pw.println();
13233                        needSep = true;
13234                        pw.println("  PID mappings:");
13235                        printed = true;
13236                        printedAnything = true;
13237                    }
13238                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13239                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13240                }
13241            }
13242        }
13243
13244        if (mForegroundProcesses.size() > 0) {
13245            synchronized (mPidsSelfLocked) {
13246                boolean printed = false;
13247                for (int i=0; i<mForegroundProcesses.size(); i++) {
13248                    ProcessRecord r = mPidsSelfLocked.get(
13249                            mForegroundProcesses.valueAt(i).pid);
13250                    if (dumpPackage != null && (r == null
13251                            || !r.pkgList.containsKey(dumpPackage))) {
13252                        continue;
13253                    }
13254                    if (!printed) {
13255                        if (needSep) pw.println();
13256                        needSep = true;
13257                        pw.println("  Foreground Processes:");
13258                        printed = true;
13259                        printedAnything = true;
13260                    }
13261                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13262                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13263                }
13264            }
13265        }
13266
13267        if (mPersistentStartingProcesses.size() > 0) {
13268            if (needSep) pw.println();
13269            needSep = true;
13270            printedAnything = true;
13271            pw.println("  Persisent processes that are starting:");
13272            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13273                    "Starting Norm", "Restarting PERS", dumpPackage);
13274        }
13275
13276        if (mRemovedProcesses.size() > 0) {
13277            if (needSep) pw.println();
13278            needSep = true;
13279            printedAnything = true;
13280            pw.println("  Processes that are being removed:");
13281            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13282                    "Removed Norm", "Removed PERS", dumpPackage);
13283        }
13284
13285        if (mProcessesOnHold.size() > 0) {
13286            if (needSep) pw.println();
13287            needSep = true;
13288            printedAnything = true;
13289            pw.println("  Processes that are on old until the system is ready:");
13290            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13291                    "OnHold Norm", "OnHold PERS", dumpPackage);
13292        }
13293
13294        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13295
13296        if (mProcessCrashTimes.getMap().size() > 0) {
13297            boolean printed = false;
13298            long now = SystemClock.uptimeMillis();
13299            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13300            final int NP = pmap.size();
13301            for (int ip=0; ip<NP; ip++) {
13302                String pname = pmap.keyAt(ip);
13303                SparseArray<Long> uids = pmap.valueAt(ip);
13304                final int N = uids.size();
13305                for (int i=0; i<N; i++) {
13306                    int puid = uids.keyAt(i);
13307                    ProcessRecord r = mProcessNames.get(pname, puid);
13308                    if (dumpPackage != null && (r == null
13309                            || !r.pkgList.containsKey(dumpPackage))) {
13310                        continue;
13311                    }
13312                    if (!printed) {
13313                        if (needSep) pw.println();
13314                        needSep = true;
13315                        pw.println("  Time since processes crashed:");
13316                        printed = true;
13317                        printedAnything = true;
13318                    }
13319                    pw.print("    Process "); pw.print(pname);
13320                            pw.print(" uid "); pw.print(puid);
13321                            pw.print(": last crashed ");
13322                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13323                            pw.println(" ago");
13324                }
13325            }
13326        }
13327
13328        if (mBadProcesses.getMap().size() > 0) {
13329            boolean printed = false;
13330            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13331            final int NP = pmap.size();
13332            for (int ip=0; ip<NP; ip++) {
13333                String pname = pmap.keyAt(ip);
13334                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13335                final int N = uids.size();
13336                for (int i=0; i<N; i++) {
13337                    int puid = uids.keyAt(i);
13338                    ProcessRecord r = mProcessNames.get(pname, puid);
13339                    if (dumpPackage != null && (r == null
13340                            || !r.pkgList.containsKey(dumpPackage))) {
13341                        continue;
13342                    }
13343                    if (!printed) {
13344                        if (needSep) pw.println();
13345                        needSep = true;
13346                        pw.println("  Bad processes:");
13347                        printedAnything = true;
13348                    }
13349                    BadProcessInfo info = uids.valueAt(i);
13350                    pw.print("    Bad process "); pw.print(pname);
13351                            pw.print(" uid "); pw.print(puid);
13352                            pw.print(": crashed at time "); pw.println(info.time);
13353                    if (info.shortMsg != null) {
13354                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13355                    }
13356                    if (info.longMsg != null) {
13357                        pw.print("      Long msg: "); pw.println(info.longMsg);
13358                    }
13359                    if (info.stack != null) {
13360                        pw.println("      Stack:");
13361                        int lastPos = 0;
13362                        for (int pos=0; pos<info.stack.length(); pos++) {
13363                            if (info.stack.charAt(pos) == '\n') {
13364                                pw.print("        ");
13365                                pw.write(info.stack, lastPos, pos-lastPos);
13366                                pw.println();
13367                                lastPos = pos+1;
13368                            }
13369                        }
13370                        if (lastPos < info.stack.length()) {
13371                            pw.print("        ");
13372                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13373                            pw.println();
13374                        }
13375                    }
13376                }
13377            }
13378        }
13379
13380        if (dumpPackage == null) {
13381            pw.println();
13382            needSep = false;
13383            pw.println("  mStartedUsers:");
13384            for (int i=0; i<mStartedUsers.size(); i++) {
13385                UserState uss = mStartedUsers.valueAt(i);
13386                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13387                        pw.print(": "); uss.dump("", pw);
13388            }
13389            pw.print("  mStartedUserArray: [");
13390            for (int i=0; i<mStartedUserArray.length; i++) {
13391                if (i > 0) pw.print(", ");
13392                pw.print(mStartedUserArray[i]);
13393            }
13394            pw.println("]");
13395            pw.print("  mUserLru: [");
13396            for (int i=0; i<mUserLru.size(); i++) {
13397                if (i > 0) pw.print(", ");
13398                pw.print(mUserLru.get(i));
13399            }
13400            pw.println("]");
13401            if (dumpAll) {
13402                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13403            }
13404            synchronized (mUserProfileGroupIdsSelfLocked) {
13405                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13406                    pw.println("  mUserProfileGroupIds:");
13407                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13408                        pw.print("    User #");
13409                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13410                        pw.print(" -> profile #");
13411                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13412                    }
13413                }
13414            }
13415        }
13416        if (mHomeProcess != null && (dumpPackage == null
13417                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13418            if (needSep) {
13419                pw.println();
13420                needSep = false;
13421            }
13422            pw.println("  mHomeProcess: " + mHomeProcess);
13423        }
13424        if (mPreviousProcess != null && (dumpPackage == null
13425                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13426            if (needSep) {
13427                pw.println();
13428                needSep = false;
13429            }
13430            pw.println("  mPreviousProcess: " + mPreviousProcess);
13431        }
13432        if (dumpAll) {
13433            StringBuilder sb = new StringBuilder(128);
13434            sb.append("  mPreviousProcessVisibleTime: ");
13435            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13436            pw.println(sb);
13437        }
13438        if (mHeavyWeightProcess != null && (dumpPackage == null
13439                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13440            if (needSep) {
13441                pw.println();
13442                needSep = false;
13443            }
13444            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13445        }
13446        if (dumpPackage == null) {
13447            pw.println("  mConfiguration: " + mConfiguration);
13448        }
13449        if (dumpAll) {
13450            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13451            if (mCompatModePackages.getPackages().size() > 0) {
13452                boolean printed = false;
13453                for (Map.Entry<String, Integer> entry
13454                        : mCompatModePackages.getPackages().entrySet()) {
13455                    String pkg = entry.getKey();
13456                    int mode = entry.getValue();
13457                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13458                        continue;
13459                    }
13460                    if (!printed) {
13461                        pw.println("  mScreenCompatPackages:");
13462                        printed = true;
13463                    }
13464                    pw.print("    "); pw.print(pkg); pw.print(": ");
13465                            pw.print(mode); pw.println();
13466                }
13467            }
13468        }
13469        if (dumpPackage == null) {
13470            pw.println("  mWakefulness="
13471                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13472            pw.println("  mSleepTokens=" + mSleepTokens);
13473            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13474                    + lockScreenShownToString());
13475            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13476            if (mRunningVoice != null) {
13477                pw.println("  mRunningVoice=" + mRunningVoice);
13478                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13479            }
13480        }
13481        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13482                || mOrigWaitForDebugger) {
13483            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13484                    || dumpPackage.equals(mOrigDebugApp)) {
13485                if (needSep) {
13486                    pw.println();
13487                    needSep = false;
13488                }
13489                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13490                        + " mDebugTransient=" + mDebugTransient
13491                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13492            }
13493        }
13494        if (mCurAppTimeTracker != null) {
13495            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13496        }
13497        if (mMemWatchProcesses.getMap().size() > 0) {
13498            pw.println("  Mem watch processes:");
13499            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13500                    = mMemWatchProcesses.getMap();
13501            for (int i=0; i<procs.size(); i++) {
13502                final String proc = procs.keyAt(i);
13503                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13504                for (int j=0; j<uids.size(); j++) {
13505                    if (needSep) {
13506                        pw.println();
13507                        needSep = false;
13508                    }
13509                    StringBuilder sb = new StringBuilder();
13510                    sb.append("    ").append(proc).append('/');
13511                    UserHandle.formatUid(sb, uids.keyAt(j));
13512                    Pair<Long, String> val = uids.valueAt(j);
13513                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13514                    if (val.second != null) {
13515                        sb.append(", report to ").append(val.second);
13516                    }
13517                    pw.println(sb.toString());
13518                }
13519            }
13520            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13521            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13522            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13523                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13524        }
13525        if (mOpenGlTraceApp != null) {
13526            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13527                if (needSep) {
13528                    pw.println();
13529                    needSep = false;
13530                }
13531                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13532            }
13533        }
13534        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13535                || mProfileFd != null) {
13536            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13537                if (needSep) {
13538                    pw.println();
13539                    needSep = false;
13540                }
13541                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13542                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13543                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13544                        + mAutoStopProfiler);
13545                pw.println("  mProfileType=" + mProfileType);
13546            }
13547        }
13548        if (dumpPackage == null) {
13549            if (mAlwaysFinishActivities || mController != null) {
13550                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13551                        + " mController=" + mController);
13552            }
13553            if (dumpAll) {
13554                pw.println("  Total persistent processes: " + numPers);
13555                pw.println("  mProcessesReady=" + mProcessesReady
13556                        + " mSystemReady=" + mSystemReady
13557                        + " mBooted=" + mBooted
13558                        + " mFactoryTest=" + mFactoryTest);
13559                pw.println("  mBooting=" + mBooting
13560                        + " mCallFinishBooting=" + mCallFinishBooting
13561                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13562                pw.print("  mLastPowerCheckRealtime=");
13563                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13564                        pw.println("");
13565                pw.print("  mLastPowerCheckUptime=");
13566                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13567                        pw.println("");
13568                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13569                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13570                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13571                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13572                        + " (" + mLruProcesses.size() + " total)"
13573                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13574                        + " mNumServiceProcs=" + mNumServiceProcs
13575                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13576                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13577                        + " mLastMemoryLevel" + mLastMemoryLevel
13578                        + " mLastNumProcesses" + mLastNumProcesses);
13579                long now = SystemClock.uptimeMillis();
13580                pw.print("  mLastIdleTime=");
13581                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13582                        pw.print(" mLowRamSinceLastIdle=");
13583                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13584                        pw.println();
13585            }
13586        }
13587
13588        if (!printedAnything) {
13589            pw.println("  (nothing)");
13590        }
13591    }
13592
13593    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13594            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13595        if (mProcessesToGc.size() > 0) {
13596            boolean printed = false;
13597            long now = SystemClock.uptimeMillis();
13598            for (int i=0; i<mProcessesToGc.size(); i++) {
13599                ProcessRecord proc = mProcessesToGc.get(i);
13600                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13601                    continue;
13602                }
13603                if (!printed) {
13604                    if (needSep) pw.println();
13605                    needSep = true;
13606                    pw.println("  Processes that are waiting to GC:");
13607                    printed = true;
13608                }
13609                pw.print("    Process "); pw.println(proc);
13610                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13611                        pw.print(", last gced=");
13612                        pw.print(now-proc.lastRequestedGc);
13613                        pw.print(" ms ago, last lowMem=");
13614                        pw.print(now-proc.lastLowMemory);
13615                        pw.println(" ms ago");
13616
13617            }
13618        }
13619        return needSep;
13620    }
13621
13622    void printOomLevel(PrintWriter pw, String name, int adj) {
13623        pw.print("    ");
13624        if (adj >= 0) {
13625            pw.print(' ');
13626            if (adj < 10) pw.print(' ');
13627        } else {
13628            if (adj > -10) pw.print(' ');
13629        }
13630        pw.print(adj);
13631        pw.print(": ");
13632        pw.print(name);
13633        pw.print(" (");
13634        pw.print(mProcessList.getMemLevel(adj)/1024);
13635        pw.println(" kB)");
13636    }
13637
13638    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13639            int opti, boolean dumpAll) {
13640        boolean needSep = false;
13641
13642        if (mLruProcesses.size() > 0) {
13643            if (needSep) pw.println();
13644            needSep = true;
13645            pw.println("  OOM levels:");
13646            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13647            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13648            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13649            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13650            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13651            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13652            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13653            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13654            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13655            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13656            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13657            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13658            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13659            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13660
13661            if (needSep) pw.println();
13662            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13663                    pw.print(" total, non-act at ");
13664                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13665                    pw.print(", non-svc at ");
13666                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13667                    pw.println("):");
13668            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13669            needSep = true;
13670        }
13671
13672        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13673
13674        pw.println();
13675        pw.println("  mHomeProcess: " + mHomeProcess);
13676        pw.println("  mPreviousProcess: " + mPreviousProcess);
13677        if (mHeavyWeightProcess != null) {
13678            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13679        }
13680
13681        return true;
13682    }
13683
13684    /**
13685     * There are three ways to call this:
13686     *  - no provider specified: dump all the providers
13687     *  - a flattened component name that matched an existing provider was specified as the
13688     *    first arg: dump that one provider
13689     *  - the first arg isn't the flattened component name of an existing provider:
13690     *    dump all providers whose component contains the first arg as a substring
13691     */
13692    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13693            int opti, boolean dumpAll) {
13694        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13695    }
13696
13697    static class ItemMatcher {
13698        ArrayList<ComponentName> components;
13699        ArrayList<String> strings;
13700        ArrayList<Integer> objects;
13701        boolean all;
13702
13703        ItemMatcher() {
13704            all = true;
13705        }
13706
13707        void build(String name) {
13708            ComponentName componentName = ComponentName.unflattenFromString(name);
13709            if (componentName != null) {
13710                if (components == null) {
13711                    components = new ArrayList<ComponentName>();
13712                }
13713                components.add(componentName);
13714                all = false;
13715            } else {
13716                int objectId = 0;
13717                // Not a '/' separated full component name; maybe an object ID?
13718                try {
13719                    objectId = Integer.parseInt(name, 16);
13720                    if (objects == null) {
13721                        objects = new ArrayList<Integer>();
13722                    }
13723                    objects.add(objectId);
13724                    all = false;
13725                } catch (RuntimeException e) {
13726                    // Not an integer; just do string match.
13727                    if (strings == null) {
13728                        strings = new ArrayList<String>();
13729                    }
13730                    strings.add(name);
13731                    all = false;
13732                }
13733            }
13734        }
13735
13736        int build(String[] args, int opti) {
13737            for (; opti<args.length; opti++) {
13738                String name = args[opti];
13739                if ("--".equals(name)) {
13740                    return opti+1;
13741                }
13742                build(name);
13743            }
13744            return opti;
13745        }
13746
13747        boolean match(Object object, ComponentName comp) {
13748            if (all) {
13749                return true;
13750            }
13751            if (components != null) {
13752                for (int i=0; i<components.size(); i++) {
13753                    if (components.get(i).equals(comp)) {
13754                        return true;
13755                    }
13756                }
13757            }
13758            if (objects != null) {
13759                for (int i=0; i<objects.size(); i++) {
13760                    if (System.identityHashCode(object) == objects.get(i)) {
13761                        return true;
13762                    }
13763                }
13764            }
13765            if (strings != null) {
13766                String flat = comp.flattenToString();
13767                for (int i=0; i<strings.size(); i++) {
13768                    if (flat.contains(strings.get(i))) {
13769                        return true;
13770                    }
13771                }
13772            }
13773            return false;
13774        }
13775    }
13776
13777    /**
13778     * There are three things that cmd can be:
13779     *  - a flattened component name that matches an existing activity
13780     *  - the cmd arg isn't the flattened component name of an existing activity:
13781     *    dump all activity whose component contains the cmd as a substring
13782     *  - A hex number of the ActivityRecord object instance.
13783     */
13784    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13785            int opti, boolean dumpAll) {
13786        ArrayList<ActivityRecord> activities;
13787
13788        synchronized (this) {
13789            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13790        }
13791
13792        if (activities.size() <= 0) {
13793            return false;
13794        }
13795
13796        String[] newArgs = new String[args.length - opti];
13797        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13798
13799        TaskRecord lastTask = null;
13800        boolean needSep = false;
13801        for (int i=activities.size()-1; i>=0; i--) {
13802            ActivityRecord r = activities.get(i);
13803            if (needSep) {
13804                pw.println();
13805            }
13806            needSep = true;
13807            synchronized (this) {
13808                if (lastTask != r.task) {
13809                    lastTask = r.task;
13810                    pw.print("TASK "); pw.print(lastTask.affinity);
13811                            pw.print(" id="); pw.println(lastTask.taskId);
13812                    if (dumpAll) {
13813                        lastTask.dump(pw, "  ");
13814                    }
13815                }
13816            }
13817            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13818        }
13819        return true;
13820    }
13821
13822    /**
13823     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13824     * there is a thread associated with the activity.
13825     */
13826    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13827            final ActivityRecord r, String[] args, boolean dumpAll) {
13828        String innerPrefix = prefix + "  ";
13829        synchronized (this) {
13830            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13831                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13832                    pw.print(" pid=");
13833                    if (r.app != null) pw.println(r.app.pid);
13834                    else pw.println("(not running)");
13835            if (dumpAll) {
13836                r.dump(pw, innerPrefix);
13837            }
13838        }
13839        if (r.app != null && r.app.thread != null) {
13840            // flush anything that is already in the PrintWriter since the thread is going
13841            // to write to the file descriptor directly
13842            pw.flush();
13843            try {
13844                TransferPipe tp = new TransferPipe();
13845                try {
13846                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13847                            r.appToken, innerPrefix, args);
13848                    tp.go(fd);
13849                } finally {
13850                    tp.kill();
13851                }
13852            } catch (IOException e) {
13853                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13854            } catch (RemoteException e) {
13855                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13856            }
13857        }
13858    }
13859
13860    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13861            int opti, boolean dumpAll, String dumpPackage) {
13862        boolean needSep = false;
13863        boolean onlyHistory = false;
13864        boolean printedAnything = false;
13865
13866        if ("history".equals(dumpPackage)) {
13867            if (opti < args.length && "-s".equals(args[opti])) {
13868                dumpAll = false;
13869            }
13870            onlyHistory = true;
13871            dumpPackage = null;
13872        }
13873
13874        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13875        if (!onlyHistory && dumpAll) {
13876            if (mRegisteredReceivers.size() > 0) {
13877                boolean printed = false;
13878                Iterator it = mRegisteredReceivers.values().iterator();
13879                while (it.hasNext()) {
13880                    ReceiverList r = (ReceiverList)it.next();
13881                    if (dumpPackage != null && (r.app == null ||
13882                            !dumpPackage.equals(r.app.info.packageName))) {
13883                        continue;
13884                    }
13885                    if (!printed) {
13886                        pw.println("  Registered Receivers:");
13887                        needSep = true;
13888                        printed = true;
13889                        printedAnything = true;
13890                    }
13891                    pw.print("  * "); pw.println(r);
13892                    r.dump(pw, "    ");
13893                }
13894            }
13895
13896            if (mReceiverResolver.dump(pw, needSep ?
13897                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13898                    "    ", dumpPackage, false, false)) {
13899                needSep = true;
13900                printedAnything = true;
13901            }
13902        }
13903
13904        for (BroadcastQueue q : mBroadcastQueues) {
13905            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13906            printedAnything |= needSep;
13907        }
13908
13909        needSep = true;
13910
13911        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13912            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13913                if (needSep) {
13914                    pw.println();
13915                }
13916                needSep = true;
13917                printedAnything = true;
13918                pw.print("  Sticky broadcasts for user ");
13919                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13920                StringBuilder sb = new StringBuilder(128);
13921                for (Map.Entry<String, ArrayList<Intent>> ent
13922                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13923                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13924                    if (dumpAll) {
13925                        pw.println(":");
13926                        ArrayList<Intent> intents = ent.getValue();
13927                        final int N = intents.size();
13928                        for (int i=0; i<N; i++) {
13929                            sb.setLength(0);
13930                            sb.append("    Intent: ");
13931                            intents.get(i).toShortString(sb, false, true, false, false);
13932                            pw.println(sb.toString());
13933                            Bundle bundle = intents.get(i).getExtras();
13934                            if (bundle != null) {
13935                                pw.print("      ");
13936                                pw.println(bundle.toString());
13937                            }
13938                        }
13939                    } else {
13940                        pw.println("");
13941                    }
13942                }
13943            }
13944        }
13945
13946        if (!onlyHistory && dumpAll) {
13947            pw.println();
13948            for (BroadcastQueue queue : mBroadcastQueues) {
13949                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13950                        + queue.mBroadcastsScheduled);
13951            }
13952            pw.println("  mHandler:");
13953            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13954            needSep = true;
13955            printedAnything = true;
13956        }
13957
13958        if (!printedAnything) {
13959            pw.println("  (nothing)");
13960        }
13961    }
13962
13963    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13964            int opti, boolean dumpAll, String dumpPackage) {
13965        boolean needSep;
13966        boolean printedAnything = false;
13967
13968        ItemMatcher matcher = new ItemMatcher();
13969        matcher.build(args, opti);
13970
13971        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13972
13973        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13974        printedAnything |= needSep;
13975
13976        if (mLaunchingProviders.size() > 0) {
13977            boolean printed = false;
13978            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13979                ContentProviderRecord r = mLaunchingProviders.get(i);
13980                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13981                    continue;
13982                }
13983                if (!printed) {
13984                    if (needSep) pw.println();
13985                    needSep = true;
13986                    pw.println("  Launching content providers:");
13987                    printed = true;
13988                    printedAnything = true;
13989                }
13990                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13991                        pw.println(r);
13992            }
13993        }
13994
13995        if (mGrantedUriPermissions.size() > 0) {
13996            boolean printed = false;
13997            int dumpUid = -2;
13998            if (dumpPackage != null) {
13999                try {
14000                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14001                } catch (NameNotFoundException e) {
14002                    dumpUid = -1;
14003                }
14004            }
14005            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14006                int uid = mGrantedUriPermissions.keyAt(i);
14007                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14008                    continue;
14009                }
14010                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14011                if (!printed) {
14012                    if (needSep) pw.println();
14013                    needSep = true;
14014                    pw.println("  Granted Uri Permissions:");
14015                    printed = true;
14016                    printedAnything = true;
14017                }
14018                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14019                for (UriPermission perm : perms.values()) {
14020                    pw.print("    "); pw.println(perm);
14021                    if (dumpAll) {
14022                        perm.dump(pw, "      ");
14023                    }
14024                }
14025            }
14026        }
14027
14028        if (!printedAnything) {
14029            pw.println("  (nothing)");
14030        }
14031    }
14032
14033    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14034            int opti, boolean dumpAll, String dumpPackage) {
14035        boolean printed = false;
14036
14037        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14038
14039        if (mIntentSenderRecords.size() > 0) {
14040            Iterator<WeakReference<PendingIntentRecord>> it
14041                    = mIntentSenderRecords.values().iterator();
14042            while (it.hasNext()) {
14043                WeakReference<PendingIntentRecord> ref = it.next();
14044                PendingIntentRecord rec = ref != null ? ref.get(): null;
14045                if (dumpPackage != null && (rec == null
14046                        || !dumpPackage.equals(rec.key.packageName))) {
14047                    continue;
14048                }
14049                printed = true;
14050                if (rec != null) {
14051                    pw.print("  * "); pw.println(rec);
14052                    if (dumpAll) {
14053                        rec.dump(pw, "    ");
14054                    }
14055                } else {
14056                    pw.print("  * "); pw.println(ref);
14057                }
14058            }
14059        }
14060
14061        if (!printed) {
14062            pw.println("  (nothing)");
14063        }
14064    }
14065
14066    private static final int dumpProcessList(PrintWriter pw,
14067            ActivityManagerService service, List list,
14068            String prefix, String normalLabel, String persistentLabel,
14069            String dumpPackage) {
14070        int numPers = 0;
14071        final int N = list.size()-1;
14072        for (int i=N; i>=0; i--) {
14073            ProcessRecord r = (ProcessRecord)list.get(i);
14074            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14075                continue;
14076            }
14077            pw.println(String.format("%s%s #%2d: %s",
14078                    prefix, (r.persistent ? persistentLabel : normalLabel),
14079                    i, r.toString()));
14080            if (r.persistent) {
14081                numPers++;
14082            }
14083        }
14084        return numPers;
14085    }
14086
14087    private static final boolean dumpProcessOomList(PrintWriter pw,
14088            ActivityManagerService service, List<ProcessRecord> origList,
14089            String prefix, String normalLabel, String persistentLabel,
14090            boolean inclDetails, String dumpPackage) {
14091
14092        ArrayList<Pair<ProcessRecord, Integer>> list
14093                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14094        for (int i=0; i<origList.size(); i++) {
14095            ProcessRecord r = origList.get(i);
14096            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14097                continue;
14098            }
14099            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14100        }
14101
14102        if (list.size() <= 0) {
14103            return false;
14104        }
14105
14106        Comparator<Pair<ProcessRecord, Integer>> comparator
14107                = new Comparator<Pair<ProcessRecord, Integer>>() {
14108            @Override
14109            public int compare(Pair<ProcessRecord, Integer> object1,
14110                    Pair<ProcessRecord, Integer> object2) {
14111                if (object1.first.setAdj != object2.first.setAdj) {
14112                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14113                }
14114                if (object1.second.intValue() != object2.second.intValue()) {
14115                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14116                }
14117                return 0;
14118            }
14119        };
14120
14121        Collections.sort(list, comparator);
14122
14123        final long curRealtime = SystemClock.elapsedRealtime();
14124        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14125        final long curUptime = SystemClock.uptimeMillis();
14126        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14127
14128        for (int i=list.size()-1; i>=0; i--) {
14129            ProcessRecord r = list.get(i).first;
14130            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14131            char schedGroup;
14132            switch (r.setSchedGroup) {
14133                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14134                    schedGroup = 'B';
14135                    break;
14136                case Process.THREAD_GROUP_DEFAULT:
14137                    schedGroup = 'F';
14138                    break;
14139                default:
14140                    schedGroup = '?';
14141                    break;
14142            }
14143            char foreground;
14144            if (r.foregroundActivities) {
14145                foreground = 'A';
14146            } else if (r.foregroundServices) {
14147                foreground = 'S';
14148            } else {
14149                foreground = ' ';
14150            }
14151            String procState = ProcessList.makeProcStateString(r.curProcState);
14152            pw.print(prefix);
14153            pw.print(r.persistent ? persistentLabel : normalLabel);
14154            pw.print(" #");
14155            int num = (origList.size()-1)-list.get(i).second;
14156            if (num < 10) pw.print(' ');
14157            pw.print(num);
14158            pw.print(": ");
14159            pw.print(oomAdj);
14160            pw.print(' ');
14161            pw.print(schedGroup);
14162            pw.print('/');
14163            pw.print(foreground);
14164            pw.print('/');
14165            pw.print(procState);
14166            pw.print(" trm:");
14167            if (r.trimMemoryLevel < 10) pw.print(' ');
14168            pw.print(r.trimMemoryLevel);
14169            pw.print(' ');
14170            pw.print(r.toShortString());
14171            pw.print(" (");
14172            pw.print(r.adjType);
14173            pw.println(')');
14174            if (r.adjSource != null || r.adjTarget != null) {
14175                pw.print(prefix);
14176                pw.print("    ");
14177                if (r.adjTarget instanceof ComponentName) {
14178                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14179                } else if (r.adjTarget != null) {
14180                    pw.print(r.adjTarget.toString());
14181                } else {
14182                    pw.print("{null}");
14183                }
14184                pw.print("<=");
14185                if (r.adjSource instanceof ProcessRecord) {
14186                    pw.print("Proc{");
14187                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14188                    pw.println("}");
14189                } else if (r.adjSource != null) {
14190                    pw.println(r.adjSource.toString());
14191                } else {
14192                    pw.println("{null}");
14193                }
14194            }
14195            if (inclDetails) {
14196                pw.print(prefix);
14197                pw.print("    ");
14198                pw.print("oom: max="); pw.print(r.maxAdj);
14199                pw.print(" curRaw="); pw.print(r.curRawAdj);
14200                pw.print(" setRaw="); pw.print(r.setRawAdj);
14201                pw.print(" cur="); pw.print(r.curAdj);
14202                pw.print(" set="); pw.println(r.setAdj);
14203                pw.print(prefix);
14204                pw.print("    ");
14205                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14206                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14207                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14208                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14209                pw.println();
14210                pw.print(prefix);
14211                pw.print("    ");
14212                pw.print("cached="); pw.print(r.cached);
14213                pw.print(" empty="); pw.print(r.empty);
14214                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14215
14216                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14217                    if (r.lastWakeTime != 0) {
14218                        long wtime;
14219                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14220                        synchronized (stats) {
14221                            wtime = stats.getProcessWakeTime(r.info.uid,
14222                                    r.pid, curRealtime);
14223                        }
14224                        long timeUsed = wtime - r.lastWakeTime;
14225                        pw.print(prefix);
14226                        pw.print("    ");
14227                        pw.print("keep awake over ");
14228                        TimeUtils.formatDuration(realtimeSince, pw);
14229                        pw.print(" used ");
14230                        TimeUtils.formatDuration(timeUsed, pw);
14231                        pw.print(" (");
14232                        pw.print((timeUsed*100)/realtimeSince);
14233                        pw.println("%)");
14234                    }
14235                    if (r.lastCpuTime != 0) {
14236                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14237                        pw.print(prefix);
14238                        pw.print("    ");
14239                        pw.print("run cpu over ");
14240                        TimeUtils.formatDuration(uptimeSince, pw);
14241                        pw.print(" used ");
14242                        TimeUtils.formatDuration(timeUsed, pw);
14243                        pw.print(" (");
14244                        pw.print((timeUsed*100)/uptimeSince);
14245                        pw.println("%)");
14246                    }
14247                }
14248            }
14249        }
14250        return true;
14251    }
14252
14253    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14254            String[] args) {
14255        ArrayList<ProcessRecord> procs;
14256        synchronized (this) {
14257            if (args != null && args.length > start
14258                    && args[start].charAt(0) != '-') {
14259                procs = new ArrayList<ProcessRecord>();
14260                int pid = -1;
14261                try {
14262                    pid = Integer.parseInt(args[start]);
14263                } catch (NumberFormatException e) {
14264                }
14265                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14266                    ProcessRecord proc = mLruProcesses.get(i);
14267                    if (proc.pid == pid) {
14268                        procs.add(proc);
14269                    } else if (allPkgs && proc.pkgList != null
14270                            && proc.pkgList.containsKey(args[start])) {
14271                        procs.add(proc);
14272                    } else if (proc.processName.equals(args[start])) {
14273                        procs.add(proc);
14274                    }
14275                }
14276                if (procs.size() <= 0) {
14277                    return null;
14278                }
14279            } else {
14280                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14281            }
14282        }
14283        return procs;
14284    }
14285
14286    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14287            PrintWriter pw, String[] args) {
14288        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14289        if (procs == null) {
14290            pw.println("No process found for: " + args[0]);
14291            return;
14292        }
14293
14294        long uptime = SystemClock.uptimeMillis();
14295        long realtime = SystemClock.elapsedRealtime();
14296        pw.println("Applications Graphics Acceleration Info:");
14297        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14298
14299        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14300            ProcessRecord r = procs.get(i);
14301            if (r.thread != null) {
14302                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14303                pw.flush();
14304                try {
14305                    TransferPipe tp = new TransferPipe();
14306                    try {
14307                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14308                        tp.go(fd);
14309                    } finally {
14310                        tp.kill();
14311                    }
14312                } catch (IOException e) {
14313                    pw.println("Failure while dumping the app: " + r);
14314                    pw.flush();
14315                } catch (RemoteException e) {
14316                    pw.println("Got a RemoteException while dumping the app " + r);
14317                    pw.flush();
14318                }
14319            }
14320        }
14321    }
14322
14323    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14324        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14325        if (procs == null) {
14326            pw.println("No process found for: " + args[0]);
14327            return;
14328        }
14329
14330        pw.println("Applications Database Info:");
14331
14332        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14333            ProcessRecord r = procs.get(i);
14334            if (r.thread != null) {
14335                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14336                pw.flush();
14337                try {
14338                    TransferPipe tp = new TransferPipe();
14339                    try {
14340                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14341                        tp.go(fd);
14342                    } finally {
14343                        tp.kill();
14344                    }
14345                } catch (IOException e) {
14346                    pw.println("Failure while dumping the app: " + r);
14347                    pw.flush();
14348                } catch (RemoteException e) {
14349                    pw.println("Got a RemoteException while dumping the app " + r);
14350                    pw.flush();
14351                }
14352            }
14353        }
14354    }
14355
14356    final static class MemItem {
14357        final boolean isProc;
14358        final String label;
14359        final String shortLabel;
14360        final long pss;
14361        final int id;
14362        final boolean hasActivities;
14363        ArrayList<MemItem> subitems;
14364
14365        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14366                boolean _hasActivities) {
14367            isProc = true;
14368            label = _label;
14369            shortLabel = _shortLabel;
14370            pss = _pss;
14371            id = _id;
14372            hasActivities = _hasActivities;
14373        }
14374
14375        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14376            isProc = false;
14377            label = _label;
14378            shortLabel = _shortLabel;
14379            pss = _pss;
14380            id = _id;
14381            hasActivities = false;
14382        }
14383    }
14384
14385    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14386            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14387        if (sort && !isCompact) {
14388            Collections.sort(items, new Comparator<MemItem>() {
14389                @Override
14390                public int compare(MemItem lhs, MemItem rhs) {
14391                    if (lhs.pss < rhs.pss) {
14392                        return 1;
14393                    } else if (lhs.pss > rhs.pss) {
14394                        return -1;
14395                    }
14396                    return 0;
14397                }
14398            });
14399        }
14400
14401        for (int i=0; i<items.size(); i++) {
14402            MemItem mi = items.get(i);
14403            if (!isCompact) {
14404                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14405            } else if (mi.isProc) {
14406                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14407                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14408                pw.println(mi.hasActivities ? ",a" : ",e");
14409            } else {
14410                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14411                pw.println(mi.pss);
14412            }
14413            if (mi.subitems != null) {
14414                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14415                        true, isCompact);
14416            }
14417        }
14418    }
14419
14420    // These are in KB.
14421    static final long[] DUMP_MEM_BUCKETS = new long[] {
14422        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14423        120*1024, 160*1024, 200*1024,
14424        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14425        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14426    };
14427
14428    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14429            boolean stackLike) {
14430        int start = label.lastIndexOf('.');
14431        if (start >= 0) start++;
14432        else start = 0;
14433        int end = label.length();
14434        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14435            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14436                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14437                out.append(bucket);
14438                out.append(stackLike ? "MB." : "MB ");
14439                out.append(label, start, end);
14440                return;
14441            }
14442        }
14443        out.append(memKB/1024);
14444        out.append(stackLike ? "MB." : "MB ");
14445        out.append(label, start, end);
14446    }
14447
14448    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14449            ProcessList.NATIVE_ADJ,
14450            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14451            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14452            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14453            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14454            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14455            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14456    };
14457    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14458            "Native",
14459            "System", "Persistent", "Persistent Service", "Foreground",
14460            "Visible", "Perceptible",
14461            "Heavy Weight", "Backup",
14462            "A Services", "Home",
14463            "Previous", "B Services", "Cached"
14464    };
14465    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14466            "native",
14467            "sys", "pers", "persvc", "fore",
14468            "vis", "percept",
14469            "heavy", "backup",
14470            "servicea", "home",
14471            "prev", "serviceb", "cached"
14472    };
14473
14474    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14475            long realtime, boolean isCheckinRequest, boolean isCompact) {
14476        if (isCheckinRequest || isCompact) {
14477            // short checkin version
14478            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14479        } else {
14480            pw.println("Applications Memory Usage (kB):");
14481            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14482        }
14483    }
14484
14485    private static final int KSM_SHARED = 0;
14486    private static final int KSM_SHARING = 1;
14487    private static final int KSM_UNSHARED = 2;
14488    private static final int KSM_VOLATILE = 3;
14489
14490    private final long[] getKsmInfo() {
14491        long[] longOut = new long[4];
14492        final int[] SINGLE_LONG_FORMAT = new int[] {
14493            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14494        };
14495        long[] longTmp = new long[1];
14496        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14497                SINGLE_LONG_FORMAT, null, longTmp, null);
14498        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14499        longTmp[0] = 0;
14500        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14501                SINGLE_LONG_FORMAT, null, longTmp, null);
14502        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14503        longTmp[0] = 0;
14504        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14505                SINGLE_LONG_FORMAT, null, longTmp, null);
14506        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14507        longTmp[0] = 0;
14508        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14509                SINGLE_LONG_FORMAT, null, longTmp, null);
14510        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14511        return longOut;
14512    }
14513
14514    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14515            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14516        boolean dumpDetails = false;
14517        boolean dumpFullDetails = false;
14518        boolean dumpDalvik = false;
14519        boolean dumpSummaryOnly = false;
14520        boolean oomOnly = false;
14521        boolean isCompact = false;
14522        boolean localOnly = false;
14523        boolean packages = false;
14524
14525        int opti = 0;
14526        while (opti < args.length) {
14527            String opt = args[opti];
14528            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14529                break;
14530            }
14531            opti++;
14532            if ("-a".equals(opt)) {
14533                dumpDetails = true;
14534                dumpFullDetails = true;
14535                dumpDalvik = true;
14536            } else if ("-d".equals(opt)) {
14537                dumpDalvik = true;
14538            } else if ("-c".equals(opt)) {
14539                isCompact = true;
14540            } else if ("-s".equals(opt)) {
14541                dumpDetails = true;
14542                dumpSummaryOnly = true;
14543            } else if ("--oom".equals(opt)) {
14544                oomOnly = true;
14545            } else if ("--local".equals(opt)) {
14546                localOnly = true;
14547            } else if ("--package".equals(opt)) {
14548                packages = true;
14549            } else if ("-h".equals(opt)) {
14550                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14551                pw.println("  -a: include all available information for each process.");
14552                pw.println("  -d: include dalvik details.");
14553                pw.println("  -c: dump in a compact machine-parseable representation.");
14554                pw.println("  -s: dump only summary of application memory usage.");
14555                pw.println("  --oom: only show processes organized by oom adj.");
14556                pw.println("  --local: only collect details locally, don't call process.");
14557                pw.println("  --package: interpret process arg as package, dumping all");
14558                pw.println("             processes that have loaded that package.");
14559                pw.println("If [process] is specified it can be the name or ");
14560                pw.println("pid of a specific process to dump.");
14561                return;
14562            } else {
14563                pw.println("Unknown argument: " + opt + "; use -h for help");
14564            }
14565        }
14566
14567        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14568        long uptime = SystemClock.uptimeMillis();
14569        long realtime = SystemClock.elapsedRealtime();
14570        final long[] tmpLong = new long[1];
14571
14572        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14573        if (procs == null) {
14574            // No Java processes.  Maybe they want to print a native process.
14575            if (args != null && args.length > opti
14576                    && args[opti].charAt(0) != '-') {
14577                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14578                        = new ArrayList<ProcessCpuTracker.Stats>();
14579                updateCpuStatsNow();
14580                int findPid = -1;
14581                try {
14582                    findPid = Integer.parseInt(args[opti]);
14583                } catch (NumberFormatException e) {
14584                }
14585                synchronized (mProcessCpuTracker) {
14586                    final int N = mProcessCpuTracker.countStats();
14587                    for (int i=0; i<N; i++) {
14588                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14589                        if (st.pid == findPid || (st.baseName != null
14590                                && st.baseName.equals(args[opti]))) {
14591                            nativeProcs.add(st);
14592                        }
14593                    }
14594                }
14595                if (nativeProcs.size() > 0) {
14596                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14597                            isCompact);
14598                    Debug.MemoryInfo mi = null;
14599                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14600                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14601                        final int pid = r.pid;
14602                        if (!isCheckinRequest && dumpDetails) {
14603                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14604                        }
14605                        if (mi == null) {
14606                            mi = new Debug.MemoryInfo();
14607                        }
14608                        if (dumpDetails || (!brief && !oomOnly)) {
14609                            Debug.getMemoryInfo(pid, mi);
14610                        } else {
14611                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14612                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14613                        }
14614                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14615                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14616                        if (isCheckinRequest) {
14617                            pw.println();
14618                        }
14619                    }
14620                    return;
14621                }
14622            }
14623            pw.println("No process found for: " + args[opti]);
14624            return;
14625        }
14626
14627        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14628            dumpDetails = true;
14629        }
14630
14631        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14632
14633        String[] innerArgs = new String[args.length-opti];
14634        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14635
14636        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14637        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14638        long nativePss = 0;
14639        long dalvikPss = 0;
14640        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14641                EmptyArray.LONG;
14642        long otherPss = 0;
14643        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14644
14645        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14646        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14647                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14648
14649        long totalPss = 0;
14650        long cachedPss = 0;
14651
14652        Debug.MemoryInfo mi = null;
14653        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14654            final ProcessRecord r = procs.get(i);
14655            final IApplicationThread thread;
14656            final int pid;
14657            final int oomAdj;
14658            final boolean hasActivities;
14659            synchronized (this) {
14660                thread = r.thread;
14661                pid = r.pid;
14662                oomAdj = r.getSetAdjWithServices();
14663                hasActivities = r.activities.size() > 0;
14664            }
14665            if (thread != null) {
14666                if (!isCheckinRequest && dumpDetails) {
14667                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14668                }
14669                if (mi == null) {
14670                    mi = new Debug.MemoryInfo();
14671                }
14672                if (dumpDetails || (!brief && !oomOnly)) {
14673                    Debug.getMemoryInfo(pid, mi);
14674                } else {
14675                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14676                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14677                }
14678                if (dumpDetails) {
14679                    if (localOnly) {
14680                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14681                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14682                        if (isCheckinRequest) {
14683                            pw.println();
14684                        }
14685                    } else {
14686                        try {
14687                            pw.flush();
14688                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14689                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14690                        } catch (RemoteException e) {
14691                            if (!isCheckinRequest) {
14692                                pw.println("Got RemoteException!");
14693                                pw.flush();
14694                            }
14695                        }
14696                    }
14697                }
14698
14699                final long myTotalPss = mi.getTotalPss();
14700                final long myTotalUss = mi.getTotalUss();
14701
14702                synchronized (this) {
14703                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14704                        // Record this for posterity if the process has been stable.
14705                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14706                    }
14707                }
14708
14709                if (!isCheckinRequest && mi != null) {
14710                    totalPss += myTotalPss;
14711                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14712                            (hasActivities ? " / activities)" : ")"),
14713                            r.processName, myTotalPss, pid, hasActivities);
14714                    procMems.add(pssItem);
14715                    procMemsMap.put(pid, pssItem);
14716
14717                    nativePss += mi.nativePss;
14718                    dalvikPss += mi.dalvikPss;
14719                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14720                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14721                    }
14722                    otherPss += mi.otherPss;
14723                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14724                        long mem = mi.getOtherPss(j);
14725                        miscPss[j] += mem;
14726                        otherPss -= mem;
14727                    }
14728
14729                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14730                        cachedPss += myTotalPss;
14731                    }
14732
14733                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14734                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14735                                || oomIndex == (oomPss.length-1)) {
14736                            oomPss[oomIndex] += myTotalPss;
14737                            if (oomProcs[oomIndex] == null) {
14738                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14739                            }
14740                            oomProcs[oomIndex].add(pssItem);
14741                            break;
14742                        }
14743                    }
14744                }
14745            }
14746        }
14747
14748        long nativeProcTotalPss = 0;
14749
14750        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14751            // If we are showing aggregations, also look for native processes to
14752            // include so that our aggregations are more accurate.
14753            updateCpuStatsNow();
14754            mi = null;
14755            synchronized (mProcessCpuTracker) {
14756                final int N = mProcessCpuTracker.countStats();
14757                for (int i=0; i<N; i++) {
14758                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14759                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14760                        if (mi == null) {
14761                            mi = new Debug.MemoryInfo();
14762                        }
14763                        if (!brief && !oomOnly) {
14764                            Debug.getMemoryInfo(st.pid, mi);
14765                        } else {
14766                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14767                            mi.nativePrivateDirty = (int)tmpLong[0];
14768                        }
14769
14770                        final long myTotalPss = mi.getTotalPss();
14771                        totalPss += myTotalPss;
14772                        nativeProcTotalPss += myTotalPss;
14773
14774                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14775                                st.name, myTotalPss, st.pid, false);
14776                        procMems.add(pssItem);
14777
14778                        nativePss += mi.nativePss;
14779                        dalvikPss += mi.dalvikPss;
14780                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14781                            dalvikSubitemPss[j] += mi.getOtherPss(
14782                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14783                        }
14784                        otherPss += mi.otherPss;
14785                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14786                            long mem = mi.getOtherPss(j);
14787                            miscPss[j] += mem;
14788                            otherPss -= mem;
14789                        }
14790                        oomPss[0] += myTotalPss;
14791                        if (oomProcs[0] == null) {
14792                            oomProcs[0] = new ArrayList<MemItem>();
14793                        }
14794                        oomProcs[0].add(pssItem);
14795                    }
14796                }
14797            }
14798
14799            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14800
14801            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14802            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14803            if (dalvikSubitemPss.length > 0) {
14804                dalvikItem.subitems = new ArrayList<MemItem>();
14805                for (int j=0; j<dalvikSubitemPss.length; j++) {
14806                    final String name = Debug.MemoryInfo.getOtherLabel(
14807                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14808                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14809                }
14810            }
14811            catMems.add(dalvikItem);
14812            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14813            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14814                String label = Debug.MemoryInfo.getOtherLabel(j);
14815                catMems.add(new MemItem(label, label, miscPss[j], j));
14816            }
14817
14818            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14819            for (int j=0; j<oomPss.length; j++) {
14820                if (oomPss[j] != 0) {
14821                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14822                            : DUMP_MEM_OOM_LABEL[j];
14823                    MemItem item = new MemItem(label, label, oomPss[j],
14824                            DUMP_MEM_OOM_ADJ[j]);
14825                    item.subitems = oomProcs[j];
14826                    oomMems.add(item);
14827                }
14828            }
14829
14830            if (!brief && !oomOnly && !isCompact) {
14831                pw.println();
14832                pw.println("Total PSS by process:");
14833                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14834                pw.println();
14835            }
14836            if (!isCompact) {
14837                pw.println("Total PSS by OOM adjustment:");
14838            }
14839            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14840            if (!brief && !oomOnly) {
14841                PrintWriter out = categoryPw != null ? categoryPw : pw;
14842                if (!isCompact) {
14843                    out.println();
14844                    out.println("Total PSS by category:");
14845                }
14846                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14847            }
14848            if (!isCompact) {
14849                pw.println();
14850            }
14851            MemInfoReader memInfo = new MemInfoReader();
14852            memInfo.readMemInfo();
14853            if (nativeProcTotalPss > 0) {
14854                synchronized (this) {
14855                    final long cachedKb = memInfo.getCachedSizeKb();
14856                    final long freeKb = memInfo.getFreeSizeKb();
14857                    final long zramKb = memInfo.getZramTotalSizeKb();
14858                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14859                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14860                            kernelKb*1024, nativeProcTotalPss*1024);
14861                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14862                            nativeProcTotalPss);
14863                }
14864            }
14865            if (!brief) {
14866                if (!isCompact) {
14867                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14868                    pw.print(" kB (status ");
14869                    switch (mLastMemoryLevel) {
14870                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14871                            pw.println("normal)");
14872                            break;
14873                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14874                            pw.println("moderate)");
14875                            break;
14876                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14877                            pw.println("low)");
14878                            break;
14879                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14880                            pw.println("critical)");
14881                            break;
14882                        default:
14883                            pw.print(mLastMemoryLevel);
14884                            pw.println(")");
14885                            break;
14886                    }
14887                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14888                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14889                            pw.print(cachedPss); pw.print(" cached pss + ");
14890                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14891                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14892                } else {
14893                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14894                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14895                            + memInfo.getFreeSizeKb()); pw.print(",");
14896                    pw.println(totalPss - cachedPss);
14897                }
14898            }
14899            if (!isCompact) {
14900                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14901                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14902                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14903                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14904                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14905                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14906                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14907            }
14908            if (!brief) {
14909                if (memInfo.getZramTotalSizeKb() != 0) {
14910                    if (!isCompact) {
14911                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14912                                pw.print(" kB physical used for ");
14913                                pw.print(memInfo.getSwapTotalSizeKb()
14914                                        - memInfo.getSwapFreeSizeKb());
14915                                pw.print(" kB in swap (");
14916                                pw.print(memInfo.getSwapTotalSizeKb());
14917                                pw.println(" kB total swap)");
14918                    } else {
14919                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14920                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14921                                pw.println(memInfo.getSwapFreeSizeKb());
14922                    }
14923                }
14924                final long[] ksm = getKsmInfo();
14925                if (!isCompact) {
14926                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14927                            || ksm[KSM_VOLATILE] != 0) {
14928                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14929                                pw.print(" kB saved from shared ");
14930                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14931                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14932                                pw.print(" kB unshared; ");
14933                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14934                    }
14935                    pw.print("   Tuning: ");
14936                    pw.print(ActivityManager.staticGetMemoryClass());
14937                    pw.print(" (large ");
14938                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14939                    pw.print("), oom ");
14940                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14941                    pw.print(" kB");
14942                    pw.print(", restore limit ");
14943                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14944                    pw.print(" kB");
14945                    if (ActivityManager.isLowRamDeviceStatic()) {
14946                        pw.print(" (low-ram)");
14947                    }
14948                    if (ActivityManager.isHighEndGfx()) {
14949                        pw.print(" (high-end-gfx)");
14950                    }
14951                    pw.println();
14952                } else {
14953                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14954                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14955                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14956                    pw.print("tuning,");
14957                    pw.print(ActivityManager.staticGetMemoryClass());
14958                    pw.print(',');
14959                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14960                    pw.print(',');
14961                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14962                    if (ActivityManager.isLowRamDeviceStatic()) {
14963                        pw.print(",low-ram");
14964                    }
14965                    if (ActivityManager.isHighEndGfx()) {
14966                        pw.print(",high-end-gfx");
14967                    }
14968                    pw.println();
14969                }
14970            }
14971        }
14972    }
14973
14974    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14975            long memtrack, String name) {
14976        sb.append("  ");
14977        sb.append(ProcessList.makeOomAdjString(oomAdj));
14978        sb.append(' ');
14979        sb.append(ProcessList.makeProcStateString(procState));
14980        sb.append(' ');
14981        ProcessList.appendRamKb(sb, pss);
14982        sb.append(" kB: ");
14983        sb.append(name);
14984        if (memtrack > 0) {
14985            sb.append(" (");
14986            sb.append(memtrack);
14987            sb.append(" kB memtrack)");
14988        }
14989    }
14990
14991    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14992        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14993        sb.append(" (pid ");
14994        sb.append(mi.pid);
14995        sb.append(") ");
14996        sb.append(mi.adjType);
14997        sb.append('\n');
14998        if (mi.adjReason != null) {
14999            sb.append("                      ");
15000            sb.append(mi.adjReason);
15001            sb.append('\n');
15002        }
15003    }
15004
15005    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15006        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15007        for (int i=0, N=memInfos.size(); i<N; i++) {
15008            ProcessMemInfo mi = memInfos.get(i);
15009            infoMap.put(mi.pid, mi);
15010        }
15011        updateCpuStatsNow();
15012        long[] memtrackTmp = new long[1];
15013        synchronized (mProcessCpuTracker) {
15014            final int N = mProcessCpuTracker.countStats();
15015            for (int i=0; i<N; i++) {
15016                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15017                if (st.vsize > 0) {
15018                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15019                    if (pss > 0) {
15020                        if (infoMap.indexOfKey(st.pid) < 0) {
15021                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15022                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15023                            mi.pss = pss;
15024                            mi.memtrack = memtrackTmp[0];
15025                            memInfos.add(mi);
15026                        }
15027                    }
15028                }
15029            }
15030        }
15031
15032        long totalPss = 0;
15033        long totalMemtrack = 0;
15034        for (int i=0, N=memInfos.size(); i<N; i++) {
15035            ProcessMemInfo mi = memInfos.get(i);
15036            if (mi.pss == 0) {
15037                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15038                mi.memtrack = memtrackTmp[0];
15039            }
15040            totalPss += mi.pss;
15041            totalMemtrack += mi.memtrack;
15042        }
15043        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15044            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15045                if (lhs.oomAdj != rhs.oomAdj) {
15046                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15047                }
15048                if (lhs.pss != rhs.pss) {
15049                    return lhs.pss < rhs.pss ? 1 : -1;
15050                }
15051                return 0;
15052            }
15053        });
15054
15055        StringBuilder tag = new StringBuilder(128);
15056        StringBuilder stack = new StringBuilder(128);
15057        tag.append("Low on memory -- ");
15058        appendMemBucket(tag, totalPss, "total", false);
15059        appendMemBucket(stack, totalPss, "total", true);
15060
15061        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15062        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15063        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15064
15065        boolean firstLine = true;
15066        int lastOomAdj = Integer.MIN_VALUE;
15067        long extraNativeRam = 0;
15068        long extraNativeMemtrack = 0;
15069        long cachedPss = 0;
15070        for (int i=0, N=memInfos.size(); i<N; i++) {
15071            ProcessMemInfo mi = memInfos.get(i);
15072
15073            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15074                cachedPss += mi.pss;
15075            }
15076
15077            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15078                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15079                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15080                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15081                if (lastOomAdj != mi.oomAdj) {
15082                    lastOomAdj = mi.oomAdj;
15083                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15084                        tag.append(" / ");
15085                    }
15086                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15087                        if (firstLine) {
15088                            stack.append(":");
15089                            firstLine = false;
15090                        }
15091                        stack.append("\n\t at ");
15092                    } else {
15093                        stack.append("$");
15094                    }
15095                } else {
15096                    tag.append(" ");
15097                    stack.append("$");
15098                }
15099                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15100                    appendMemBucket(tag, mi.pss, mi.name, false);
15101                }
15102                appendMemBucket(stack, mi.pss, mi.name, true);
15103                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15104                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15105                    stack.append("(");
15106                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15107                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15108                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15109                            stack.append(":");
15110                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15111                        }
15112                    }
15113                    stack.append(")");
15114                }
15115            }
15116
15117            appendMemInfo(fullNativeBuilder, mi);
15118            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15119                // The short form only has native processes that are >= 512K.
15120                if (mi.pss >= 512) {
15121                    appendMemInfo(shortNativeBuilder, mi);
15122                } else {
15123                    extraNativeRam += mi.pss;
15124                    extraNativeMemtrack += mi.memtrack;
15125                }
15126            } else {
15127                // Short form has all other details, but if we have collected RAM
15128                // from smaller native processes let's dump a summary of that.
15129                if (extraNativeRam > 0) {
15130                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15131                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15132                    shortNativeBuilder.append('\n');
15133                    extraNativeRam = 0;
15134                }
15135                appendMemInfo(fullJavaBuilder, mi);
15136            }
15137        }
15138
15139        fullJavaBuilder.append("           ");
15140        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15141        fullJavaBuilder.append(" kB: TOTAL");
15142        if (totalMemtrack > 0) {
15143            fullJavaBuilder.append(" (");
15144            fullJavaBuilder.append(totalMemtrack);
15145            fullJavaBuilder.append(" kB memtrack)");
15146        } else {
15147        }
15148        fullJavaBuilder.append("\n");
15149
15150        MemInfoReader memInfo = new MemInfoReader();
15151        memInfo.readMemInfo();
15152        final long[] infos = memInfo.getRawInfo();
15153
15154        StringBuilder memInfoBuilder = new StringBuilder(1024);
15155        Debug.getMemInfo(infos);
15156        memInfoBuilder.append("  MemInfo: ");
15157        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15158        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15159        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15160        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15161        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15162        memInfoBuilder.append("           ");
15163        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15164        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15165        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15166        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15167        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15168            memInfoBuilder.append("  ZRAM: ");
15169            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15170            memInfoBuilder.append(" kB RAM, ");
15171            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15172            memInfoBuilder.append(" kB swap total, ");
15173            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15174            memInfoBuilder.append(" kB swap free\n");
15175        }
15176        final long[] ksm = getKsmInfo();
15177        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15178                || ksm[KSM_VOLATILE] != 0) {
15179            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15180            memInfoBuilder.append(" kB saved from shared ");
15181            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15182            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15183            memInfoBuilder.append(" kB unshared; ");
15184            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15185        }
15186        memInfoBuilder.append("  Free RAM: ");
15187        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15188                + memInfo.getFreeSizeKb());
15189        memInfoBuilder.append(" kB\n");
15190        memInfoBuilder.append("  Used RAM: ");
15191        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15192        memInfoBuilder.append(" kB\n");
15193        memInfoBuilder.append("  Lost RAM: ");
15194        memInfoBuilder.append(memInfo.getTotalSizeKb()
15195                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15196                - memInfo.getKernelUsedSizeKb());
15197        memInfoBuilder.append(" kB\n");
15198        Slog.i(TAG, "Low on memory:");
15199        Slog.i(TAG, shortNativeBuilder.toString());
15200        Slog.i(TAG, fullJavaBuilder.toString());
15201        Slog.i(TAG, memInfoBuilder.toString());
15202
15203        StringBuilder dropBuilder = new StringBuilder(1024);
15204        /*
15205        StringWriter oomSw = new StringWriter();
15206        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15207        StringWriter catSw = new StringWriter();
15208        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15209        String[] emptyArgs = new String[] { };
15210        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15211        oomPw.flush();
15212        String oomString = oomSw.toString();
15213        */
15214        dropBuilder.append("Low on memory:");
15215        dropBuilder.append(stack);
15216        dropBuilder.append('\n');
15217        dropBuilder.append(fullNativeBuilder);
15218        dropBuilder.append(fullJavaBuilder);
15219        dropBuilder.append('\n');
15220        dropBuilder.append(memInfoBuilder);
15221        dropBuilder.append('\n');
15222        /*
15223        dropBuilder.append(oomString);
15224        dropBuilder.append('\n');
15225        */
15226        StringWriter catSw = new StringWriter();
15227        synchronized (ActivityManagerService.this) {
15228            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15229            String[] emptyArgs = new String[] { };
15230            catPw.println();
15231            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15232            catPw.println();
15233            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15234                    false, false, null);
15235            catPw.println();
15236            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15237            catPw.flush();
15238        }
15239        dropBuilder.append(catSw.toString());
15240        addErrorToDropBox("lowmem", null, "system_server", null,
15241                null, tag.toString(), dropBuilder.toString(), null, null);
15242        //Slog.i(TAG, "Sent to dropbox:");
15243        //Slog.i(TAG, dropBuilder.toString());
15244        synchronized (ActivityManagerService.this) {
15245            long now = SystemClock.uptimeMillis();
15246            if (mLastMemUsageReportTime < now) {
15247                mLastMemUsageReportTime = now;
15248            }
15249        }
15250    }
15251
15252    /**
15253     * Searches array of arguments for the specified string
15254     * @param args array of argument strings
15255     * @param value value to search for
15256     * @return true if the value is contained in the array
15257     */
15258    private static boolean scanArgs(String[] args, String value) {
15259        if (args != null) {
15260            for (String arg : args) {
15261                if (value.equals(arg)) {
15262                    return true;
15263                }
15264            }
15265        }
15266        return false;
15267    }
15268
15269    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15270            ContentProviderRecord cpr, boolean always) {
15271        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15272
15273        if (!inLaunching || always) {
15274            synchronized (cpr) {
15275                cpr.launchingApp = null;
15276                cpr.notifyAll();
15277            }
15278            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15279            String names[] = cpr.info.authority.split(";");
15280            for (int j = 0; j < names.length; j++) {
15281                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15282            }
15283        }
15284
15285        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15286            ContentProviderConnection conn = cpr.connections.get(i);
15287            if (conn.waiting) {
15288                // If this connection is waiting for the provider, then we don't
15289                // need to mess with its process unless we are always removing
15290                // or for some reason the provider is not currently launching.
15291                if (inLaunching && !always) {
15292                    continue;
15293                }
15294            }
15295            ProcessRecord capp = conn.client;
15296            conn.dead = true;
15297            if (conn.stableCount > 0) {
15298                if (!capp.persistent && capp.thread != null
15299                        && capp.pid != 0
15300                        && capp.pid != MY_PID) {
15301                    capp.kill("depends on provider "
15302                            + cpr.name.flattenToShortString()
15303                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15304                }
15305            } else if (capp.thread != null && conn.provider.provider != null) {
15306                try {
15307                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15308                } catch (RemoteException e) {
15309                }
15310                // In the protocol here, we don't expect the client to correctly
15311                // clean up this connection, we'll just remove it.
15312                cpr.connections.remove(i);
15313                if (conn.client.conProviders.remove(conn)) {
15314                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15315                }
15316            }
15317        }
15318
15319        if (inLaunching && always) {
15320            mLaunchingProviders.remove(cpr);
15321        }
15322        return inLaunching;
15323    }
15324
15325    /**
15326     * Main code for cleaning up a process when it has gone away.  This is
15327     * called both as a result of the process dying, or directly when stopping
15328     * a process when running in single process mode.
15329     *
15330     * @return Returns true if the given process has been restarted, so the
15331     * app that was passed in must remain on the process lists.
15332     */
15333    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15334            boolean restarting, boolean allowRestart, int index) {
15335        if (index >= 0) {
15336            removeLruProcessLocked(app);
15337            ProcessList.remove(app.pid);
15338        }
15339
15340        mProcessesToGc.remove(app);
15341        mPendingPssProcesses.remove(app);
15342
15343        // Dismiss any open dialogs.
15344        if (app.crashDialog != null && !app.forceCrashReport) {
15345            app.crashDialog.dismiss();
15346            app.crashDialog = null;
15347        }
15348        if (app.anrDialog != null) {
15349            app.anrDialog.dismiss();
15350            app.anrDialog = null;
15351        }
15352        if (app.waitDialog != null) {
15353            app.waitDialog.dismiss();
15354            app.waitDialog = null;
15355        }
15356
15357        app.crashing = false;
15358        app.notResponding = false;
15359
15360        app.resetPackageList(mProcessStats);
15361        app.unlinkDeathRecipient();
15362        app.makeInactive(mProcessStats);
15363        app.waitingToKill = null;
15364        app.forcingToForeground = null;
15365        updateProcessForegroundLocked(app, false, false);
15366        app.foregroundActivities = false;
15367        app.hasShownUi = false;
15368        app.treatLikeActivity = false;
15369        app.hasAboveClient = false;
15370        app.hasClientActivities = false;
15371
15372        mServices.killServicesLocked(app, allowRestart);
15373
15374        boolean restart = false;
15375
15376        // Remove published content providers.
15377        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15378            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15379            final boolean always = app.bad || !allowRestart;
15380            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15381            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15382                // We left the provider in the launching list, need to
15383                // restart it.
15384                restart = true;
15385            }
15386
15387            cpr.provider = null;
15388            cpr.proc = null;
15389        }
15390        app.pubProviders.clear();
15391
15392        // Take care of any launching providers waiting for this process.
15393        if (checkAppInLaunchingProvidersLocked(app, false)) {
15394            restart = true;
15395        }
15396
15397        // Unregister from connected content providers.
15398        if (!app.conProviders.isEmpty()) {
15399            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15400                ContentProviderConnection conn = app.conProviders.get(i);
15401                conn.provider.connections.remove(conn);
15402                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15403                        conn.provider.name);
15404            }
15405            app.conProviders.clear();
15406        }
15407
15408        // At this point there may be remaining entries in mLaunchingProviders
15409        // where we were the only one waiting, so they are no longer of use.
15410        // Look for these and clean up if found.
15411        // XXX Commented out for now.  Trying to figure out a way to reproduce
15412        // the actual situation to identify what is actually going on.
15413        if (false) {
15414            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15415                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15416                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15417                    synchronized (cpr) {
15418                        cpr.launchingApp = null;
15419                        cpr.notifyAll();
15420                    }
15421                }
15422            }
15423        }
15424
15425        skipCurrentReceiverLocked(app);
15426
15427        // Unregister any receivers.
15428        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15429            removeReceiverLocked(app.receivers.valueAt(i));
15430        }
15431        app.receivers.clear();
15432
15433        // If the app is undergoing backup, tell the backup manager about it
15434        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15435            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15436                    + mBackupTarget.appInfo + " died during backup");
15437            try {
15438                IBackupManager bm = IBackupManager.Stub.asInterface(
15439                        ServiceManager.getService(Context.BACKUP_SERVICE));
15440                bm.agentDisconnected(app.info.packageName);
15441            } catch (RemoteException e) {
15442                // can't happen; backup manager is local
15443            }
15444        }
15445
15446        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15447            ProcessChangeItem item = mPendingProcessChanges.get(i);
15448            if (item.pid == app.pid) {
15449                mPendingProcessChanges.remove(i);
15450                mAvailProcessChanges.add(item);
15451            }
15452        }
15453        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15454
15455        // If the caller is restarting this app, then leave it in its
15456        // current lists and let the caller take care of it.
15457        if (restarting) {
15458            return false;
15459        }
15460
15461        if (!app.persistent || app.isolated) {
15462            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15463                    "Removing non-persistent process during cleanup: " + app);
15464            removeProcessNameLocked(app.processName, app.uid);
15465            if (mHeavyWeightProcess == app) {
15466                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15467                        mHeavyWeightProcess.userId, 0));
15468                mHeavyWeightProcess = null;
15469            }
15470        } else if (!app.removed) {
15471            // This app is persistent, so we need to keep its record around.
15472            // If it is not already on the pending app list, add it there
15473            // and start a new process for it.
15474            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15475                mPersistentStartingProcesses.add(app);
15476                restart = true;
15477            }
15478        }
15479        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15480                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15481        mProcessesOnHold.remove(app);
15482
15483        if (app == mHomeProcess) {
15484            mHomeProcess = null;
15485        }
15486        if (app == mPreviousProcess) {
15487            mPreviousProcess = null;
15488        }
15489
15490        if (restart && !app.isolated) {
15491            // We have components that still need to be running in the
15492            // process, so re-launch it.
15493            if (index < 0) {
15494                ProcessList.remove(app.pid);
15495            }
15496            addProcessNameLocked(app);
15497            startProcessLocked(app, "restart", app.processName);
15498            return true;
15499        } else if (app.pid > 0 && app.pid != MY_PID) {
15500            // Goodbye!
15501            boolean removed;
15502            synchronized (mPidsSelfLocked) {
15503                mPidsSelfLocked.remove(app.pid);
15504                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15505            }
15506            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15507            if (app.isolated) {
15508                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15509            }
15510            app.setPid(0);
15511        }
15512        return false;
15513    }
15514
15515    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15516        // Look through the content providers we are waiting to have launched,
15517        // and if any run in this process then either schedule a restart of
15518        // the process or kill the client waiting for it if this process has
15519        // gone bad.
15520        boolean restart = false;
15521        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15522            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15523            if (cpr.launchingApp == app) {
15524                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15525                    restart = true;
15526                } else {
15527                    removeDyingProviderLocked(app, cpr, true);
15528                }
15529            }
15530        }
15531        return restart;
15532    }
15533
15534    // =========================================================
15535    // SERVICES
15536    // =========================================================
15537
15538    @Override
15539    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15540            int flags) {
15541        enforceNotIsolatedCaller("getServices");
15542        synchronized (this) {
15543            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15544        }
15545    }
15546
15547    @Override
15548    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15549        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15550        synchronized (this) {
15551            return mServices.getRunningServiceControlPanelLocked(name);
15552        }
15553    }
15554
15555    @Override
15556    public ComponentName startService(IApplicationThread caller, Intent service,
15557            String resolvedType, String callingPackage, int userId)
15558            throws TransactionTooLargeException {
15559        enforceNotIsolatedCaller("startService");
15560        // Refuse possible leaked file descriptors
15561        if (service != null && service.hasFileDescriptors() == true) {
15562            throw new IllegalArgumentException("File descriptors passed in Intent");
15563        }
15564
15565        if (callingPackage == null) {
15566            throw new IllegalArgumentException("callingPackage cannot be null");
15567        }
15568
15569        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15570                "startService: " + service + " type=" + resolvedType);
15571        synchronized(this) {
15572            final int callingPid = Binder.getCallingPid();
15573            final int callingUid = Binder.getCallingUid();
15574            final long origId = Binder.clearCallingIdentity();
15575            ComponentName res = mServices.startServiceLocked(caller, service,
15576                    resolvedType, callingPid, callingUid, callingPackage, userId);
15577            Binder.restoreCallingIdentity(origId);
15578            return res;
15579        }
15580    }
15581
15582    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15583            String callingPackage, int userId)
15584            throws TransactionTooLargeException {
15585        synchronized(this) {
15586            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15587                    "startServiceInPackage: " + service + " type=" + resolvedType);
15588            final long origId = Binder.clearCallingIdentity();
15589            ComponentName res = mServices.startServiceLocked(null, service,
15590                    resolvedType, -1, uid, callingPackage, userId);
15591            Binder.restoreCallingIdentity(origId);
15592            return res;
15593        }
15594    }
15595
15596    @Override
15597    public int stopService(IApplicationThread caller, Intent service,
15598            String resolvedType, int userId) {
15599        enforceNotIsolatedCaller("stopService");
15600        // Refuse possible leaked file descriptors
15601        if (service != null && service.hasFileDescriptors() == true) {
15602            throw new IllegalArgumentException("File descriptors passed in Intent");
15603        }
15604
15605        synchronized(this) {
15606            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15607        }
15608    }
15609
15610    @Override
15611    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15612        enforceNotIsolatedCaller("peekService");
15613        // Refuse possible leaked file descriptors
15614        if (service != null && service.hasFileDescriptors() == true) {
15615            throw new IllegalArgumentException("File descriptors passed in Intent");
15616        }
15617
15618        if (callingPackage == null) {
15619            throw new IllegalArgumentException("callingPackage cannot be null");
15620        }
15621
15622        synchronized(this) {
15623            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15624        }
15625    }
15626
15627    @Override
15628    public boolean stopServiceToken(ComponentName className, IBinder token,
15629            int startId) {
15630        synchronized(this) {
15631            return mServices.stopServiceTokenLocked(className, token, startId);
15632        }
15633    }
15634
15635    @Override
15636    public void setServiceForeground(ComponentName className, IBinder token,
15637            int id, Notification notification, boolean removeNotification) {
15638        synchronized(this) {
15639            mServices.setServiceForegroundLocked(className, token, id, notification,
15640                    removeNotification);
15641        }
15642    }
15643
15644    @Override
15645    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15646            boolean requireFull, String name, String callerPackage) {
15647        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15648                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15649    }
15650
15651    int unsafeConvertIncomingUser(int userId) {
15652        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15653                ? mCurrentUserId : userId;
15654    }
15655
15656    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15657            int allowMode, String name, String callerPackage) {
15658        final int callingUserId = UserHandle.getUserId(callingUid);
15659        if (callingUserId == userId) {
15660            return userId;
15661        }
15662
15663        // Note that we may be accessing mCurrentUserId outside of a lock...
15664        // shouldn't be a big deal, if this is being called outside
15665        // of a locked context there is intrinsically a race with
15666        // the value the caller will receive and someone else changing it.
15667        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15668        // we will switch to the calling user if access to the current user fails.
15669        int targetUserId = unsafeConvertIncomingUser(userId);
15670
15671        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15672            final boolean allow;
15673            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15674                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15675                // If the caller has this permission, they always pass go.  And collect $200.
15676                allow = true;
15677            } else if (allowMode == ALLOW_FULL_ONLY) {
15678                // We require full access, sucks to be you.
15679                allow = false;
15680            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15681                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15682                // If the caller does not have either permission, they are always doomed.
15683                allow = false;
15684            } else if (allowMode == ALLOW_NON_FULL) {
15685                // We are blanket allowing non-full access, you lucky caller!
15686                allow = true;
15687            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15688                // We may or may not allow this depending on whether the two users are
15689                // in the same profile.
15690                synchronized (mUserProfileGroupIdsSelfLocked) {
15691                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15692                            UserInfo.NO_PROFILE_GROUP_ID);
15693                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15694                            UserInfo.NO_PROFILE_GROUP_ID);
15695                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15696                            && callingProfile == targetProfile;
15697                }
15698            } else {
15699                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15700            }
15701            if (!allow) {
15702                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15703                    // In this case, they would like to just execute as their
15704                    // owner user instead of failing.
15705                    targetUserId = callingUserId;
15706                } else {
15707                    StringBuilder builder = new StringBuilder(128);
15708                    builder.append("Permission Denial: ");
15709                    builder.append(name);
15710                    if (callerPackage != null) {
15711                        builder.append(" from ");
15712                        builder.append(callerPackage);
15713                    }
15714                    builder.append(" asks to run as user ");
15715                    builder.append(userId);
15716                    builder.append(" but is calling from user ");
15717                    builder.append(UserHandle.getUserId(callingUid));
15718                    builder.append("; this requires ");
15719                    builder.append(INTERACT_ACROSS_USERS_FULL);
15720                    if (allowMode != ALLOW_FULL_ONLY) {
15721                        builder.append(" or ");
15722                        builder.append(INTERACT_ACROSS_USERS);
15723                    }
15724                    String msg = builder.toString();
15725                    Slog.w(TAG, msg);
15726                    throw new SecurityException(msg);
15727                }
15728            }
15729        }
15730        if (!allowAll && targetUserId < 0) {
15731            throw new IllegalArgumentException(
15732                    "Call does not support special user #" + targetUserId);
15733        }
15734        // Check shell permission
15735        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15736            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15737                    targetUserId)) {
15738                throw new SecurityException("Shell does not have permission to access user "
15739                        + targetUserId + "\n " + Debug.getCallers(3));
15740            }
15741        }
15742        return targetUserId;
15743    }
15744
15745    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15746            String className, int flags) {
15747        boolean result = false;
15748        // For apps that don't have pre-defined UIDs, check for permission
15749        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15750            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15751                if (ActivityManager.checkUidPermission(
15752                        INTERACT_ACROSS_USERS,
15753                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15754                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15755                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15756                            + " requests FLAG_SINGLE_USER, but app does not hold "
15757                            + INTERACT_ACROSS_USERS;
15758                    Slog.w(TAG, msg);
15759                    throw new SecurityException(msg);
15760                }
15761                // Permission passed
15762                result = true;
15763            }
15764        } else if ("system".equals(componentProcessName)) {
15765            result = true;
15766        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15767            // Phone app and persistent apps are allowed to export singleuser providers.
15768            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15769                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15770        }
15771        if (DEBUG_MU) Slog.v(TAG_MU,
15772                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15773                + Integer.toHexString(flags) + ") = " + result);
15774        return result;
15775    }
15776
15777    /**
15778     * Checks to see if the caller is in the same app as the singleton
15779     * component, or the component is in a special app. It allows special apps
15780     * to export singleton components but prevents exporting singleton
15781     * components for regular apps.
15782     */
15783    boolean isValidSingletonCall(int callingUid, int componentUid) {
15784        int componentAppId = UserHandle.getAppId(componentUid);
15785        return UserHandle.isSameApp(callingUid, componentUid)
15786                || componentAppId == Process.SYSTEM_UID
15787                || componentAppId == Process.PHONE_UID
15788                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15789                        == PackageManager.PERMISSION_GRANTED;
15790    }
15791
15792    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15793            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15794            int userId) throws TransactionTooLargeException {
15795        enforceNotIsolatedCaller("bindService");
15796
15797        // Refuse possible leaked file descriptors
15798        if (service != null && service.hasFileDescriptors() == true) {
15799            throw new IllegalArgumentException("File descriptors passed in Intent");
15800        }
15801
15802        if (callingPackage == null) {
15803            throw new IllegalArgumentException("callingPackage cannot be null");
15804        }
15805
15806        synchronized(this) {
15807            return mServices.bindServiceLocked(caller, token, service,
15808                    resolvedType, connection, flags, callingPackage, userId);
15809        }
15810    }
15811
15812    public boolean unbindService(IServiceConnection connection) {
15813        synchronized (this) {
15814            return mServices.unbindServiceLocked(connection);
15815        }
15816    }
15817
15818    public void publishService(IBinder token, Intent intent, IBinder service) {
15819        // Refuse possible leaked file descriptors
15820        if (intent != null && intent.hasFileDescriptors() == true) {
15821            throw new IllegalArgumentException("File descriptors passed in Intent");
15822        }
15823
15824        synchronized(this) {
15825            if (!(token instanceof ServiceRecord)) {
15826                throw new IllegalArgumentException("Invalid service token");
15827            }
15828            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15829        }
15830    }
15831
15832    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15833        // Refuse possible leaked file descriptors
15834        if (intent != null && intent.hasFileDescriptors() == true) {
15835            throw new IllegalArgumentException("File descriptors passed in Intent");
15836        }
15837
15838        synchronized(this) {
15839            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15840        }
15841    }
15842
15843    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15844        synchronized(this) {
15845            if (!(token instanceof ServiceRecord)) {
15846                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15847                throw new IllegalArgumentException("Invalid service token");
15848            }
15849            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15850        }
15851    }
15852
15853    // =========================================================
15854    // BACKUP AND RESTORE
15855    // =========================================================
15856
15857    // Cause the target app to be launched if necessary and its backup agent
15858    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15859    // activity manager to announce its creation.
15860    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15861        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15862                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15863        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15864
15865        synchronized(this) {
15866            // !!! TODO: currently no check here that we're already bound
15867            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15868            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15869            synchronized (stats) {
15870                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15871            }
15872
15873            // Backup agent is now in use, its package can't be stopped.
15874            try {
15875                AppGlobals.getPackageManager().setPackageStoppedState(
15876                        app.packageName, false, UserHandle.getUserId(app.uid));
15877            } catch (RemoteException e) {
15878            } catch (IllegalArgumentException e) {
15879                Slog.w(TAG, "Failed trying to unstop package "
15880                        + app.packageName + ": " + e);
15881            }
15882
15883            BackupRecord r = new BackupRecord(ss, app, backupMode);
15884            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15885                    ? new ComponentName(app.packageName, app.backupAgentName)
15886                    : new ComponentName("android", "FullBackupAgent");
15887            // startProcessLocked() returns existing proc's record if it's already running
15888            ProcessRecord proc = startProcessLocked(app.processName, app,
15889                    false, 0, "backup", hostingName, false, false, false);
15890            if (proc == null) {
15891                Slog.e(TAG, "Unable to start backup agent process " + r);
15892                return false;
15893            }
15894
15895            r.app = proc;
15896            mBackupTarget = r;
15897            mBackupAppName = app.packageName;
15898
15899            // Try not to kill the process during backup
15900            updateOomAdjLocked(proc);
15901
15902            // If the process is already attached, schedule the creation of the backup agent now.
15903            // If it is not yet live, this will be done when it attaches to the framework.
15904            if (proc.thread != null) {
15905                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15906                try {
15907                    proc.thread.scheduleCreateBackupAgent(app,
15908                            compatibilityInfoForPackageLocked(app), backupMode);
15909                } catch (RemoteException e) {
15910                    // Will time out on the backup manager side
15911                }
15912            } else {
15913                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15914            }
15915            // Invariants: at this point, the target app process exists and the application
15916            // is either already running or in the process of coming up.  mBackupTarget and
15917            // mBackupAppName describe the app, so that when it binds back to the AM we
15918            // know that it's scheduled for a backup-agent operation.
15919        }
15920
15921        return true;
15922    }
15923
15924    @Override
15925    public void clearPendingBackup() {
15926        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15927        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15928
15929        synchronized (this) {
15930            mBackupTarget = null;
15931            mBackupAppName = null;
15932        }
15933    }
15934
15935    // A backup agent has just come up
15936    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15937        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15938                + " = " + agent);
15939
15940        synchronized(this) {
15941            if (!agentPackageName.equals(mBackupAppName)) {
15942                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15943                return;
15944            }
15945        }
15946
15947        long oldIdent = Binder.clearCallingIdentity();
15948        try {
15949            IBackupManager bm = IBackupManager.Stub.asInterface(
15950                    ServiceManager.getService(Context.BACKUP_SERVICE));
15951            bm.agentConnected(agentPackageName, agent);
15952        } catch (RemoteException e) {
15953            // can't happen; the backup manager service is local
15954        } catch (Exception e) {
15955            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15956            e.printStackTrace();
15957        } finally {
15958            Binder.restoreCallingIdentity(oldIdent);
15959        }
15960    }
15961
15962    // done with this agent
15963    public void unbindBackupAgent(ApplicationInfo appInfo) {
15964        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15965        if (appInfo == null) {
15966            Slog.w(TAG, "unbind backup agent for null app");
15967            return;
15968        }
15969
15970        synchronized(this) {
15971            try {
15972                if (mBackupAppName == null) {
15973                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15974                    return;
15975                }
15976
15977                if (!mBackupAppName.equals(appInfo.packageName)) {
15978                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15979                    return;
15980                }
15981
15982                // Not backing this app up any more; reset its OOM adjustment
15983                final ProcessRecord proc = mBackupTarget.app;
15984                updateOomAdjLocked(proc);
15985
15986                // If the app crashed during backup, 'thread' will be null here
15987                if (proc.thread != null) {
15988                    try {
15989                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15990                                compatibilityInfoForPackageLocked(appInfo));
15991                    } catch (Exception e) {
15992                        Slog.e(TAG, "Exception when unbinding backup agent:");
15993                        e.printStackTrace();
15994                    }
15995                }
15996            } finally {
15997                mBackupTarget = null;
15998                mBackupAppName = null;
15999            }
16000        }
16001    }
16002    // =========================================================
16003    // BROADCASTS
16004    // =========================================================
16005
16006    boolean isPendingBroadcastProcessLocked(int pid) {
16007        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16008                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16009    }
16010
16011    void skipPendingBroadcastLocked(int pid) {
16012            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16013            for (BroadcastQueue queue : mBroadcastQueues) {
16014                queue.skipPendingBroadcastLocked(pid);
16015            }
16016    }
16017
16018    // The app just attached; send any pending broadcasts that it should receive
16019    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16020        boolean didSomething = false;
16021        for (BroadcastQueue queue : mBroadcastQueues) {
16022            didSomething |= queue.sendPendingBroadcastsLocked(app);
16023        }
16024        return didSomething;
16025    }
16026
16027    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16028            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16029        enforceNotIsolatedCaller("registerReceiver");
16030        ArrayList<Intent> stickyIntents = null;
16031        ProcessRecord callerApp = null;
16032        int callingUid;
16033        int callingPid;
16034        synchronized(this) {
16035            if (caller != null) {
16036                callerApp = getRecordForAppLocked(caller);
16037                if (callerApp == null) {
16038                    throw new SecurityException(
16039                            "Unable to find app for caller " + caller
16040                            + " (pid=" + Binder.getCallingPid()
16041                            + ") when registering receiver " + receiver);
16042                }
16043                if (callerApp.info.uid != Process.SYSTEM_UID &&
16044                        !callerApp.pkgList.containsKey(callerPackage) &&
16045                        !"android".equals(callerPackage)) {
16046                    throw new SecurityException("Given caller package " + callerPackage
16047                            + " is not running in process " + callerApp);
16048                }
16049                callingUid = callerApp.info.uid;
16050                callingPid = callerApp.pid;
16051            } else {
16052                callerPackage = null;
16053                callingUid = Binder.getCallingUid();
16054                callingPid = Binder.getCallingPid();
16055            }
16056
16057            userId = handleIncomingUser(callingPid, callingUid, userId,
16058                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16059
16060            Iterator<String> actions = filter.actionsIterator();
16061            if (actions == null) {
16062                ArrayList<String> noAction = new ArrayList<String>(1);
16063                noAction.add(null);
16064                actions = noAction.iterator();
16065            }
16066
16067            // Collect stickies of users
16068            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16069            while (actions.hasNext()) {
16070                String action = actions.next();
16071                for (int id : userIds) {
16072                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16073                    if (stickies != null) {
16074                        ArrayList<Intent> intents = stickies.get(action);
16075                        if (intents != null) {
16076                            if (stickyIntents == null) {
16077                                stickyIntents = new ArrayList<Intent>();
16078                            }
16079                            stickyIntents.addAll(intents);
16080                        }
16081                    }
16082                }
16083            }
16084        }
16085
16086        ArrayList<Intent> allSticky = null;
16087        if (stickyIntents != null) {
16088            final ContentResolver resolver = mContext.getContentResolver();
16089            // Look for any matching sticky broadcasts...
16090            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16091                Intent intent = stickyIntents.get(i);
16092                // If intent has scheme "content", it will need to acccess
16093                // provider that needs to lock mProviderMap in ActivityThread
16094                // and also it may need to wait application response, so we
16095                // cannot lock ActivityManagerService here.
16096                if (filter.match(resolver, intent, true, TAG) >= 0) {
16097                    if (allSticky == null) {
16098                        allSticky = new ArrayList<Intent>();
16099                    }
16100                    allSticky.add(intent);
16101                }
16102            }
16103        }
16104
16105        // The first sticky in the list is returned directly back to the client.
16106        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16107        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16108        if (receiver == null) {
16109            return sticky;
16110        }
16111
16112        synchronized (this) {
16113            if (callerApp != null && (callerApp.thread == null
16114                    || callerApp.thread.asBinder() != caller.asBinder())) {
16115                // Original caller already died
16116                return null;
16117            }
16118            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16119            if (rl == null) {
16120                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16121                        userId, receiver);
16122                if (rl.app != null) {
16123                    rl.app.receivers.add(rl);
16124                } else {
16125                    try {
16126                        receiver.asBinder().linkToDeath(rl, 0);
16127                    } catch (RemoteException e) {
16128                        return sticky;
16129                    }
16130                    rl.linkedToDeath = true;
16131                }
16132                mRegisteredReceivers.put(receiver.asBinder(), rl);
16133            } else if (rl.uid != callingUid) {
16134                throw new IllegalArgumentException(
16135                        "Receiver requested to register for uid " + callingUid
16136                        + " was previously registered for uid " + rl.uid);
16137            } else if (rl.pid != callingPid) {
16138                throw new IllegalArgumentException(
16139                        "Receiver requested to register for pid " + callingPid
16140                        + " was previously registered for pid " + rl.pid);
16141            } else if (rl.userId != userId) {
16142                throw new IllegalArgumentException(
16143                        "Receiver requested to register for user " + userId
16144                        + " was previously registered for user " + rl.userId);
16145            }
16146            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16147                    permission, callingUid, userId);
16148            rl.add(bf);
16149            if (!bf.debugCheck()) {
16150                Slog.w(TAG, "==> For Dynamic broadcast");
16151            }
16152            mReceiverResolver.addFilter(bf);
16153
16154            // Enqueue broadcasts for all existing stickies that match
16155            // this filter.
16156            if (allSticky != null) {
16157                ArrayList receivers = new ArrayList();
16158                receivers.add(bf);
16159
16160                final int stickyCount = allSticky.size();
16161                for (int i = 0; i < stickyCount; i++) {
16162                    Intent intent = allSticky.get(i);
16163                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16164                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16165                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16166                            null, 0, null, null, false, true, true, -1);
16167                    queue.enqueueParallelBroadcastLocked(r);
16168                    queue.scheduleBroadcastsLocked();
16169                }
16170            }
16171
16172            return sticky;
16173        }
16174    }
16175
16176    public void unregisterReceiver(IIntentReceiver receiver) {
16177        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16178
16179        final long origId = Binder.clearCallingIdentity();
16180        try {
16181            boolean doTrim = false;
16182
16183            synchronized(this) {
16184                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16185                if (rl != null) {
16186                    final BroadcastRecord r = rl.curBroadcast;
16187                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16188                        final boolean doNext = r.queue.finishReceiverLocked(
16189                                r, r.resultCode, r.resultData, r.resultExtras,
16190                                r.resultAbort, false);
16191                        if (doNext) {
16192                            doTrim = true;
16193                            r.queue.processNextBroadcast(false);
16194                        }
16195                    }
16196
16197                    if (rl.app != null) {
16198                        rl.app.receivers.remove(rl);
16199                    }
16200                    removeReceiverLocked(rl);
16201                    if (rl.linkedToDeath) {
16202                        rl.linkedToDeath = false;
16203                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16204                    }
16205                }
16206            }
16207
16208            // If we actually concluded any broadcasts, we might now be able
16209            // to trim the recipients' apps from our working set
16210            if (doTrim) {
16211                trimApplications();
16212                return;
16213            }
16214
16215        } finally {
16216            Binder.restoreCallingIdentity(origId);
16217        }
16218    }
16219
16220    void removeReceiverLocked(ReceiverList rl) {
16221        mRegisteredReceivers.remove(rl.receiver.asBinder());
16222        for (int i = rl.size() - 1; i >= 0; i--) {
16223            mReceiverResolver.removeFilter(rl.get(i));
16224        }
16225    }
16226
16227    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16228        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16229            ProcessRecord r = mLruProcesses.get(i);
16230            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16231                try {
16232                    r.thread.dispatchPackageBroadcast(cmd, packages);
16233                } catch (RemoteException ex) {
16234                }
16235            }
16236        }
16237    }
16238
16239    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16240            int callingUid, int[] users) {
16241        List<ResolveInfo> receivers = null;
16242        try {
16243            HashSet<ComponentName> singleUserReceivers = null;
16244            boolean scannedFirstReceivers = false;
16245            for (int user : users) {
16246                // Skip users that have Shell restrictions
16247                if (callingUid == Process.SHELL_UID
16248                        && getUserManagerLocked().hasUserRestriction(
16249                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16250                    continue;
16251                }
16252                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16253                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16254                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16255                    // If this is not the primary user, we need to check for
16256                    // any receivers that should be filtered out.
16257                    for (int i=0; i<newReceivers.size(); i++) {
16258                        ResolveInfo ri = newReceivers.get(i);
16259                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16260                            newReceivers.remove(i);
16261                            i--;
16262                        }
16263                    }
16264                }
16265                if (newReceivers != null && newReceivers.size() == 0) {
16266                    newReceivers = null;
16267                }
16268                if (receivers == null) {
16269                    receivers = newReceivers;
16270                } else if (newReceivers != null) {
16271                    // We need to concatenate the additional receivers
16272                    // found with what we have do far.  This would be easy,
16273                    // but we also need to de-dup any receivers that are
16274                    // singleUser.
16275                    if (!scannedFirstReceivers) {
16276                        // Collect any single user receivers we had already retrieved.
16277                        scannedFirstReceivers = true;
16278                        for (int i=0; i<receivers.size(); i++) {
16279                            ResolveInfo ri = receivers.get(i);
16280                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16281                                ComponentName cn = new ComponentName(
16282                                        ri.activityInfo.packageName, ri.activityInfo.name);
16283                                if (singleUserReceivers == null) {
16284                                    singleUserReceivers = new HashSet<ComponentName>();
16285                                }
16286                                singleUserReceivers.add(cn);
16287                            }
16288                        }
16289                    }
16290                    // Add the new results to the existing results, tracking
16291                    // and de-dupping single user receivers.
16292                    for (int i=0; i<newReceivers.size(); i++) {
16293                        ResolveInfo ri = newReceivers.get(i);
16294                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16295                            ComponentName cn = new ComponentName(
16296                                    ri.activityInfo.packageName, ri.activityInfo.name);
16297                            if (singleUserReceivers == null) {
16298                                singleUserReceivers = new HashSet<ComponentName>();
16299                            }
16300                            if (!singleUserReceivers.contains(cn)) {
16301                                singleUserReceivers.add(cn);
16302                                receivers.add(ri);
16303                            }
16304                        } else {
16305                            receivers.add(ri);
16306                        }
16307                    }
16308                }
16309            }
16310        } catch (RemoteException ex) {
16311            // pm is in same process, this will never happen.
16312        }
16313        return receivers;
16314    }
16315
16316    private final int broadcastIntentLocked(ProcessRecord callerApp,
16317            String callerPackage, Intent intent, String resolvedType,
16318            IIntentReceiver resultTo, int resultCode, String resultData,
16319            Bundle resultExtras, String requiredPermission, int appOp, Bundle options,
16320            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16321        intent = new Intent(intent);
16322
16323        // By default broadcasts do not go to stopped apps.
16324        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16325
16326        // If we have not finished booting, don't allow this to launch new processes.
16327        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16328            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16329        }
16330
16331        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16332                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16333                + " ordered=" + ordered + " userid=" + userId);
16334        if ((resultTo != null) && !ordered) {
16335            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16336        }
16337
16338        userId = handleIncomingUser(callingPid, callingUid, userId,
16339                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16340
16341        // Make sure that the user who is receiving this broadcast is running.
16342        // If not, we will just skip it. Make an exception for shutdown broadcasts
16343        // and upgrade steps.
16344
16345        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16346            if ((callingUid != Process.SYSTEM_UID
16347                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16348                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16349                Slog.w(TAG, "Skipping broadcast of " + intent
16350                        + ": user " + userId + " is stopped");
16351                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16352            }
16353        }
16354
16355        BroadcastOptions brOptions = null;
16356        if (options != null) {
16357            brOptions = new BroadcastOptions(options);
16358            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16359                // See if the caller is allowed to do this.  Note we are checking against
16360                // the actual real caller (not whoever provided the operation as say a
16361                // PendingIntent), because that who is actually supplied the arguments.
16362                if (checkComponentPermission(
16363                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16364                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16365                        != PackageManager.PERMISSION_GRANTED) {
16366                    String msg = "Permission Denial: " + intent.getAction()
16367                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16368                            + ", uid=" + callingUid + ")"
16369                            + " requires "
16370                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16371                    Slog.w(TAG, msg);
16372                    throw new SecurityException(msg);
16373                }
16374            }
16375        }
16376
16377        /*
16378         * Prevent non-system code (defined here to be non-persistent
16379         * processes) from sending protected broadcasts.
16380         */
16381        int callingAppId = UserHandle.getAppId(callingUid);
16382        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16383            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16384            || callingAppId == Process.NFC_UID || callingUid == 0) {
16385            // Always okay.
16386        } else if (callerApp == null || !callerApp.persistent) {
16387            try {
16388                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16389                        intent.getAction())) {
16390                    String msg = "Permission Denial: not allowed to send broadcast "
16391                            + intent.getAction() + " from pid="
16392                            + callingPid + ", uid=" + callingUid;
16393                    Slog.w(TAG, msg);
16394                    throw new SecurityException(msg);
16395                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16396                    // Special case for compatibility: we don't want apps to send this,
16397                    // but historically it has not been protected and apps may be using it
16398                    // to poke their own app widget.  So, instead of making it protected,
16399                    // just limit it to the caller.
16400                    if (callerApp == null) {
16401                        String msg = "Permission Denial: not allowed to send broadcast "
16402                                + intent.getAction() + " from unknown caller.";
16403                        Slog.w(TAG, msg);
16404                        throw new SecurityException(msg);
16405                    } else if (intent.getComponent() != null) {
16406                        // They are good enough to send to an explicit component...  verify
16407                        // it is being sent to the calling app.
16408                        if (!intent.getComponent().getPackageName().equals(
16409                                callerApp.info.packageName)) {
16410                            String msg = "Permission Denial: not allowed to send broadcast "
16411                                    + intent.getAction() + " to "
16412                                    + intent.getComponent().getPackageName() + " from "
16413                                    + callerApp.info.packageName;
16414                            Slog.w(TAG, msg);
16415                            throw new SecurityException(msg);
16416                        }
16417                    } else {
16418                        // Limit broadcast to their own package.
16419                        intent.setPackage(callerApp.info.packageName);
16420                    }
16421                }
16422            } catch (RemoteException e) {
16423                Slog.w(TAG, "Remote exception", e);
16424                return ActivityManager.BROADCAST_SUCCESS;
16425            }
16426        }
16427
16428        final String action = intent.getAction();
16429        if (action != null) {
16430            switch (action) {
16431                case Intent.ACTION_UID_REMOVED:
16432                case Intent.ACTION_PACKAGE_REMOVED:
16433                case Intent.ACTION_PACKAGE_CHANGED:
16434                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16435                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16436                    // Handle special intents: if this broadcast is from the package
16437                    // manager about a package being removed, we need to remove all of
16438                    // its activities from the history stack.
16439                    if (checkComponentPermission(
16440                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16441                            callingPid, callingUid, -1, true)
16442                            != PackageManager.PERMISSION_GRANTED) {
16443                        String msg = "Permission Denial: " + intent.getAction()
16444                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16445                                + ", uid=" + callingUid + ")"
16446                                + " requires "
16447                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16448                        Slog.w(TAG, msg);
16449                        throw new SecurityException(msg);
16450                    }
16451                    switch (action) {
16452                        case Intent.ACTION_UID_REMOVED:
16453                            final Bundle intentExtras = intent.getExtras();
16454                            final int uid = intentExtras != null
16455                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16456                            if (uid >= 0) {
16457                                mBatteryStatsService.removeUid(uid);
16458                                mAppOpsService.uidRemoved(uid);
16459                            }
16460                            break;
16461                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16462                            // If resources are unavailable just force stop all those packages
16463                            // and flush the attribute cache as well.
16464                            String list[] =
16465                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16466                            if (list != null && list.length > 0) {
16467                                for (int i = 0; i < list.length; i++) {
16468                                    forceStopPackageLocked(list[i], -1, false, true, true,
16469                                            false, false, userId, "storage unmount");
16470                                }
16471                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16472                                sendPackageBroadcastLocked(
16473                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16474                                        userId);
16475                            }
16476                            break;
16477                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16478                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16479                            break;
16480                        case Intent.ACTION_PACKAGE_REMOVED:
16481                        case Intent.ACTION_PACKAGE_CHANGED:
16482                            Uri data = intent.getData();
16483                            String ssp;
16484                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16485                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16486                                boolean fullUninstall = removed &&
16487                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16488                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16489                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16490                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16491                                            false, true, true, false, fullUninstall, userId,
16492                                            removed ? "pkg removed" : "pkg changed");
16493                                }
16494                                if (removed) {
16495                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16496                                            new String[] {ssp}, userId);
16497                                    if (fullUninstall) {
16498                                        mAppOpsService.packageRemoved(
16499                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16500
16501                                        // Remove all permissions granted from/to this package
16502                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16503
16504                                        removeTasksByPackageNameLocked(ssp, userId);
16505                                        mBatteryStatsService.notePackageUninstalled(ssp);
16506                                    }
16507                                } else {
16508                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16509                                            intent.getStringArrayExtra(
16510                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16511                                }
16512                            }
16513                            break;
16514                    }
16515                    break;
16516                case Intent.ACTION_PACKAGE_ADDED:
16517                    // Special case for adding a package: by default turn on compatibility mode.
16518                    Uri data = intent.getData();
16519                    String ssp;
16520                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16521                        final boolean replacing =
16522                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16523                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16524
16525                        try {
16526                            ApplicationInfo ai = AppGlobals.getPackageManager().
16527                                    getApplicationInfo(ssp, 0, 0);
16528                            mBatteryStatsService.notePackageInstalled(ssp,
16529                                    ai != null ? ai.versionCode : 0);
16530                        } catch (RemoteException e) {
16531                        }
16532                    }
16533                    break;
16534                case Intent.ACTION_TIMEZONE_CHANGED:
16535                    // If this is the time zone changed action, queue up a message that will reset
16536                    // the timezone of all currently running processes. This message will get
16537                    // queued up before the broadcast happens.
16538                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16539                    break;
16540                case Intent.ACTION_TIME_CHANGED:
16541                    // If the user set the time, let all running processes know.
16542                    final int is24Hour =
16543                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16544                                    : 0;
16545                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16546                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16547                    synchronized (stats) {
16548                        stats.noteCurrentTimeChangedLocked();
16549                    }
16550                    break;
16551                case Intent.ACTION_CLEAR_DNS_CACHE:
16552                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16553                    break;
16554                case Proxy.PROXY_CHANGE_ACTION:
16555                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16556                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16557                    break;
16558            }
16559        }
16560
16561        // Add to the sticky list if requested.
16562        if (sticky) {
16563            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16564                    callingPid, callingUid)
16565                    != PackageManager.PERMISSION_GRANTED) {
16566                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16567                        + callingPid + ", uid=" + callingUid
16568                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16569                Slog.w(TAG, msg);
16570                throw new SecurityException(msg);
16571            }
16572            if (requiredPermission != null) {
16573                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16574                        + " and enforce permission " + requiredPermission);
16575                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16576            }
16577            if (intent.getComponent() != null) {
16578                throw new SecurityException(
16579                        "Sticky broadcasts can't target a specific component");
16580            }
16581            // We use userId directly here, since the "all" target is maintained
16582            // as a separate set of sticky broadcasts.
16583            if (userId != UserHandle.USER_ALL) {
16584                // But first, if this is not a broadcast to all users, then
16585                // make sure it doesn't conflict with an existing broadcast to
16586                // all users.
16587                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16588                        UserHandle.USER_ALL);
16589                if (stickies != null) {
16590                    ArrayList<Intent> list = stickies.get(intent.getAction());
16591                    if (list != null) {
16592                        int N = list.size();
16593                        int i;
16594                        for (i=0; i<N; i++) {
16595                            if (intent.filterEquals(list.get(i))) {
16596                                throw new IllegalArgumentException(
16597                                        "Sticky broadcast " + intent + " for user "
16598                                        + userId + " conflicts with existing global broadcast");
16599                            }
16600                        }
16601                    }
16602                }
16603            }
16604            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16605            if (stickies == null) {
16606                stickies = new ArrayMap<>();
16607                mStickyBroadcasts.put(userId, stickies);
16608            }
16609            ArrayList<Intent> list = stickies.get(intent.getAction());
16610            if (list == null) {
16611                list = new ArrayList<>();
16612                stickies.put(intent.getAction(), list);
16613            }
16614            final int stickiesCount = list.size();
16615            int i;
16616            for (i = 0; i < stickiesCount; i++) {
16617                if (intent.filterEquals(list.get(i))) {
16618                    // This sticky already exists, replace it.
16619                    list.set(i, new Intent(intent));
16620                    break;
16621                }
16622            }
16623            if (i >= stickiesCount) {
16624                list.add(new Intent(intent));
16625            }
16626        }
16627
16628        int[] users;
16629        if (userId == UserHandle.USER_ALL) {
16630            // Caller wants broadcast to go to all started users.
16631            users = mStartedUserArray;
16632        } else {
16633            // Caller wants broadcast to go to one specific user.
16634            users = new int[] {userId};
16635        }
16636
16637        // Figure out who all will receive this broadcast.
16638        List receivers = null;
16639        List<BroadcastFilter> registeredReceivers = null;
16640        // Need to resolve the intent to interested receivers...
16641        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16642                 == 0) {
16643            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16644        }
16645        if (intent.getComponent() == null) {
16646            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16647                // Query one target user at a time, excluding shell-restricted users
16648                UserManagerService ums = getUserManagerLocked();
16649                for (int i = 0; i < users.length; i++) {
16650                    if (ums.hasUserRestriction(
16651                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16652                        continue;
16653                    }
16654                    List<BroadcastFilter> registeredReceiversForUser =
16655                            mReceiverResolver.queryIntent(intent,
16656                                    resolvedType, false, users[i]);
16657                    if (registeredReceivers == null) {
16658                        registeredReceivers = registeredReceiversForUser;
16659                    } else if (registeredReceiversForUser != null) {
16660                        registeredReceivers.addAll(registeredReceiversForUser);
16661                    }
16662                }
16663            } else {
16664                registeredReceivers = mReceiverResolver.queryIntent(intent,
16665                        resolvedType, false, userId);
16666            }
16667        }
16668
16669        final boolean replacePending =
16670                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16671
16672        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16673                + " replacePending=" + replacePending);
16674
16675        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16676        if (!ordered && NR > 0) {
16677            // If we are not serializing this broadcast, then send the
16678            // registered receivers separately so they don't wait for the
16679            // components to be launched.
16680            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16681            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16682                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16683                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16684                    resultExtras, ordered, sticky, false, userId);
16685            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16686            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16687            if (!replaced) {
16688                queue.enqueueParallelBroadcastLocked(r);
16689                queue.scheduleBroadcastsLocked();
16690            }
16691            registeredReceivers = null;
16692            NR = 0;
16693        }
16694
16695        // Merge into one list.
16696        int ir = 0;
16697        if (receivers != null) {
16698            // A special case for PACKAGE_ADDED: do not allow the package
16699            // being added to see this broadcast.  This prevents them from
16700            // using this as a back door to get run as soon as they are
16701            // installed.  Maybe in the future we want to have a special install
16702            // broadcast or such for apps, but we'd like to deliberately make
16703            // this decision.
16704            String skipPackages[] = null;
16705            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16706                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16707                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16708                Uri data = intent.getData();
16709                if (data != null) {
16710                    String pkgName = data.getSchemeSpecificPart();
16711                    if (pkgName != null) {
16712                        skipPackages = new String[] { pkgName };
16713                    }
16714                }
16715            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16716                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16717            }
16718            if (skipPackages != null && (skipPackages.length > 0)) {
16719                for (String skipPackage : skipPackages) {
16720                    if (skipPackage != null) {
16721                        int NT = receivers.size();
16722                        for (int it=0; it<NT; it++) {
16723                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16724                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16725                                receivers.remove(it);
16726                                it--;
16727                                NT--;
16728                            }
16729                        }
16730                    }
16731                }
16732            }
16733
16734            int NT = receivers != null ? receivers.size() : 0;
16735            int it = 0;
16736            ResolveInfo curt = null;
16737            BroadcastFilter curr = null;
16738            while (it < NT && ir < NR) {
16739                if (curt == null) {
16740                    curt = (ResolveInfo)receivers.get(it);
16741                }
16742                if (curr == null) {
16743                    curr = registeredReceivers.get(ir);
16744                }
16745                if (curr.getPriority() >= curt.priority) {
16746                    // Insert this broadcast record into the final list.
16747                    receivers.add(it, curr);
16748                    ir++;
16749                    curr = null;
16750                    it++;
16751                    NT++;
16752                } else {
16753                    // Skip to the next ResolveInfo in the final list.
16754                    it++;
16755                    curt = null;
16756                }
16757            }
16758        }
16759        while (ir < NR) {
16760            if (receivers == null) {
16761                receivers = new ArrayList();
16762            }
16763            receivers.add(registeredReceivers.get(ir));
16764            ir++;
16765        }
16766
16767        if ((receivers != null && receivers.size() > 0)
16768                || resultTo != null) {
16769            BroadcastQueue queue = broadcastQueueForIntent(intent);
16770            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16771                    callerPackage, callingPid, callingUid, resolvedType,
16772                    requiredPermission, appOp, brOptions, receivers, resultTo, resultCode,
16773                    resultData, resultExtras, ordered, sticky, false, userId);
16774
16775            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16776                    + ": prev had " + queue.mOrderedBroadcasts.size());
16777            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16778                    "Enqueueing broadcast " + r.intent.getAction());
16779
16780            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16781            if (!replaced) {
16782                queue.enqueueOrderedBroadcastLocked(r);
16783                queue.scheduleBroadcastsLocked();
16784            }
16785        }
16786
16787        return ActivityManager.BROADCAST_SUCCESS;
16788    }
16789
16790    final Intent verifyBroadcastLocked(Intent intent) {
16791        // Refuse possible leaked file descriptors
16792        if (intent != null && intent.hasFileDescriptors() == true) {
16793            throw new IllegalArgumentException("File descriptors passed in Intent");
16794        }
16795
16796        int flags = intent.getFlags();
16797
16798        if (!mProcessesReady) {
16799            // if the caller really truly claims to know what they're doing, go
16800            // ahead and allow the broadcast without launching any receivers
16801            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16802                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16803            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16804                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16805                        + " before boot completion");
16806                throw new IllegalStateException("Cannot broadcast before boot completed");
16807            }
16808        }
16809
16810        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16811            throw new IllegalArgumentException(
16812                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16813        }
16814
16815        return intent;
16816    }
16817
16818    public final int broadcastIntent(IApplicationThread caller,
16819            Intent intent, String resolvedType, IIntentReceiver resultTo,
16820            int resultCode, String resultData, Bundle resultExtras,
16821            String requiredPermission, int appOp, Bundle options,
16822            boolean serialized, boolean sticky, int userId) {
16823        enforceNotIsolatedCaller("broadcastIntent");
16824        synchronized(this) {
16825            intent = verifyBroadcastLocked(intent);
16826
16827            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16828            final int callingPid = Binder.getCallingPid();
16829            final int callingUid = Binder.getCallingUid();
16830            final long origId = Binder.clearCallingIdentity();
16831            int res = broadcastIntentLocked(callerApp,
16832                    callerApp != null ? callerApp.info.packageName : null,
16833                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16834                    requiredPermission, appOp, null, serialized, sticky,
16835                    callingPid, callingUid, userId);
16836            Binder.restoreCallingIdentity(origId);
16837            return res;
16838        }
16839    }
16840
16841    int broadcastIntentInPackage(String packageName, int uid,
16842            Intent intent, String resolvedType, IIntentReceiver resultTo,
16843            int resultCode, String resultData, Bundle resultExtras,
16844            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16845            int userId) {
16846        synchronized(this) {
16847            intent = verifyBroadcastLocked(intent);
16848
16849            final long origId = Binder.clearCallingIdentity();
16850            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16851                    resultTo, resultCode, resultData, resultExtras, requiredPermission,
16852                    AppOpsManager.OP_NONE, options, serialized, sticky, -1, uid, userId);
16853            Binder.restoreCallingIdentity(origId);
16854            return res;
16855        }
16856    }
16857
16858    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16859        // Refuse possible leaked file descriptors
16860        if (intent != null && intent.hasFileDescriptors() == true) {
16861            throw new IllegalArgumentException("File descriptors passed in Intent");
16862        }
16863
16864        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16865                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16866
16867        synchronized(this) {
16868            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16869                    != PackageManager.PERMISSION_GRANTED) {
16870                String msg = "Permission Denial: unbroadcastIntent() from pid="
16871                        + Binder.getCallingPid()
16872                        + ", uid=" + Binder.getCallingUid()
16873                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16874                Slog.w(TAG, msg);
16875                throw new SecurityException(msg);
16876            }
16877            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16878            if (stickies != null) {
16879                ArrayList<Intent> list = stickies.get(intent.getAction());
16880                if (list != null) {
16881                    int N = list.size();
16882                    int i;
16883                    for (i=0; i<N; i++) {
16884                        if (intent.filterEquals(list.get(i))) {
16885                            list.remove(i);
16886                            break;
16887                        }
16888                    }
16889                    if (list.size() <= 0) {
16890                        stickies.remove(intent.getAction());
16891                    }
16892                }
16893                if (stickies.size() <= 0) {
16894                    mStickyBroadcasts.remove(userId);
16895                }
16896            }
16897        }
16898    }
16899
16900    void backgroundServicesFinishedLocked(int userId) {
16901        for (BroadcastQueue queue : mBroadcastQueues) {
16902            queue.backgroundServicesFinishedLocked(userId);
16903        }
16904    }
16905
16906    public void finishReceiver(IBinder who, int resultCode, String resultData,
16907            Bundle resultExtras, boolean resultAbort, int flags) {
16908        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16909
16910        // Refuse possible leaked file descriptors
16911        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16912            throw new IllegalArgumentException("File descriptors passed in Bundle");
16913        }
16914
16915        final long origId = Binder.clearCallingIdentity();
16916        try {
16917            boolean doNext = false;
16918            BroadcastRecord r;
16919
16920            synchronized(this) {
16921                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16922                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16923                r = queue.getMatchingOrderedReceiver(who);
16924                if (r != null) {
16925                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16926                        resultData, resultExtras, resultAbort, true);
16927                }
16928            }
16929
16930            if (doNext) {
16931                r.queue.processNextBroadcast(false);
16932            }
16933            trimApplications();
16934        } finally {
16935            Binder.restoreCallingIdentity(origId);
16936        }
16937    }
16938
16939    // =========================================================
16940    // INSTRUMENTATION
16941    // =========================================================
16942
16943    public boolean startInstrumentation(ComponentName className,
16944            String profileFile, int flags, Bundle arguments,
16945            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16946            int userId, String abiOverride) {
16947        enforceNotIsolatedCaller("startInstrumentation");
16948        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16949                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16950        // Refuse possible leaked file descriptors
16951        if (arguments != null && arguments.hasFileDescriptors()) {
16952            throw new IllegalArgumentException("File descriptors passed in Bundle");
16953        }
16954
16955        synchronized(this) {
16956            InstrumentationInfo ii = null;
16957            ApplicationInfo ai = null;
16958            try {
16959                ii = mContext.getPackageManager().getInstrumentationInfo(
16960                    className, STOCK_PM_FLAGS);
16961                ai = AppGlobals.getPackageManager().getApplicationInfo(
16962                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16963            } catch (PackageManager.NameNotFoundException e) {
16964            } catch (RemoteException e) {
16965            }
16966            if (ii == null) {
16967                reportStartInstrumentationFailure(watcher, className,
16968                        "Unable to find instrumentation info for: " + className);
16969                return false;
16970            }
16971            if (ai == null) {
16972                reportStartInstrumentationFailure(watcher, className,
16973                        "Unable to find instrumentation target package: " + ii.targetPackage);
16974                return false;
16975            }
16976
16977            int match = mContext.getPackageManager().checkSignatures(
16978                    ii.targetPackage, ii.packageName);
16979            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16980                String msg = "Permission Denial: starting instrumentation "
16981                        + className + " from pid="
16982                        + Binder.getCallingPid()
16983                        + ", uid=" + Binder.getCallingPid()
16984                        + " not allowed because package " + ii.packageName
16985                        + " does not have a signature matching the target "
16986                        + ii.targetPackage;
16987                reportStartInstrumentationFailure(watcher, className, msg);
16988                throw new SecurityException(msg);
16989            }
16990
16991            final long origId = Binder.clearCallingIdentity();
16992            // Instrumentation can kill and relaunch even persistent processes
16993            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16994                    "start instr");
16995            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16996            app.instrumentationClass = className;
16997            app.instrumentationInfo = ai;
16998            app.instrumentationProfileFile = profileFile;
16999            app.instrumentationArguments = arguments;
17000            app.instrumentationWatcher = watcher;
17001            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17002            app.instrumentationResultClass = className;
17003            Binder.restoreCallingIdentity(origId);
17004        }
17005
17006        return true;
17007    }
17008
17009    /**
17010     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17011     * error to the logs, but if somebody is watching, send the report there too.  This enables
17012     * the "am" command to report errors with more information.
17013     *
17014     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17015     * @param cn The component name of the instrumentation.
17016     * @param report The error report.
17017     */
17018    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17019            ComponentName cn, String report) {
17020        Slog.w(TAG, report);
17021        try {
17022            if (watcher != null) {
17023                Bundle results = new Bundle();
17024                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17025                results.putString("Error", report);
17026                watcher.instrumentationStatus(cn, -1, results);
17027            }
17028        } catch (RemoteException e) {
17029            Slog.w(TAG, e);
17030        }
17031    }
17032
17033    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17034        if (app.instrumentationWatcher != null) {
17035            try {
17036                // NOTE:  IInstrumentationWatcher *must* be oneway here
17037                app.instrumentationWatcher.instrumentationFinished(
17038                    app.instrumentationClass,
17039                    resultCode,
17040                    results);
17041            } catch (RemoteException e) {
17042            }
17043        }
17044        if (app.instrumentationUiAutomationConnection != null) {
17045            try {
17046                app.instrumentationUiAutomationConnection.shutdown();
17047            } catch (RemoteException re) {
17048                /* ignore */
17049            }
17050            // Only a UiAutomation can set this flag and now that
17051            // it is finished we make sure it is reset to its default.
17052            mUserIsMonkey = false;
17053        }
17054        app.instrumentationWatcher = null;
17055        app.instrumentationUiAutomationConnection = null;
17056        app.instrumentationClass = null;
17057        app.instrumentationInfo = null;
17058        app.instrumentationProfileFile = null;
17059        app.instrumentationArguments = null;
17060
17061        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17062                "finished inst");
17063    }
17064
17065    public void finishInstrumentation(IApplicationThread target,
17066            int resultCode, Bundle results) {
17067        int userId = UserHandle.getCallingUserId();
17068        // Refuse possible leaked file descriptors
17069        if (results != null && results.hasFileDescriptors()) {
17070            throw new IllegalArgumentException("File descriptors passed in Intent");
17071        }
17072
17073        synchronized(this) {
17074            ProcessRecord app = getRecordForAppLocked(target);
17075            if (app == null) {
17076                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17077                return;
17078            }
17079            final long origId = Binder.clearCallingIdentity();
17080            finishInstrumentationLocked(app, resultCode, results);
17081            Binder.restoreCallingIdentity(origId);
17082        }
17083    }
17084
17085    // =========================================================
17086    // CONFIGURATION
17087    // =========================================================
17088
17089    public ConfigurationInfo getDeviceConfigurationInfo() {
17090        ConfigurationInfo config = new ConfigurationInfo();
17091        synchronized (this) {
17092            config.reqTouchScreen = mConfiguration.touchscreen;
17093            config.reqKeyboardType = mConfiguration.keyboard;
17094            config.reqNavigation = mConfiguration.navigation;
17095            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17096                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17097                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17098            }
17099            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17100                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17101                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17102            }
17103            config.reqGlEsVersion = GL_ES_VERSION;
17104        }
17105        return config;
17106    }
17107
17108    ActivityStack getFocusedStack() {
17109        return mStackSupervisor.getFocusedStack();
17110    }
17111
17112    @Override
17113    public int getFocusedStackId() throws RemoteException {
17114        ActivityStack focusedStack = getFocusedStack();
17115        if (focusedStack != null) {
17116            return focusedStack.getStackId();
17117        }
17118        return -1;
17119    }
17120
17121    public Configuration getConfiguration() {
17122        Configuration ci;
17123        synchronized(this) {
17124            ci = new Configuration(mConfiguration);
17125            ci.userSetLocale = false;
17126        }
17127        return ci;
17128    }
17129
17130    public void updatePersistentConfiguration(Configuration values) {
17131        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17132                "updateConfiguration()");
17133        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17134                "updateConfiguration()");
17135        if (values == null) {
17136            throw new NullPointerException("Configuration must not be null");
17137        }
17138
17139        synchronized(this) {
17140            final long origId = Binder.clearCallingIdentity();
17141            updateConfigurationLocked(values, null, true, false);
17142            Binder.restoreCallingIdentity(origId);
17143        }
17144    }
17145
17146    public void updateConfiguration(Configuration values) {
17147        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17148                "updateConfiguration()");
17149
17150        synchronized(this) {
17151            if (values == null && mWindowManager != null) {
17152                // sentinel: fetch the current configuration from the window manager
17153                values = mWindowManager.computeNewConfiguration();
17154            }
17155
17156            if (mWindowManager != null) {
17157                mProcessList.applyDisplaySize(mWindowManager);
17158            }
17159
17160            final long origId = Binder.clearCallingIdentity();
17161            if (values != null) {
17162                Settings.System.clearConfiguration(values);
17163            }
17164            updateConfigurationLocked(values, null, false, false);
17165            Binder.restoreCallingIdentity(origId);
17166        }
17167    }
17168
17169    /**
17170     * Do either or both things: (1) change the current configuration, and (2)
17171     * make sure the given activity is running with the (now) current
17172     * configuration.  Returns true if the activity has been left running, or
17173     * false if <var>starting</var> is being destroyed to match the new
17174     * configuration.
17175     * @param persistent TODO
17176     */
17177    boolean updateConfigurationLocked(Configuration values,
17178            ActivityRecord starting, boolean persistent, boolean initLocale) {
17179        int changes = 0;
17180
17181        if (values != null) {
17182            Configuration newConfig = new Configuration(mConfiguration);
17183            changes = newConfig.updateFrom(values);
17184            if (changes != 0) {
17185                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17186                        "Updating configuration to: " + values);
17187
17188                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17189
17190                if (!initLocale && values.locale != null && values.userSetLocale) {
17191                    final String languageTag = values.locale.toLanguageTag();
17192                    SystemProperties.set("persist.sys.locale", languageTag);
17193                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17194                            values.locale));
17195                }
17196
17197                mConfigurationSeq++;
17198                if (mConfigurationSeq <= 0) {
17199                    mConfigurationSeq = 1;
17200                }
17201                newConfig.seq = mConfigurationSeq;
17202                mConfiguration = newConfig;
17203                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17204                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17205                //mUsageStatsService.noteStartConfig(newConfig);
17206
17207                final Configuration configCopy = new Configuration(mConfiguration);
17208
17209                // TODO: If our config changes, should we auto dismiss any currently
17210                // showing dialogs?
17211                mShowDialogs = shouldShowDialogs(newConfig);
17212
17213                AttributeCache ac = AttributeCache.instance();
17214                if (ac != null) {
17215                    ac.updateConfiguration(configCopy);
17216                }
17217
17218                // Make sure all resources in our process are updated
17219                // right now, so that anyone who is going to retrieve
17220                // resource values after we return will be sure to get
17221                // the new ones.  This is especially important during
17222                // boot, where the first config change needs to guarantee
17223                // all resources have that config before following boot
17224                // code is executed.
17225                mSystemThread.applyConfigurationToResources(configCopy);
17226
17227                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17228                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17229                    msg.obj = new Configuration(configCopy);
17230                    mHandler.sendMessage(msg);
17231                }
17232
17233                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17234                    ProcessRecord app = mLruProcesses.get(i);
17235                    try {
17236                        if (app.thread != null) {
17237                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17238                                    + app.processName + " new config " + mConfiguration);
17239                            app.thread.scheduleConfigurationChanged(configCopy);
17240                        }
17241                    } catch (Exception e) {
17242                    }
17243                }
17244                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17245                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17246                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17247                        | Intent.FLAG_RECEIVER_FOREGROUND);
17248                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17249                        null, AppOpsManager.OP_NONE, null, false, false,
17250                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17251                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17252                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17253                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17254                    if (!mProcessesReady) {
17255                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17256                    }
17257                    broadcastIntentLocked(null, null, intent,
17258                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17259                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17260                }
17261            }
17262        }
17263
17264        boolean kept = true;
17265        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17266        // mainStack is null during startup.
17267        if (mainStack != null) {
17268            if (changes != 0 && starting == null) {
17269                // If the configuration changed, and the caller is not already
17270                // in the process of starting an activity, then find the top
17271                // activity to check if its configuration needs to change.
17272                starting = mainStack.topRunningActivityLocked(null);
17273            }
17274
17275            if (starting != null) {
17276                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17277                // And we need to make sure at this point that all other activities
17278                // are made visible with the correct configuration.
17279                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17280            }
17281        }
17282
17283        if (values != null && mWindowManager != null) {
17284            mWindowManager.setNewConfiguration(mConfiguration);
17285        }
17286
17287        return kept;
17288    }
17289
17290    /**
17291     * Decide based on the configuration whether we should shouw the ANR,
17292     * crash, etc dialogs.  The idea is that if there is no affordnace to
17293     * press the on-screen buttons, we shouldn't show the dialog.
17294     *
17295     * A thought: SystemUI might also want to get told about this, the Power
17296     * dialog / global actions also might want different behaviors.
17297     */
17298    private static final boolean shouldShowDialogs(Configuration config) {
17299        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17300                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17301                && config.navigation == Configuration.NAVIGATION_NONAV);
17302    }
17303
17304    @Override
17305    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17306        synchronized (this) {
17307            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17308            if (srec != null) {
17309                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17310            }
17311        }
17312        return false;
17313    }
17314
17315    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17316            Intent resultData) {
17317
17318        synchronized (this) {
17319            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17320            if (r != null) {
17321                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17322            }
17323            return false;
17324        }
17325    }
17326
17327    public int getLaunchedFromUid(IBinder activityToken) {
17328        ActivityRecord srec;
17329        synchronized (this) {
17330            srec = ActivityRecord.forTokenLocked(activityToken);
17331        }
17332        if (srec == null) {
17333            return -1;
17334        }
17335        return srec.launchedFromUid;
17336    }
17337
17338    public String getLaunchedFromPackage(IBinder activityToken) {
17339        ActivityRecord srec;
17340        synchronized (this) {
17341            srec = ActivityRecord.forTokenLocked(activityToken);
17342        }
17343        if (srec == null) {
17344            return null;
17345        }
17346        return srec.launchedFromPackage;
17347    }
17348
17349    // =========================================================
17350    // LIFETIME MANAGEMENT
17351    // =========================================================
17352
17353    // Returns which broadcast queue the app is the current [or imminent] receiver
17354    // on, or 'null' if the app is not an active broadcast recipient.
17355    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17356        BroadcastRecord r = app.curReceiver;
17357        if (r != null) {
17358            return r.queue;
17359        }
17360
17361        // It's not the current receiver, but it might be starting up to become one
17362        synchronized (this) {
17363            for (BroadcastQueue queue : mBroadcastQueues) {
17364                r = queue.mPendingBroadcast;
17365                if (r != null && r.curApp == app) {
17366                    // found it; report which queue it's in
17367                    return queue;
17368                }
17369            }
17370        }
17371
17372        return null;
17373    }
17374
17375    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17376            ComponentName targetComponent, String targetProcess) {
17377        if (!mTrackingAssociations) {
17378            return null;
17379        }
17380        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17381                = mAssociations.get(targetUid);
17382        if (components == null) {
17383            components = new ArrayMap<>();
17384            mAssociations.put(targetUid, components);
17385        }
17386        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17387        if (sourceUids == null) {
17388            sourceUids = new SparseArray<>();
17389            components.put(targetComponent, sourceUids);
17390        }
17391        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17392        if (sourceProcesses == null) {
17393            sourceProcesses = new ArrayMap<>();
17394            sourceUids.put(sourceUid, sourceProcesses);
17395        }
17396        Association ass = sourceProcesses.get(sourceProcess);
17397        if (ass == null) {
17398            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17399                    targetProcess);
17400            sourceProcesses.put(sourceProcess, ass);
17401        }
17402        ass.mCount++;
17403        ass.mNesting++;
17404        if (ass.mNesting == 1) {
17405            ass.mStartTime = SystemClock.uptimeMillis();
17406        }
17407        return ass;
17408    }
17409
17410    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17411            ComponentName targetComponent) {
17412        if (!mTrackingAssociations) {
17413            return;
17414        }
17415        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17416                = mAssociations.get(targetUid);
17417        if (components == null) {
17418            return;
17419        }
17420        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17421        if (sourceUids == null) {
17422            return;
17423        }
17424        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17425        if (sourceProcesses == null) {
17426            return;
17427        }
17428        Association ass = sourceProcesses.get(sourceProcess);
17429        if (ass == null || ass.mNesting <= 0) {
17430            return;
17431        }
17432        ass.mNesting--;
17433        if (ass.mNesting == 0) {
17434            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17435        }
17436    }
17437
17438    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17439            boolean doingAll, long now) {
17440        if (mAdjSeq == app.adjSeq) {
17441            // This adjustment has already been computed.
17442            return app.curRawAdj;
17443        }
17444
17445        if (app.thread == null) {
17446            app.adjSeq = mAdjSeq;
17447            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17448            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17449            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17450        }
17451
17452        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17453        app.adjSource = null;
17454        app.adjTarget = null;
17455        app.empty = false;
17456        app.cached = false;
17457
17458        final int activitiesSize = app.activities.size();
17459
17460        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17461            // The max adjustment doesn't allow this app to be anything
17462            // below foreground, so it is not worth doing work for it.
17463            app.adjType = "fixed";
17464            app.adjSeq = mAdjSeq;
17465            app.curRawAdj = app.maxAdj;
17466            app.foregroundActivities = false;
17467            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17468            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17469            // System processes can do UI, and when they do we want to have
17470            // them trim their memory after the user leaves the UI.  To
17471            // facilitate this, here we need to determine whether or not it
17472            // is currently showing UI.
17473            app.systemNoUi = true;
17474            if (app == TOP_APP) {
17475                app.systemNoUi = false;
17476            } else if (activitiesSize > 0) {
17477                for (int j = 0; j < activitiesSize; j++) {
17478                    final ActivityRecord r = app.activities.get(j);
17479                    if (r.visible) {
17480                        app.systemNoUi = false;
17481                    }
17482                }
17483            }
17484            if (!app.systemNoUi) {
17485                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17486            }
17487            return (app.curAdj=app.maxAdj);
17488        }
17489
17490        app.systemNoUi = false;
17491
17492        final int PROCESS_STATE_TOP = mTopProcessState;
17493
17494        // Determine the importance of the process, starting with most
17495        // important to least, and assign an appropriate OOM adjustment.
17496        int adj;
17497        int schedGroup;
17498        int procState;
17499        boolean foregroundActivities = false;
17500        BroadcastQueue queue;
17501        if (app == TOP_APP) {
17502            // The last app on the list is the foreground app.
17503            adj = ProcessList.FOREGROUND_APP_ADJ;
17504            schedGroup = Process.THREAD_GROUP_DEFAULT;
17505            app.adjType = "top-activity";
17506            foregroundActivities = true;
17507            procState = PROCESS_STATE_TOP;
17508        } else if (app.instrumentationClass != null) {
17509            // Don't want to kill running instrumentation.
17510            adj = ProcessList.FOREGROUND_APP_ADJ;
17511            schedGroup = Process.THREAD_GROUP_DEFAULT;
17512            app.adjType = "instrumentation";
17513            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17514        } else if ((queue = isReceivingBroadcast(app)) != null) {
17515            // An app that is currently receiving a broadcast also
17516            // counts as being in the foreground for OOM killer purposes.
17517            // It's placed in a sched group based on the nature of the
17518            // broadcast as reflected by which queue it's active in.
17519            adj = ProcessList.FOREGROUND_APP_ADJ;
17520            schedGroup = (queue == mFgBroadcastQueue)
17521                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17522            app.adjType = "broadcast";
17523            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17524        } else if (app.executingServices.size() > 0) {
17525            // An app that is currently executing a service callback also
17526            // counts as being in the foreground.
17527            adj = ProcessList.FOREGROUND_APP_ADJ;
17528            schedGroup = app.execServicesFg ?
17529                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17530            app.adjType = "exec-service";
17531            procState = ActivityManager.PROCESS_STATE_SERVICE;
17532            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17533        } else {
17534            // As far as we know the process is empty.  We may change our mind later.
17535            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17536            // At this point we don't actually know the adjustment.  Use the cached adj
17537            // value that the caller wants us to.
17538            adj = cachedAdj;
17539            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17540            app.cached = true;
17541            app.empty = true;
17542            app.adjType = "cch-empty";
17543        }
17544
17545        // Examine all activities if not already foreground.
17546        if (!foregroundActivities && activitiesSize > 0) {
17547            for (int j = 0; j < activitiesSize; j++) {
17548                final ActivityRecord r = app.activities.get(j);
17549                if (r.app != app) {
17550                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17551                            + app + "?!? Using " + r.app + " instead.");
17552                    continue;
17553                }
17554                if (r.visible) {
17555                    // App has a visible activity; only upgrade adjustment.
17556                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17557                        adj = ProcessList.VISIBLE_APP_ADJ;
17558                        app.adjType = "visible";
17559                    }
17560                    if (procState > PROCESS_STATE_TOP) {
17561                        procState = PROCESS_STATE_TOP;
17562                    }
17563                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17564                    app.cached = false;
17565                    app.empty = false;
17566                    foregroundActivities = true;
17567                    break;
17568                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17569                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17570                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17571                        app.adjType = "pausing";
17572                    }
17573                    if (procState > PROCESS_STATE_TOP) {
17574                        procState = PROCESS_STATE_TOP;
17575                    }
17576                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17577                    app.cached = false;
17578                    app.empty = false;
17579                    foregroundActivities = true;
17580                } else if (r.state == ActivityState.STOPPING) {
17581                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17582                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17583                        app.adjType = "stopping";
17584                    }
17585                    // For the process state, we will at this point consider the
17586                    // process to be cached.  It will be cached either as an activity
17587                    // or empty depending on whether the activity is finishing.  We do
17588                    // this so that we can treat the process as cached for purposes of
17589                    // memory trimming (determing current memory level, trim command to
17590                    // send to process) since there can be an arbitrary number of stopping
17591                    // processes and they should soon all go into the cached state.
17592                    if (!r.finishing) {
17593                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17594                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17595                        }
17596                    }
17597                    app.cached = false;
17598                    app.empty = false;
17599                    foregroundActivities = true;
17600                } else {
17601                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17602                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17603                        app.adjType = "cch-act";
17604                    }
17605                }
17606            }
17607        }
17608
17609        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17610            if (app.foregroundServices) {
17611                // The user is aware of this app, so make it visible.
17612                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17613                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17614                app.cached = false;
17615                app.adjType = "fg-service";
17616                schedGroup = Process.THREAD_GROUP_DEFAULT;
17617            } else if (app.forcingToForeground != null) {
17618                // The user is aware of this app, so make it visible.
17619                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17620                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17621                app.cached = false;
17622                app.adjType = "force-fg";
17623                app.adjSource = app.forcingToForeground;
17624                schedGroup = Process.THREAD_GROUP_DEFAULT;
17625            }
17626        }
17627
17628        if (app == mHeavyWeightProcess) {
17629            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17630                // We don't want to kill the current heavy-weight process.
17631                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17632                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17633                app.cached = false;
17634                app.adjType = "heavy";
17635            }
17636            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17637                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17638            }
17639        }
17640
17641        if (app == mHomeProcess) {
17642            if (adj > ProcessList.HOME_APP_ADJ) {
17643                // This process is hosting what we currently consider to be the
17644                // home app, so we don't want to let it go into the background.
17645                adj = ProcessList.HOME_APP_ADJ;
17646                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17647                app.cached = false;
17648                app.adjType = "home";
17649            }
17650            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17651                procState = ActivityManager.PROCESS_STATE_HOME;
17652            }
17653        }
17654
17655        if (app == mPreviousProcess && app.activities.size() > 0) {
17656            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17657                // This was the previous process that showed UI to the user.
17658                // We want to try to keep it around more aggressively, to give
17659                // a good experience around switching between two apps.
17660                adj = ProcessList.PREVIOUS_APP_ADJ;
17661                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17662                app.cached = false;
17663                app.adjType = "previous";
17664            }
17665            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17666                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17667            }
17668        }
17669
17670        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17671                + " reason=" + app.adjType);
17672
17673        // By default, we use the computed adjustment.  It may be changed if
17674        // there are applications dependent on our services or providers, but
17675        // this gives us a baseline and makes sure we don't get into an
17676        // infinite recursion.
17677        app.adjSeq = mAdjSeq;
17678        app.curRawAdj = adj;
17679        app.hasStartedServices = false;
17680
17681        if (mBackupTarget != null && app == mBackupTarget.app) {
17682            // If possible we want to avoid killing apps while they're being backed up
17683            if (adj > ProcessList.BACKUP_APP_ADJ) {
17684                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17685                adj = ProcessList.BACKUP_APP_ADJ;
17686                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17687                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17688                }
17689                app.adjType = "backup";
17690                app.cached = false;
17691            }
17692            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17693                procState = ActivityManager.PROCESS_STATE_BACKUP;
17694            }
17695        }
17696
17697        boolean mayBeTop = false;
17698
17699        for (int is = app.services.size()-1;
17700                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17701                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17702                        || procState > ActivityManager.PROCESS_STATE_TOP);
17703                is--) {
17704            ServiceRecord s = app.services.valueAt(is);
17705            if (s.startRequested) {
17706                app.hasStartedServices = true;
17707                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17708                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17709                }
17710                if (app.hasShownUi && app != mHomeProcess) {
17711                    // If this process has shown some UI, let it immediately
17712                    // go to the LRU list because it may be pretty heavy with
17713                    // UI stuff.  We'll tag it with a label just to help
17714                    // debug and understand what is going on.
17715                    if (adj > ProcessList.SERVICE_ADJ) {
17716                        app.adjType = "cch-started-ui-services";
17717                    }
17718                } else {
17719                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17720                        // This service has seen some activity within
17721                        // recent memory, so we will keep its process ahead
17722                        // of the background processes.
17723                        if (adj > ProcessList.SERVICE_ADJ) {
17724                            adj = ProcessList.SERVICE_ADJ;
17725                            app.adjType = "started-services";
17726                            app.cached = false;
17727                        }
17728                    }
17729                    // If we have let the service slide into the background
17730                    // state, still have some text describing what it is doing
17731                    // even though the service no longer has an impact.
17732                    if (adj > ProcessList.SERVICE_ADJ) {
17733                        app.adjType = "cch-started-services";
17734                    }
17735                }
17736            }
17737            for (int conni = s.connections.size()-1;
17738                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17739                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17740                            || procState > ActivityManager.PROCESS_STATE_TOP);
17741                    conni--) {
17742                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17743                for (int i = 0;
17744                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17745                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17746                                || procState > ActivityManager.PROCESS_STATE_TOP);
17747                        i++) {
17748                    // XXX should compute this based on the max of
17749                    // all connected clients.
17750                    ConnectionRecord cr = clist.get(i);
17751                    if (cr.binding.client == app) {
17752                        // Binding to ourself is not interesting.
17753                        continue;
17754                    }
17755                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17756                        ProcessRecord client = cr.binding.client;
17757                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17758                                TOP_APP, doingAll, now);
17759                        int clientProcState = client.curProcState;
17760                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17761                            // If the other app is cached for any reason, for purposes here
17762                            // we are going to consider it empty.  The specific cached state
17763                            // doesn't propagate except under certain conditions.
17764                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17765                        }
17766                        String adjType = null;
17767                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17768                            // Not doing bind OOM management, so treat
17769                            // this guy more like a started service.
17770                            if (app.hasShownUi && app != mHomeProcess) {
17771                                // If this process has shown some UI, let it immediately
17772                                // go to the LRU list because it may be pretty heavy with
17773                                // UI stuff.  We'll tag it with a label just to help
17774                                // debug and understand what is going on.
17775                                if (adj > clientAdj) {
17776                                    adjType = "cch-bound-ui-services";
17777                                }
17778                                app.cached = false;
17779                                clientAdj = adj;
17780                                clientProcState = procState;
17781                            } else {
17782                                if (now >= (s.lastActivity
17783                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17784                                    // This service has not seen activity within
17785                                    // recent memory, so allow it to drop to the
17786                                    // LRU list if there is no other reason to keep
17787                                    // it around.  We'll also tag it with a label just
17788                                    // to help debug and undertand what is going on.
17789                                    if (adj > clientAdj) {
17790                                        adjType = "cch-bound-services";
17791                                    }
17792                                    clientAdj = adj;
17793                                }
17794                            }
17795                        }
17796                        if (adj > clientAdj) {
17797                            // If this process has recently shown UI, and
17798                            // the process that is binding to it is less
17799                            // important than being visible, then we don't
17800                            // care about the binding as much as we care
17801                            // about letting this process get into the LRU
17802                            // list to be killed and restarted if needed for
17803                            // memory.
17804                            if (app.hasShownUi && app != mHomeProcess
17805                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17806                                adjType = "cch-bound-ui-services";
17807                            } else {
17808                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17809                                        |Context.BIND_IMPORTANT)) != 0) {
17810                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17811                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17812                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17813                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17814                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17815                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17816                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17817                                    adj = clientAdj;
17818                                } else {
17819                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17820                                        adj = ProcessList.VISIBLE_APP_ADJ;
17821                                    }
17822                                }
17823                                if (!client.cached) {
17824                                    app.cached = false;
17825                                }
17826                                adjType = "service";
17827                            }
17828                        }
17829                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17830                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17831                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17832                            }
17833                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17834                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17835                                    // Special handling of clients who are in the top state.
17836                                    // We *may* want to consider this process to be in the
17837                                    // top state as well, but only if there is not another
17838                                    // reason for it to be running.  Being on the top is a
17839                                    // special state, meaning you are specifically running
17840                                    // for the current top app.  If the process is already
17841                                    // running in the background for some other reason, it
17842                                    // is more important to continue considering it to be
17843                                    // in the background state.
17844                                    mayBeTop = true;
17845                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17846                                } else {
17847                                    // Special handling for above-top states (persistent
17848                                    // processes).  These should not bring the current process
17849                                    // into the top state, since they are not on top.  Instead
17850                                    // give them the best state after that.
17851                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17852                                        clientProcState =
17853                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17854                                    } else if (mWakefulness
17855                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17856                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17857                                                    != 0) {
17858                                        clientProcState =
17859                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17860                                    } else {
17861                                        clientProcState =
17862                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17863                                    }
17864                                }
17865                            }
17866                        } else {
17867                            if (clientProcState <
17868                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17869                                clientProcState =
17870                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17871                            }
17872                        }
17873                        if (procState > clientProcState) {
17874                            procState = clientProcState;
17875                        }
17876                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17877                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17878                            app.pendingUiClean = true;
17879                        }
17880                        if (adjType != null) {
17881                            app.adjType = adjType;
17882                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17883                                    .REASON_SERVICE_IN_USE;
17884                            app.adjSource = cr.binding.client;
17885                            app.adjSourceProcState = clientProcState;
17886                            app.adjTarget = s.name;
17887                        }
17888                    }
17889                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17890                        app.treatLikeActivity = true;
17891                    }
17892                    final ActivityRecord a = cr.activity;
17893                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17894                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17895                                (a.visible || a.state == ActivityState.RESUMED
17896                                 || a.state == ActivityState.PAUSING)) {
17897                            adj = ProcessList.FOREGROUND_APP_ADJ;
17898                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17899                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17900                            }
17901                            app.cached = false;
17902                            app.adjType = "service";
17903                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17904                                    .REASON_SERVICE_IN_USE;
17905                            app.adjSource = a;
17906                            app.adjSourceProcState = procState;
17907                            app.adjTarget = s.name;
17908                        }
17909                    }
17910                }
17911            }
17912        }
17913
17914        for (int provi = app.pubProviders.size()-1;
17915                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17916                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17917                        || procState > ActivityManager.PROCESS_STATE_TOP);
17918                provi--) {
17919            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17920            for (int i = cpr.connections.size()-1;
17921                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17922                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17923                            || procState > ActivityManager.PROCESS_STATE_TOP);
17924                    i--) {
17925                ContentProviderConnection conn = cpr.connections.get(i);
17926                ProcessRecord client = conn.client;
17927                if (client == app) {
17928                    // Being our own client is not interesting.
17929                    continue;
17930                }
17931                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17932                int clientProcState = client.curProcState;
17933                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17934                    // If the other app is cached for any reason, for purposes here
17935                    // we are going to consider it empty.
17936                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17937                }
17938                if (adj > clientAdj) {
17939                    if (app.hasShownUi && app != mHomeProcess
17940                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17941                        app.adjType = "cch-ui-provider";
17942                    } else {
17943                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17944                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17945                        app.adjType = "provider";
17946                    }
17947                    app.cached &= client.cached;
17948                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17949                            .REASON_PROVIDER_IN_USE;
17950                    app.adjSource = client;
17951                    app.adjSourceProcState = clientProcState;
17952                    app.adjTarget = cpr.name;
17953                }
17954                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17955                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17956                        // Special handling of clients who are in the top state.
17957                        // We *may* want to consider this process to be in the
17958                        // top state as well, but only if there is not another
17959                        // reason for it to be running.  Being on the top is a
17960                        // special state, meaning you are specifically running
17961                        // for the current top app.  If the process is already
17962                        // running in the background for some other reason, it
17963                        // is more important to continue considering it to be
17964                        // in the background state.
17965                        mayBeTop = true;
17966                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17967                    } else {
17968                        // Special handling for above-top states (persistent
17969                        // processes).  These should not bring the current process
17970                        // into the top state, since they are not on top.  Instead
17971                        // give them the best state after that.
17972                        clientProcState =
17973                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17974                    }
17975                }
17976                if (procState > clientProcState) {
17977                    procState = clientProcState;
17978                }
17979                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17980                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17981                }
17982            }
17983            // If the provider has external (non-framework) process
17984            // dependencies, ensure that its adjustment is at least
17985            // FOREGROUND_APP_ADJ.
17986            if (cpr.hasExternalProcessHandles()) {
17987                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17988                    adj = ProcessList.FOREGROUND_APP_ADJ;
17989                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17990                    app.cached = false;
17991                    app.adjType = "provider";
17992                    app.adjTarget = cpr.name;
17993                }
17994                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17995                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17996                }
17997            }
17998        }
17999
18000        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18001            // A client of one of our services or providers is in the top state.  We
18002            // *may* want to be in the top state, but not if we are already running in
18003            // the background for some other reason.  For the decision here, we are going
18004            // to pick out a few specific states that we want to remain in when a client
18005            // is top (states that tend to be longer-term) and otherwise allow it to go
18006            // to the top state.
18007            switch (procState) {
18008                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18009                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18010                case ActivityManager.PROCESS_STATE_SERVICE:
18011                    // These all are longer-term states, so pull them up to the top
18012                    // of the background states, but not all the way to the top state.
18013                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18014                    break;
18015                default:
18016                    // Otherwise, top is a better choice, so take it.
18017                    procState = ActivityManager.PROCESS_STATE_TOP;
18018                    break;
18019            }
18020        }
18021
18022        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18023            if (app.hasClientActivities) {
18024                // This is a cached process, but with client activities.  Mark it so.
18025                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18026                app.adjType = "cch-client-act";
18027            } else if (app.treatLikeActivity) {
18028                // This is a cached process, but somebody wants us to treat it like it has
18029                // an activity, okay!
18030                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18031                app.adjType = "cch-as-act";
18032            }
18033        }
18034
18035        if (adj == ProcessList.SERVICE_ADJ) {
18036            if (doingAll) {
18037                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18038                mNewNumServiceProcs++;
18039                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18040                if (!app.serviceb) {
18041                    // This service isn't far enough down on the LRU list to
18042                    // normally be a B service, but if we are low on RAM and it
18043                    // is large we want to force it down since we would prefer to
18044                    // keep launcher over it.
18045                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18046                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18047                        app.serviceHighRam = true;
18048                        app.serviceb = true;
18049                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18050                    } else {
18051                        mNewNumAServiceProcs++;
18052                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18053                    }
18054                } else {
18055                    app.serviceHighRam = false;
18056                }
18057            }
18058            if (app.serviceb) {
18059                adj = ProcessList.SERVICE_B_ADJ;
18060            }
18061        }
18062
18063        app.curRawAdj = adj;
18064
18065        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18066        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18067        if (adj > app.maxAdj) {
18068            adj = app.maxAdj;
18069            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18070                schedGroup = Process.THREAD_GROUP_DEFAULT;
18071            }
18072        }
18073
18074        // Do final modification to adj.  Everything we do between here and applying
18075        // the final setAdj must be done in this function, because we will also use
18076        // it when computing the final cached adj later.  Note that we don't need to
18077        // worry about this for max adj above, since max adj will always be used to
18078        // keep it out of the cached vaues.
18079        app.curAdj = app.modifyRawOomAdj(adj);
18080        app.curSchedGroup = schedGroup;
18081        app.curProcState = procState;
18082        app.foregroundActivities = foregroundActivities;
18083
18084        return app.curRawAdj;
18085    }
18086
18087    /**
18088     * Record new PSS sample for a process.
18089     */
18090    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18091        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18092        proc.lastPssTime = now;
18093        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18094        if (DEBUG_PSS) Slog.d(TAG_PSS,
18095                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18096                + " state=" + ProcessList.makeProcStateString(procState));
18097        if (proc.initialIdlePss == 0) {
18098            proc.initialIdlePss = pss;
18099        }
18100        proc.lastPss = pss;
18101        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18102            proc.lastCachedPss = pss;
18103        }
18104
18105        final SparseArray<Pair<Long, String>> watchUids
18106                = mMemWatchProcesses.getMap().get(proc.processName);
18107        Long check = null;
18108        if (watchUids != null) {
18109            Pair<Long, String> val = watchUids.get(proc.uid);
18110            if (val == null) {
18111                val = watchUids.get(0);
18112            }
18113            if (val != null) {
18114                check = val.first;
18115            }
18116        }
18117        if (check != null) {
18118            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18119                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18120                if (!isDebuggable) {
18121                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18122                        isDebuggable = true;
18123                    }
18124                }
18125                if (isDebuggable) {
18126                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18127                    final ProcessRecord myProc = proc;
18128                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18129                    mMemWatchDumpProcName = proc.processName;
18130                    mMemWatchDumpFile = heapdumpFile.toString();
18131                    mMemWatchDumpPid = proc.pid;
18132                    mMemWatchDumpUid = proc.uid;
18133                    BackgroundThread.getHandler().post(new Runnable() {
18134                        @Override
18135                        public void run() {
18136                            revokeUriPermission(ActivityThread.currentActivityThread()
18137                                            .getApplicationThread(),
18138                                    DumpHeapActivity.JAVA_URI,
18139                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18140                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18141                                    UserHandle.myUserId());
18142                            ParcelFileDescriptor fd = null;
18143                            try {
18144                                heapdumpFile.delete();
18145                                fd = ParcelFileDescriptor.open(heapdumpFile,
18146                                        ParcelFileDescriptor.MODE_CREATE |
18147                                                ParcelFileDescriptor.MODE_TRUNCATE |
18148                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18149                                                ParcelFileDescriptor.MODE_APPEND);
18150                                IApplicationThread thread = myProc.thread;
18151                                if (thread != null) {
18152                                    try {
18153                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18154                                                "Requesting dump heap from "
18155                                                + myProc + " to " + heapdumpFile);
18156                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18157                                    } catch (RemoteException e) {
18158                                    }
18159                                }
18160                            } catch (FileNotFoundException e) {
18161                                e.printStackTrace();
18162                            } finally {
18163                                if (fd != null) {
18164                                    try {
18165                                        fd.close();
18166                                    } catch (IOException e) {
18167                                    }
18168                                }
18169                            }
18170                        }
18171                    });
18172                } else {
18173                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18174                            + ", but debugging not enabled");
18175                }
18176            }
18177        }
18178    }
18179
18180    /**
18181     * Schedule PSS collection of a process.
18182     */
18183    void requestPssLocked(ProcessRecord proc, int procState) {
18184        if (mPendingPssProcesses.contains(proc)) {
18185            return;
18186        }
18187        if (mPendingPssProcesses.size() == 0) {
18188            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18189        }
18190        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18191        proc.pssProcState = procState;
18192        mPendingPssProcesses.add(proc);
18193    }
18194
18195    /**
18196     * Schedule PSS collection of all processes.
18197     */
18198    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18199        if (!always) {
18200            if (now < (mLastFullPssTime +
18201                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18202                return;
18203            }
18204        }
18205        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18206        mLastFullPssTime = now;
18207        mFullPssPending = true;
18208        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18209        mPendingPssProcesses.clear();
18210        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18211            ProcessRecord app = mLruProcesses.get(i);
18212            if (app.thread == null
18213                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18214                continue;
18215            }
18216            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18217                app.pssProcState = app.setProcState;
18218                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18219                        mTestPssMode, isSleeping(), now);
18220                mPendingPssProcesses.add(app);
18221            }
18222        }
18223        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18224    }
18225
18226    public void setTestPssMode(boolean enabled) {
18227        synchronized (this) {
18228            mTestPssMode = enabled;
18229            if (enabled) {
18230                // Whenever we enable the mode, we want to take a snapshot all of current
18231                // process mem use.
18232                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18233            }
18234        }
18235    }
18236
18237    /**
18238     * Ask a given process to GC right now.
18239     */
18240    final void performAppGcLocked(ProcessRecord app) {
18241        try {
18242            app.lastRequestedGc = SystemClock.uptimeMillis();
18243            if (app.thread != null) {
18244                if (app.reportLowMemory) {
18245                    app.reportLowMemory = false;
18246                    app.thread.scheduleLowMemory();
18247                } else {
18248                    app.thread.processInBackground();
18249                }
18250            }
18251        } catch (Exception e) {
18252            // whatever.
18253        }
18254    }
18255
18256    /**
18257     * Returns true if things are idle enough to perform GCs.
18258     */
18259    private final boolean canGcNowLocked() {
18260        boolean processingBroadcasts = false;
18261        for (BroadcastQueue q : mBroadcastQueues) {
18262            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18263                processingBroadcasts = true;
18264            }
18265        }
18266        return !processingBroadcasts
18267                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18268    }
18269
18270    /**
18271     * Perform GCs on all processes that are waiting for it, but only
18272     * if things are idle.
18273     */
18274    final void performAppGcsLocked() {
18275        final int N = mProcessesToGc.size();
18276        if (N <= 0) {
18277            return;
18278        }
18279        if (canGcNowLocked()) {
18280            while (mProcessesToGc.size() > 0) {
18281                ProcessRecord proc = mProcessesToGc.remove(0);
18282                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18283                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18284                            <= SystemClock.uptimeMillis()) {
18285                        // To avoid spamming the system, we will GC processes one
18286                        // at a time, waiting a few seconds between each.
18287                        performAppGcLocked(proc);
18288                        scheduleAppGcsLocked();
18289                        return;
18290                    } else {
18291                        // It hasn't been long enough since we last GCed this
18292                        // process...  put it in the list to wait for its time.
18293                        addProcessToGcListLocked(proc);
18294                        break;
18295                    }
18296                }
18297            }
18298
18299            scheduleAppGcsLocked();
18300        }
18301    }
18302
18303    /**
18304     * If all looks good, perform GCs on all processes waiting for them.
18305     */
18306    final void performAppGcsIfAppropriateLocked() {
18307        if (canGcNowLocked()) {
18308            performAppGcsLocked();
18309            return;
18310        }
18311        // Still not idle, wait some more.
18312        scheduleAppGcsLocked();
18313    }
18314
18315    /**
18316     * Schedule the execution of all pending app GCs.
18317     */
18318    final void scheduleAppGcsLocked() {
18319        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18320
18321        if (mProcessesToGc.size() > 0) {
18322            // Schedule a GC for the time to the next process.
18323            ProcessRecord proc = mProcessesToGc.get(0);
18324            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18325
18326            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18327            long now = SystemClock.uptimeMillis();
18328            if (when < (now+GC_TIMEOUT)) {
18329                when = now + GC_TIMEOUT;
18330            }
18331            mHandler.sendMessageAtTime(msg, when);
18332        }
18333    }
18334
18335    /**
18336     * Add a process to the array of processes waiting to be GCed.  Keeps the
18337     * list in sorted order by the last GC time.  The process can't already be
18338     * on the list.
18339     */
18340    final void addProcessToGcListLocked(ProcessRecord proc) {
18341        boolean added = false;
18342        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18343            if (mProcessesToGc.get(i).lastRequestedGc <
18344                    proc.lastRequestedGc) {
18345                added = true;
18346                mProcessesToGc.add(i+1, proc);
18347                break;
18348            }
18349        }
18350        if (!added) {
18351            mProcessesToGc.add(0, proc);
18352        }
18353    }
18354
18355    /**
18356     * Set up to ask a process to GC itself.  This will either do it
18357     * immediately, or put it on the list of processes to gc the next
18358     * time things are idle.
18359     */
18360    final void scheduleAppGcLocked(ProcessRecord app) {
18361        long now = SystemClock.uptimeMillis();
18362        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18363            return;
18364        }
18365        if (!mProcessesToGc.contains(app)) {
18366            addProcessToGcListLocked(app);
18367            scheduleAppGcsLocked();
18368        }
18369    }
18370
18371    final void checkExcessivePowerUsageLocked(boolean doKills) {
18372        updateCpuStatsNow();
18373
18374        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18375        boolean doWakeKills = doKills;
18376        boolean doCpuKills = doKills;
18377        if (mLastPowerCheckRealtime == 0) {
18378            doWakeKills = false;
18379        }
18380        if (mLastPowerCheckUptime == 0) {
18381            doCpuKills = false;
18382        }
18383        if (stats.isScreenOn()) {
18384            doWakeKills = false;
18385        }
18386        final long curRealtime = SystemClock.elapsedRealtime();
18387        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18388        final long curUptime = SystemClock.uptimeMillis();
18389        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18390        mLastPowerCheckRealtime = curRealtime;
18391        mLastPowerCheckUptime = curUptime;
18392        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18393            doWakeKills = false;
18394        }
18395        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18396            doCpuKills = false;
18397        }
18398        int i = mLruProcesses.size();
18399        while (i > 0) {
18400            i--;
18401            ProcessRecord app = mLruProcesses.get(i);
18402            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18403                long wtime;
18404                synchronized (stats) {
18405                    wtime = stats.getProcessWakeTime(app.info.uid,
18406                            app.pid, curRealtime);
18407                }
18408                long wtimeUsed = wtime - app.lastWakeTime;
18409                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18410                if (DEBUG_POWER) {
18411                    StringBuilder sb = new StringBuilder(128);
18412                    sb.append("Wake for ");
18413                    app.toShortString(sb);
18414                    sb.append(": over ");
18415                    TimeUtils.formatDuration(realtimeSince, sb);
18416                    sb.append(" used ");
18417                    TimeUtils.formatDuration(wtimeUsed, sb);
18418                    sb.append(" (");
18419                    sb.append((wtimeUsed*100)/realtimeSince);
18420                    sb.append("%)");
18421                    Slog.i(TAG_POWER, sb.toString());
18422                    sb.setLength(0);
18423                    sb.append("CPU for ");
18424                    app.toShortString(sb);
18425                    sb.append(": over ");
18426                    TimeUtils.formatDuration(uptimeSince, sb);
18427                    sb.append(" used ");
18428                    TimeUtils.formatDuration(cputimeUsed, sb);
18429                    sb.append(" (");
18430                    sb.append((cputimeUsed*100)/uptimeSince);
18431                    sb.append("%)");
18432                    Slog.i(TAG_POWER, sb.toString());
18433                }
18434                // If a process has held a wake lock for more
18435                // than 50% of the time during this period,
18436                // that sounds bad.  Kill!
18437                if (doWakeKills && realtimeSince > 0
18438                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18439                    synchronized (stats) {
18440                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18441                                realtimeSince, wtimeUsed);
18442                    }
18443                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18444                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18445                } else if (doCpuKills && uptimeSince > 0
18446                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18447                    synchronized (stats) {
18448                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18449                                uptimeSince, cputimeUsed);
18450                    }
18451                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18452                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18453                } else {
18454                    app.lastWakeTime = wtime;
18455                    app.lastCpuTime = app.curCpuTime;
18456                }
18457            }
18458        }
18459    }
18460
18461    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18462        boolean success = true;
18463
18464        if (app.curRawAdj != app.setRawAdj) {
18465            app.setRawAdj = app.curRawAdj;
18466        }
18467
18468        int changes = 0;
18469
18470        if (app.curAdj != app.setAdj) {
18471            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18472            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18473                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18474                    + app.adjType);
18475            app.setAdj = app.curAdj;
18476        }
18477
18478        if (app.setSchedGroup != app.curSchedGroup) {
18479            app.setSchedGroup = app.curSchedGroup;
18480            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18481                    "Setting process group of " + app.processName
18482                    + " to " + app.curSchedGroup);
18483            if (app.waitingToKill != null && app.curReceiver == null
18484                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18485                app.kill(app.waitingToKill, true);
18486                success = false;
18487            } else {
18488                if (true) {
18489                    long oldId = Binder.clearCallingIdentity();
18490                    try {
18491                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18492                    } catch (Exception e) {
18493                        Slog.w(TAG, "Failed setting process group of " + app.pid
18494                                + " to " + app.curSchedGroup);
18495                        e.printStackTrace();
18496                    } finally {
18497                        Binder.restoreCallingIdentity(oldId);
18498                    }
18499                } else {
18500                    if (app.thread != null) {
18501                        try {
18502                            app.thread.setSchedulingGroup(app.curSchedGroup);
18503                        } catch (RemoteException e) {
18504                        }
18505                    }
18506                }
18507                Process.setSwappiness(app.pid,
18508                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18509            }
18510        }
18511        if (app.repForegroundActivities != app.foregroundActivities) {
18512            app.repForegroundActivities = app.foregroundActivities;
18513            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18514        }
18515        if (app.repProcState != app.curProcState) {
18516            app.repProcState = app.curProcState;
18517            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18518            if (app.thread != null) {
18519                try {
18520                    if (false) {
18521                        //RuntimeException h = new RuntimeException("here");
18522                        Slog.i(TAG, "Sending new process state " + app.repProcState
18523                                + " to " + app /*, h*/);
18524                    }
18525                    app.thread.setProcessState(app.repProcState);
18526                } catch (RemoteException e) {
18527                }
18528            }
18529        }
18530        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18531                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18532            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18533                // Experimental code to more aggressively collect pss while
18534                // running test...  the problem is that this tends to collect
18535                // the data right when a process is transitioning between process
18536                // states, which well tend to give noisy data.
18537                long start = SystemClock.uptimeMillis();
18538                long pss = Debug.getPss(app.pid, mTmpLong, null);
18539                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18540                mPendingPssProcesses.remove(app);
18541                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18542                        + " to " + app.curProcState + ": "
18543                        + (SystemClock.uptimeMillis()-start) + "ms");
18544            }
18545            app.lastStateTime = now;
18546            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18547                    mTestPssMode, isSleeping(), now);
18548            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18549                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18550                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18551                    + (app.nextPssTime-now) + ": " + app);
18552        } else {
18553            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18554                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18555                    mTestPssMode)))) {
18556                requestPssLocked(app, app.setProcState);
18557                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18558                        mTestPssMode, isSleeping(), now);
18559            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18560                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18561        }
18562        if (app.setProcState != app.curProcState) {
18563            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18564                    "Proc state change of " + app.processName
18565                    + " to " + app.curProcState);
18566            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18567            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18568            if (setImportant && !curImportant) {
18569                // This app is no longer something we consider important enough to allow to
18570                // use arbitrary amounts of battery power.  Note
18571                // its current wake lock time to later know to kill it if
18572                // it is not behaving well.
18573                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18574                synchronized (stats) {
18575                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18576                            app.pid, SystemClock.elapsedRealtime());
18577                }
18578                app.lastCpuTime = app.curCpuTime;
18579
18580            }
18581            // Inform UsageStats of important process state change
18582            // Must be called before updating setProcState
18583            maybeUpdateUsageStatsLocked(app);
18584
18585            app.setProcState = app.curProcState;
18586            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18587                app.notCachedSinceIdle = false;
18588            }
18589            if (!doingAll) {
18590                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18591            } else {
18592                app.procStateChanged = true;
18593            }
18594        }
18595
18596        if (changes != 0) {
18597            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18598                    "Changes in " + app + ": " + changes);
18599            int i = mPendingProcessChanges.size()-1;
18600            ProcessChangeItem item = null;
18601            while (i >= 0) {
18602                item = mPendingProcessChanges.get(i);
18603                if (item.pid == app.pid) {
18604                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18605                            "Re-using existing item: " + item);
18606                    break;
18607                }
18608                i--;
18609            }
18610            if (i < 0) {
18611                // No existing item in pending changes; need a new one.
18612                final int NA = mAvailProcessChanges.size();
18613                if (NA > 0) {
18614                    item = mAvailProcessChanges.remove(NA-1);
18615                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18616                            "Retrieving available item: " + item);
18617                } else {
18618                    item = new ProcessChangeItem();
18619                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18620                            "Allocating new item: " + item);
18621                }
18622                item.changes = 0;
18623                item.pid = app.pid;
18624                item.uid = app.info.uid;
18625                if (mPendingProcessChanges.size() == 0) {
18626                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18627                            "*** Enqueueing dispatch processes changed!");
18628                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18629                }
18630                mPendingProcessChanges.add(item);
18631            }
18632            item.changes |= changes;
18633            item.processState = app.repProcState;
18634            item.foregroundActivities = app.repForegroundActivities;
18635            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18636                    "Item " + Integer.toHexString(System.identityHashCode(item))
18637                    + " " + app.toShortString() + ": changes=" + item.changes
18638                    + " procState=" + item.processState
18639                    + " foreground=" + item.foregroundActivities
18640                    + " type=" + app.adjType + " source=" + app.adjSource
18641                    + " target=" + app.adjTarget);
18642        }
18643
18644        return success;
18645    }
18646
18647    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18648        if (uidRec.pendingChange == null) {
18649            if (mPendingUidChanges.size() == 0) {
18650                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18651                        "*** Enqueueing dispatch uid changed!");
18652                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18653            }
18654            final int NA = mAvailUidChanges.size();
18655            if (NA > 0) {
18656                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18657                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18658                        "Retrieving available item: " + uidRec.pendingChange);
18659            } else {
18660                uidRec.pendingChange = new UidRecord.ChangeItem();
18661                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18662                        "Allocating new item: " + uidRec.pendingChange);
18663            }
18664            uidRec.pendingChange.uidRecord = uidRec;
18665            uidRec.pendingChange.uid = uidRec.uid;
18666            mPendingUidChanges.add(uidRec.pendingChange);
18667        }
18668        uidRec.pendingChange.gone = gone;
18669        uidRec.pendingChange.processState = uidRec.setProcState;
18670    }
18671
18672    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18673            String authority) {
18674        if (app == null) return;
18675        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18676            UserState userState = mStartedUsers.get(app.userId);
18677            if (userState == null) return;
18678            final long now = SystemClock.elapsedRealtime();
18679            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18680            if (lastReported == null || lastReported < now - 60 * 1000L) {
18681                mUsageStatsService.reportContentProviderUsage(
18682                        authority, providerPkgName, app.userId);
18683                userState.mProviderLastReportedFg.put(authority, now);
18684            }
18685        }
18686    }
18687
18688    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18689        if (DEBUG_USAGE_STATS) {
18690            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18691                    + "] state changes: old = " + app.setProcState + ", new = "
18692                    + app.curProcState);
18693        }
18694        if (mUsageStatsService == null) {
18695            return;
18696        }
18697        boolean isInteraction;
18698        // To avoid some abuse patterns, we are going to be careful about what we consider
18699        // to be an app interaction.  Being the top activity doesn't count while the display
18700        // is sleeping, nor do short foreground services.
18701        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18702            isInteraction = true;
18703            app.fgInteractionTime = 0;
18704        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18705            final long now = SystemClock.elapsedRealtime();
18706            if (app.fgInteractionTime == 0) {
18707                app.fgInteractionTime = now;
18708                isInteraction = false;
18709            } else {
18710                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18711            }
18712        } else {
18713            isInteraction = app.curProcState
18714                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18715            app.fgInteractionTime = 0;
18716        }
18717        if (isInteraction && !app.reportedInteraction) {
18718            String[] packages = app.getPackageList();
18719            if (packages != null) {
18720                for (int i = 0; i < packages.length; i++) {
18721                    mUsageStatsService.reportEvent(packages[i], app.userId,
18722                            UsageEvents.Event.SYSTEM_INTERACTION);
18723                }
18724            }
18725        }
18726        app.reportedInteraction = isInteraction;
18727    }
18728
18729    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18730        if (proc.thread != null) {
18731            if (proc.baseProcessTracker != null) {
18732                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18733            }
18734            if (proc.repProcState >= 0) {
18735                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18736                        proc.repProcState);
18737            }
18738        }
18739    }
18740
18741    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18742            ProcessRecord TOP_APP, boolean doingAll, long now) {
18743        if (app.thread == null) {
18744            return false;
18745        }
18746
18747        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18748
18749        return applyOomAdjLocked(app, doingAll, now);
18750    }
18751
18752    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18753            boolean oomAdj) {
18754        if (isForeground != proc.foregroundServices) {
18755            proc.foregroundServices = isForeground;
18756            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18757                    proc.info.uid);
18758            if (isForeground) {
18759                if (curProcs == null) {
18760                    curProcs = new ArrayList<ProcessRecord>();
18761                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18762                }
18763                if (!curProcs.contains(proc)) {
18764                    curProcs.add(proc);
18765                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18766                            proc.info.packageName, proc.info.uid);
18767                }
18768            } else {
18769                if (curProcs != null) {
18770                    if (curProcs.remove(proc)) {
18771                        mBatteryStatsService.noteEvent(
18772                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18773                                proc.info.packageName, proc.info.uid);
18774                        if (curProcs.size() <= 0) {
18775                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18776                        }
18777                    }
18778                }
18779            }
18780            if (oomAdj) {
18781                updateOomAdjLocked();
18782            }
18783        }
18784    }
18785
18786    private final ActivityRecord resumedAppLocked() {
18787        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18788        String pkg;
18789        int uid;
18790        if (act != null) {
18791            pkg = act.packageName;
18792            uid = act.info.applicationInfo.uid;
18793        } else {
18794            pkg = null;
18795            uid = -1;
18796        }
18797        // Has the UID or resumed package name changed?
18798        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18799                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18800            if (mCurResumedPackage != null) {
18801                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18802                        mCurResumedPackage, mCurResumedUid);
18803            }
18804            mCurResumedPackage = pkg;
18805            mCurResumedUid = uid;
18806            if (mCurResumedPackage != null) {
18807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18808                        mCurResumedPackage, mCurResumedUid);
18809            }
18810        }
18811        return act;
18812    }
18813
18814    final boolean updateOomAdjLocked(ProcessRecord app) {
18815        final ActivityRecord TOP_ACT = resumedAppLocked();
18816        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18817        final boolean wasCached = app.cached;
18818
18819        mAdjSeq++;
18820
18821        // This is the desired cached adjusment we want to tell it to use.
18822        // If our app is currently cached, we know it, and that is it.  Otherwise,
18823        // we don't know it yet, and it needs to now be cached we will then
18824        // need to do a complete oom adj.
18825        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18826                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18827        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18828                SystemClock.uptimeMillis());
18829        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18830            // Changed to/from cached state, so apps after it in the LRU
18831            // list may also be changed.
18832            updateOomAdjLocked();
18833        }
18834        return success;
18835    }
18836
18837    final void updateOomAdjLocked() {
18838        final ActivityRecord TOP_ACT = resumedAppLocked();
18839        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18840        final long now = SystemClock.uptimeMillis();
18841        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18842        final int N = mLruProcesses.size();
18843
18844        if (false) {
18845            RuntimeException e = new RuntimeException();
18846            e.fillInStackTrace();
18847            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18848        }
18849
18850        // Reset state in all uid records.
18851        for (int i=mActiveUids.size()-1; i>=0; i--) {
18852            final UidRecord uidRec = mActiveUids.valueAt(i);
18853            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18854                    "Starting update of " + uidRec);
18855            uidRec.reset();
18856        }
18857
18858        mAdjSeq++;
18859        mNewNumServiceProcs = 0;
18860        mNewNumAServiceProcs = 0;
18861
18862        final int emptyProcessLimit;
18863        final int cachedProcessLimit;
18864        if (mProcessLimit <= 0) {
18865            emptyProcessLimit = cachedProcessLimit = 0;
18866        } else if (mProcessLimit == 1) {
18867            emptyProcessLimit = 1;
18868            cachedProcessLimit = 0;
18869        } else {
18870            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18871            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18872        }
18873
18874        // Let's determine how many processes we have running vs.
18875        // how many slots we have for background processes; we may want
18876        // to put multiple processes in a slot of there are enough of
18877        // them.
18878        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18879                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18880        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18881        if (numEmptyProcs > cachedProcessLimit) {
18882            // If there are more empty processes than our limit on cached
18883            // processes, then use the cached process limit for the factor.
18884            // This ensures that the really old empty processes get pushed
18885            // down to the bottom, so if we are running low on memory we will
18886            // have a better chance at keeping around more cached processes
18887            // instead of a gazillion empty processes.
18888            numEmptyProcs = cachedProcessLimit;
18889        }
18890        int emptyFactor = numEmptyProcs/numSlots;
18891        if (emptyFactor < 1) emptyFactor = 1;
18892        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18893        if (cachedFactor < 1) cachedFactor = 1;
18894        int stepCached = 0;
18895        int stepEmpty = 0;
18896        int numCached = 0;
18897        int numEmpty = 0;
18898        int numTrimming = 0;
18899
18900        mNumNonCachedProcs = 0;
18901        mNumCachedHiddenProcs = 0;
18902
18903        // First update the OOM adjustment for each of the
18904        // application processes based on their current state.
18905        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18906        int nextCachedAdj = curCachedAdj+1;
18907        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18908        int nextEmptyAdj = curEmptyAdj+2;
18909        for (int i=N-1; i>=0; i--) {
18910            ProcessRecord app = mLruProcesses.get(i);
18911            if (!app.killedByAm && app.thread != null) {
18912                app.procStateChanged = false;
18913                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18914
18915                // If we haven't yet assigned the final cached adj
18916                // to the process, do that now.
18917                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18918                    switch (app.curProcState) {
18919                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18920                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18921                            // This process is a cached process holding activities...
18922                            // assign it the next cached value for that type, and then
18923                            // step that cached level.
18924                            app.curRawAdj = curCachedAdj;
18925                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18926                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18927                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18928                                    + ")");
18929                            if (curCachedAdj != nextCachedAdj) {
18930                                stepCached++;
18931                                if (stepCached >= cachedFactor) {
18932                                    stepCached = 0;
18933                                    curCachedAdj = nextCachedAdj;
18934                                    nextCachedAdj += 2;
18935                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18936                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18937                                    }
18938                                }
18939                            }
18940                            break;
18941                        default:
18942                            // For everything else, assign next empty cached process
18943                            // level and bump that up.  Note that this means that
18944                            // long-running services that have dropped down to the
18945                            // cached level will be treated as empty (since their process
18946                            // state is still as a service), which is what we want.
18947                            app.curRawAdj = curEmptyAdj;
18948                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18949                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18950                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18951                                    + ")");
18952                            if (curEmptyAdj != nextEmptyAdj) {
18953                                stepEmpty++;
18954                                if (stepEmpty >= emptyFactor) {
18955                                    stepEmpty = 0;
18956                                    curEmptyAdj = nextEmptyAdj;
18957                                    nextEmptyAdj += 2;
18958                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18959                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18960                                    }
18961                                }
18962                            }
18963                            break;
18964                    }
18965                }
18966
18967                applyOomAdjLocked(app, true, now);
18968
18969                // Count the number of process types.
18970                switch (app.curProcState) {
18971                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18972                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18973                        mNumCachedHiddenProcs++;
18974                        numCached++;
18975                        if (numCached > cachedProcessLimit) {
18976                            app.kill("cached #" + numCached, true);
18977                        }
18978                        break;
18979                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18980                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18981                                && app.lastActivityTime < oldTime) {
18982                            app.kill("empty for "
18983                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18984                                    / 1000) + "s", true);
18985                        } else {
18986                            numEmpty++;
18987                            if (numEmpty > emptyProcessLimit) {
18988                                app.kill("empty #" + numEmpty, true);
18989                            }
18990                        }
18991                        break;
18992                    default:
18993                        mNumNonCachedProcs++;
18994                        break;
18995                }
18996
18997                if (app.isolated && app.services.size() <= 0) {
18998                    // If this is an isolated process, and there are no
18999                    // services running in it, then the process is no longer
19000                    // needed.  We agressively kill these because we can by
19001                    // definition not re-use the same process again, and it is
19002                    // good to avoid having whatever code was running in them
19003                    // left sitting around after no longer needed.
19004                    app.kill("isolated not needed", true);
19005                } else {
19006                    // Keeping this process, update its uid.
19007                    final UidRecord uidRec = app.uidRecord;
19008                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19009                        uidRec.curProcState = app.curProcState;
19010                    }
19011                }
19012
19013                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19014                        && !app.killedByAm) {
19015                    numTrimming++;
19016                }
19017            }
19018        }
19019
19020        mNumServiceProcs = mNewNumServiceProcs;
19021
19022        // Now determine the memory trimming level of background processes.
19023        // Unfortunately we need to start at the back of the list to do this
19024        // properly.  We only do this if the number of background apps we
19025        // are managing to keep around is less than half the maximum we desire;
19026        // if we are keeping a good number around, we'll let them use whatever
19027        // memory they want.
19028        final int numCachedAndEmpty = numCached + numEmpty;
19029        int memFactor;
19030        if (numCached <= ProcessList.TRIM_CACHED_APPS
19031                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19032            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19033                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19034            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19035                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19036            } else {
19037                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19038            }
19039        } else {
19040            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19041        }
19042        // We always allow the memory level to go up (better).  We only allow it to go
19043        // down if we are in a state where that is allowed, *and* the total number of processes
19044        // has gone down since last time.
19045        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19046                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19047                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19048        if (memFactor > mLastMemoryLevel) {
19049            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19050                memFactor = mLastMemoryLevel;
19051                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19052            }
19053        }
19054        mLastMemoryLevel = memFactor;
19055        mLastNumProcesses = mLruProcesses.size();
19056        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19057        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19058        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19059            if (mLowRamStartTime == 0) {
19060                mLowRamStartTime = now;
19061            }
19062            int step = 0;
19063            int fgTrimLevel;
19064            switch (memFactor) {
19065                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19066                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19067                    break;
19068                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19069                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19070                    break;
19071                default:
19072                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19073                    break;
19074            }
19075            int factor = numTrimming/3;
19076            int minFactor = 2;
19077            if (mHomeProcess != null) minFactor++;
19078            if (mPreviousProcess != null) minFactor++;
19079            if (factor < minFactor) factor = minFactor;
19080            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19081            for (int i=N-1; i>=0; i--) {
19082                ProcessRecord app = mLruProcesses.get(i);
19083                if (allChanged || app.procStateChanged) {
19084                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19085                    app.procStateChanged = false;
19086                }
19087                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19088                        && !app.killedByAm) {
19089                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19090                        try {
19091                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19092                                    "Trimming memory of " + app.processName + " to " + curLevel);
19093                            app.thread.scheduleTrimMemory(curLevel);
19094                        } catch (RemoteException e) {
19095                        }
19096                        if (false) {
19097                            // For now we won't do this; our memory trimming seems
19098                            // to be good enough at this point that destroying
19099                            // activities causes more harm than good.
19100                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19101                                    && app != mHomeProcess && app != mPreviousProcess) {
19102                                // Need to do this on its own message because the stack may not
19103                                // be in a consistent state at this point.
19104                                // For these apps we will also finish their activities
19105                                // to help them free memory.
19106                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19107                            }
19108                        }
19109                    }
19110                    app.trimMemoryLevel = curLevel;
19111                    step++;
19112                    if (step >= factor) {
19113                        step = 0;
19114                        switch (curLevel) {
19115                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19116                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19117                                break;
19118                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19119                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19120                                break;
19121                        }
19122                    }
19123                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19124                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19125                            && app.thread != null) {
19126                        try {
19127                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19128                                    "Trimming memory of heavy-weight " + app.processName
19129                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19130                            app.thread.scheduleTrimMemory(
19131                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19132                        } catch (RemoteException e) {
19133                        }
19134                    }
19135                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19136                } else {
19137                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19138                            || app.systemNoUi) && app.pendingUiClean) {
19139                        // If this application is now in the background and it
19140                        // had done UI, then give it the special trim level to
19141                        // have it free UI resources.
19142                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19143                        if (app.trimMemoryLevel < level && app.thread != null) {
19144                            try {
19145                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19146                                        "Trimming memory of bg-ui " + app.processName
19147                                        + " to " + level);
19148                                app.thread.scheduleTrimMemory(level);
19149                            } catch (RemoteException e) {
19150                            }
19151                        }
19152                        app.pendingUiClean = false;
19153                    }
19154                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19155                        try {
19156                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19157                                    "Trimming memory of fg " + app.processName
19158                                    + " to " + fgTrimLevel);
19159                            app.thread.scheduleTrimMemory(fgTrimLevel);
19160                        } catch (RemoteException e) {
19161                        }
19162                    }
19163                    app.trimMemoryLevel = fgTrimLevel;
19164                }
19165            }
19166        } else {
19167            if (mLowRamStartTime != 0) {
19168                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19169                mLowRamStartTime = 0;
19170            }
19171            for (int i=N-1; i>=0; i--) {
19172                ProcessRecord app = mLruProcesses.get(i);
19173                if (allChanged || app.procStateChanged) {
19174                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19175                    app.procStateChanged = false;
19176                }
19177                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19178                        || app.systemNoUi) && app.pendingUiClean) {
19179                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19180                            && app.thread != null) {
19181                        try {
19182                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19183                                    "Trimming memory of ui hidden " + app.processName
19184                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19185                            app.thread.scheduleTrimMemory(
19186                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19187                        } catch (RemoteException e) {
19188                        }
19189                    }
19190                    app.pendingUiClean = false;
19191                }
19192                app.trimMemoryLevel = 0;
19193            }
19194        }
19195
19196        if (mAlwaysFinishActivities) {
19197            // Need to do this on its own message because the stack may not
19198            // be in a consistent state at this point.
19199            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19200        }
19201
19202        if (allChanged) {
19203            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19204        }
19205
19206        // Update from any uid changes.
19207        for (int i=mActiveUids.size()-1; i>=0; i--) {
19208            final UidRecord uidRec = mActiveUids.valueAt(i);
19209            if (uidRec.setProcState != uidRec.curProcState) {
19210                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19211                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19212                        + " to " + uidRec.curProcState);
19213                uidRec.setProcState = uidRec.curProcState;
19214                enqueueUidChangeLocked(uidRec, false);
19215            }
19216        }
19217
19218        if (mProcessStats.shouldWriteNowLocked(now)) {
19219            mHandler.post(new Runnable() {
19220                @Override public void run() {
19221                    synchronized (ActivityManagerService.this) {
19222                        mProcessStats.writeStateAsyncLocked();
19223                    }
19224                }
19225            });
19226        }
19227
19228        if (DEBUG_OOM_ADJ) {
19229            final long duration = SystemClock.uptimeMillis() - now;
19230            if (false) {
19231                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19232                        new RuntimeException("here").fillInStackTrace());
19233            } else {
19234                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19235            }
19236        }
19237    }
19238
19239    final void trimApplications() {
19240        synchronized (this) {
19241            int i;
19242
19243            // First remove any unused application processes whose package
19244            // has been removed.
19245            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19246                final ProcessRecord app = mRemovedProcesses.get(i);
19247                if (app.activities.size() == 0
19248                        && app.curReceiver == null && app.services.size() == 0) {
19249                    Slog.i(
19250                        TAG, "Exiting empty application process "
19251                        + app.processName + " ("
19252                        + (app.thread != null ? app.thread.asBinder() : null)
19253                        + ")\n");
19254                    if (app.pid > 0 && app.pid != MY_PID) {
19255                        app.kill("empty", false);
19256                    } else {
19257                        try {
19258                            app.thread.scheduleExit();
19259                        } catch (Exception e) {
19260                            // Ignore exceptions.
19261                        }
19262                    }
19263                    cleanUpApplicationRecordLocked(app, false, true, -1);
19264                    mRemovedProcesses.remove(i);
19265
19266                    if (app.persistent) {
19267                        addAppLocked(app.info, false, null /* ABI override */);
19268                    }
19269                }
19270            }
19271
19272            // Now update the oom adj for all processes.
19273            updateOomAdjLocked();
19274        }
19275    }
19276
19277    /** This method sends the specified signal to each of the persistent apps */
19278    public void signalPersistentProcesses(int sig) throws RemoteException {
19279        if (sig != Process.SIGNAL_USR1) {
19280            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19281        }
19282
19283        synchronized (this) {
19284            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19285                    != PackageManager.PERMISSION_GRANTED) {
19286                throw new SecurityException("Requires permission "
19287                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19288            }
19289
19290            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19291                ProcessRecord r = mLruProcesses.get(i);
19292                if (r.thread != null && r.persistent) {
19293                    Process.sendSignal(r.pid, sig);
19294                }
19295            }
19296        }
19297    }
19298
19299    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19300        if (proc == null || proc == mProfileProc) {
19301            proc = mProfileProc;
19302            profileType = mProfileType;
19303            clearProfilerLocked();
19304        }
19305        if (proc == null) {
19306            return;
19307        }
19308        try {
19309            proc.thread.profilerControl(false, null, profileType);
19310        } catch (RemoteException e) {
19311            throw new IllegalStateException("Process disappeared");
19312        }
19313    }
19314
19315    private void clearProfilerLocked() {
19316        if (mProfileFd != null) {
19317            try {
19318                mProfileFd.close();
19319            } catch (IOException e) {
19320            }
19321        }
19322        mProfileApp = null;
19323        mProfileProc = null;
19324        mProfileFile = null;
19325        mProfileType = 0;
19326        mAutoStopProfiler = false;
19327        mSamplingInterval = 0;
19328    }
19329
19330    public boolean profileControl(String process, int userId, boolean start,
19331            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19332
19333        try {
19334            synchronized (this) {
19335                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19336                // its own permission.
19337                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19338                        != PackageManager.PERMISSION_GRANTED) {
19339                    throw new SecurityException("Requires permission "
19340                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19341                }
19342
19343                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19344                    throw new IllegalArgumentException("null profile info or fd");
19345                }
19346
19347                ProcessRecord proc = null;
19348                if (process != null) {
19349                    proc = findProcessLocked(process, userId, "profileControl");
19350                }
19351
19352                if (start && (proc == null || proc.thread == null)) {
19353                    throw new IllegalArgumentException("Unknown process: " + process);
19354                }
19355
19356                if (start) {
19357                    stopProfilerLocked(null, 0);
19358                    setProfileApp(proc.info, proc.processName, profilerInfo);
19359                    mProfileProc = proc;
19360                    mProfileType = profileType;
19361                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19362                    try {
19363                        fd = fd.dup();
19364                    } catch (IOException e) {
19365                        fd = null;
19366                    }
19367                    profilerInfo.profileFd = fd;
19368                    proc.thread.profilerControl(start, profilerInfo, profileType);
19369                    fd = null;
19370                    mProfileFd = null;
19371                } else {
19372                    stopProfilerLocked(proc, profileType);
19373                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19374                        try {
19375                            profilerInfo.profileFd.close();
19376                        } catch (IOException e) {
19377                        }
19378                    }
19379                }
19380
19381                return true;
19382            }
19383        } catch (RemoteException e) {
19384            throw new IllegalStateException("Process disappeared");
19385        } finally {
19386            if (profilerInfo != null && profilerInfo.profileFd != null) {
19387                try {
19388                    profilerInfo.profileFd.close();
19389                } catch (IOException e) {
19390                }
19391            }
19392        }
19393    }
19394
19395    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19396        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19397                userId, true, ALLOW_FULL_ONLY, callName, null);
19398        ProcessRecord proc = null;
19399        try {
19400            int pid = Integer.parseInt(process);
19401            synchronized (mPidsSelfLocked) {
19402                proc = mPidsSelfLocked.get(pid);
19403            }
19404        } catch (NumberFormatException e) {
19405        }
19406
19407        if (proc == null) {
19408            ArrayMap<String, SparseArray<ProcessRecord>> all
19409                    = mProcessNames.getMap();
19410            SparseArray<ProcessRecord> procs = all.get(process);
19411            if (procs != null && procs.size() > 0) {
19412                proc = procs.valueAt(0);
19413                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19414                    for (int i=1; i<procs.size(); i++) {
19415                        ProcessRecord thisProc = procs.valueAt(i);
19416                        if (thisProc.userId == userId) {
19417                            proc = thisProc;
19418                            break;
19419                        }
19420                    }
19421                }
19422            }
19423        }
19424
19425        return proc;
19426    }
19427
19428    public boolean dumpHeap(String process, int userId, boolean managed,
19429            String path, ParcelFileDescriptor fd) throws RemoteException {
19430
19431        try {
19432            synchronized (this) {
19433                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19434                // its own permission (same as profileControl).
19435                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19436                        != PackageManager.PERMISSION_GRANTED) {
19437                    throw new SecurityException("Requires permission "
19438                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19439                }
19440
19441                if (fd == null) {
19442                    throw new IllegalArgumentException("null fd");
19443                }
19444
19445                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19446                if (proc == null || proc.thread == null) {
19447                    throw new IllegalArgumentException("Unknown process: " + process);
19448                }
19449
19450                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19451                if (!isDebuggable) {
19452                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19453                        throw new SecurityException("Process not debuggable: " + proc);
19454                    }
19455                }
19456
19457                proc.thread.dumpHeap(managed, path, fd);
19458                fd = null;
19459                return true;
19460            }
19461        } catch (RemoteException e) {
19462            throw new IllegalStateException("Process disappeared");
19463        } finally {
19464            if (fd != null) {
19465                try {
19466                    fd.close();
19467                } catch (IOException e) {
19468                }
19469            }
19470        }
19471    }
19472
19473    @Override
19474    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19475            String reportPackage) {
19476        if (processName != null) {
19477            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19478                    "setDumpHeapDebugLimit()");
19479        } else {
19480            synchronized (mPidsSelfLocked) {
19481                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19482                if (proc == null) {
19483                    throw new SecurityException("No process found for calling pid "
19484                            + Binder.getCallingPid());
19485                }
19486                if (!Build.IS_DEBUGGABLE
19487                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19488                    throw new SecurityException("Not running a debuggable build");
19489                }
19490                processName = proc.processName;
19491                uid = proc.uid;
19492                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19493                    throw new SecurityException("Package " + reportPackage + " is not running in "
19494                            + proc);
19495                }
19496            }
19497        }
19498        synchronized (this) {
19499            if (maxMemSize > 0) {
19500                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19501            } else {
19502                if (uid != 0) {
19503                    mMemWatchProcesses.remove(processName, uid);
19504                } else {
19505                    mMemWatchProcesses.getMap().remove(processName);
19506                }
19507            }
19508        }
19509    }
19510
19511    @Override
19512    public void dumpHeapFinished(String path) {
19513        synchronized (this) {
19514            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19515                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19516                        + " does not match last pid " + mMemWatchDumpPid);
19517                return;
19518            }
19519            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19520                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19521                        + " does not match last path " + mMemWatchDumpFile);
19522                return;
19523            }
19524            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19525            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19526        }
19527    }
19528
19529    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19530    public void monitor() {
19531        synchronized (this) { }
19532    }
19533
19534    void onCoreSettingsChange(Bundle settings) {
19535        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19536            ProcessRecord processRecord = mLruProcesses.get(i);
19537            try {
19538                if (processRecord.thread != null) {
19539                    processRecord.thread.setCoreSettings(settings);
19540                }
19541            } catch (RemoteException re) {
19542                /* ignore */
19543            }
19544        }
19545    }
19546
19547    // Multi-user methods
19548
19549    /**
19550     * Start user, if its not already running, but don't bring it to foreground.
19551     */
19552    @Override
19553    public boolean startUserInBackground(final int userId) {
19554        return startUser(userId, /* foreground */ false);
19555    }
19556
19557    /**
19558     * Start user, if its not already running, and bring it to foreground.
19559     */
19560    boolean startUserInForeground(final int userId, Dialog dlg) {
19561        boolean result = startUser(userId, /* foreground */ true);
19562        dlg.dismiss();
19563        return result;
19564    }
19565
19566    /**
19567     * Refreshes the list of users related to the current user when either a
19568     * user switch happens or when a new related user is started in the
19569     * background.
19570     */
19571    private void updateCurrentProfileIdsLocked() {
19572        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19573                mCurrentUserId, false /* enabledOnly */);
19574        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19575        for (int i = 0; i < currentProfileIds.length; i++) {
19576            currentProfileIds[i] = profiles.get(i).id;
19577        }
19578        mCurrentProfileIds = currentProfileIds;
19579
19580        synchronized (mUserProfileGroupIdsSelfLocked) {
19581            mUserProfileGroupIdsSelfLocked.clear();
19582            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19583            for (int i = 0; i < users.size(); i++) {
19584                UserInfo user = users.get(i);
19585                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19586                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19587                }
19588            }
19589        }
19590    }
19591
19592    private Set<Integer> getProfileIdsLocked(int userId) {
19593        Set<Integer> userIds = new HashSet<Integer>();
19594        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19595                userId, false /* enabledOnly */);
19596        for (UserInfo user : profiles) {
19597            userIds.add(Integer.valueOf(user.id));
19598        }
19599        return userIds;
19600    }
19601
19602    @Override
19603    public boolean switchUser(final int userId) {
19604        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19605        String userName;
19606        synchronized (this) {
19607            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19608            if (userInfo == null) {
19609                Slog.w(TAG, "No user info for user #" + userId);
19610                return false;
19611            }
19612            if (userInfo.isManagedProfile()) {
19613                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19614                return false;
19615            }
19616            userName = userInfo.name;
19617            mTargetUserId = userId;
19618        }
19619        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19620        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19621        return true;
19622    }
19623
19624    private void showUserSwitchDialog(int userId, String userName) {
19625        // The dialog will show and then initiate the user switch by calling startUserInForeground
19626        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19627                true /* above system */);
19628        d.show();
19629    }
19630
19631    private boolean startUser(final int userId, final boolean foreground) {
19632        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19633                != PackageManager.PERMISSION_GRANTED) {
19634            String msg = "Permission Denial: switchUser() from pid="
19635                    + Binder.getCallingPid()
19636                    + ", uid=" + Binder.getCallingUid()
19637                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19638            Slog.w(TAG, msg);
19639            throw new SecurityException(msg);
19640        }
19641
19642        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19643
19644        final long ident = Binder.clearCallingIdentity();
19645        try {
19646            synchronized (this) {
19647                final int oldUserId = mCurrentUserId;
19648                if (oldUserId == userId) {
19649                    return true;
19650                }
19651
19652                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19653                        "startUser", false);
19654
19655                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19656                if (userInfo == null) {
19657                    Slog.w(TAG, "No user info for user #" + userId);
19658                    return false;
19659                }
19660                if (foreground && userInfo.isManagedProfile()) {
19661                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19662                    return false;
19663                }
19664
19665                if (foreground) {
19666                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19667                            R.anim.screen_user_enter);
19668                }
19669
19670                boolean needStart = false;
19671
19672                // If the user we are switching to is not currently started, then
19673                // we need to start it now.
19674                if (mStartedUsers.get(userId) == null) {
19675                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19676                    updateStartedUserArrayLocked();
19677                    needStart = true;
19678                }
19679
19680                final Integer userIdInt = Integer.valueOf(userId);
19681                mUserLru.remove(userIdInt);
19682                mUserLru.add(userIdInt);
19683
19684                if (foreground) {
19685                    mCurrentUserId = userId;
19686                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19687                    updateCurrentProfileIdsLocked();
19688                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19689                    // Once the internal notion of the active user has switched, we lock the device
19690                    // with the option to show the user switcher on the keyguard.
19691                    mWindowManager.lockNow(null);
19692                } else {
19693                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19694                    updateCurrentProfileIdsLocked();
19695                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19696                    mUserLru.remove(currentUserIdInt);
19697                    mUserLru.add(currentUserIdInt);
19698                }
19699
19700                final UserState uss = mStartedUsers.get(userId);
19701
19702                // Make sure user is in the started state.  If it is currently
19703                // stopping, we need to knock that off.
19704                if (uss.mState == UserState.STATE_STOPPING) {
19705                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19706                    // so we can just fairly silently bring the user back from
19707                    // the almost-dead.
19708                    uss.mState = UserState.STATE_RUNNING;
19709                    updateStartedUserArrayLocked();
19710                    needStart = true;
19711                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19712                    // This means ACTION_SHUTDOWN has been sent, so we will
19713                    // need to treat this as a new boot of the user.
19714                    uss.mState = UserState.STATE_BOOTING;
19715                    updateStartedUserArrayLocked();
19716                    needStart = true;
19717                }
19718
19719                if (uss.mState == UserState.STATE_BOOTING) {
19720                    // Booting up a new user, need to tell system services about it.
19721                    // Note that this is on the same handler as scheduling of broadcasts,
19722                    // which is important because it needs to go first.
19723                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19724                }
19725
19726                if (foreground) {
19727                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19728                            oldUserId));
19729                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19730                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19731                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19732                            oldUserId, userId, uss));
19733                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19734                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19735                }
19736
19737                if (needStart) {
19738                    // Send USER_STARTED broadcast
19739                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19740                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19741                            | Intent.FLAG_RECEIVER_FOREGROUND);
19742                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19743                    broadcastIntentLocked(null, null, intent,
19744                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19745                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19746                }
19747
19748                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19749                    if (userId != UserHandle.USER_OWNER) {
19750                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19751                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19752                        broadcastIntentLocked(null, null, intent, null,
19753                                new IIntentReceiver.Stub() {
19754                                    public void performReceive(Intent intent, int resultCode,
19755                                            String data, Bundle extras, boolean ordered,
19756                                            boolean sticky, int sendingUser) {
19757                                        onUserInitialized(uss, foreground, oldUserId, userId);
19758                                    }
19759                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19760                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19761                        uss.initializing = true;
19762                    } else {
19763                        getUserManagerLocked().makeInitialized(userInfo.id);
19764                    }
19765                }
19766
19767                if (foreground) {
19768                    if (!uss.initializing) {
19769                        moveUserToForeground(uss, oldUserId, userId);
19770                    }
19771                } else {
19772                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19773                }
19774
19775                if (needStart) {
19776                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19777                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19778                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19779                    broadcastIntentLocked(null, null, intent,
19780                            null, new IIntentReceiver.Stub() {
19781                                @Override
19782                                public void performReceive(Intent intent, int resultCode,
19783                                        String data, Bundle extras, boolean ordered, boolean sticky,
19784                                        int sendingUser) throws RemoteException {
19785                                }
19786                            }, 0, null, null,
19787                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19788                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19789                }
19790            }
19791        } finally {
19792            Binder.restoreCallingIdentity(ident);
19793        }
19794
19795        return true;
19796    }
19797
19798    void dispatchForegroundProfileChanged(int userId) {
19799        final int N = mUserSwitchObservers.beginBroadcast();
19800        for (int i = 0; i < N; i++) {
19801            try {
19802                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19803            } catch (RemoteException e) {
19804                // Ignore
19805            }
19806        }
19807        mUserSwitchObservers.finishBroadcast();
19808    }
19809
19810    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19811        long ident = Binder.clearCallingIdentity();
19812        try {
19813            Intent intent;
19814            if (oldUserId >= 0) {
19815                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19816                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19817                int count = profiles.size();
19818                for (int i = 0; i < count; i++) {
19819                    int profileUserId = profiles.get(i).id;
19820                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19821                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19822                            | Intent.FLAG_RECEIVER_FOREGROUND);
19823                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19824                    broadcastIntentLocked(null, null, intent,
19825                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19826                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19827                }
19828            }
19829            if (newUserId >= 0) {
19830                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19831                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19832                int count = profiles.size();
19833                for (int i = 0; i < count; i++) {
19834                    int profileUserId = profiles.get(i).id;
19835                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19836                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19837                            | Intent.FLAG_RECEIVER_FOREGROUND);
19838                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19839                    broadcastIntentLocked(null, null, intent,
19840                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19841                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19842                }
19843                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19844                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19845                        | Intent.FLAG_RECEIVER_FOREGROUND);
19846                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19847                broadcastIntentLocked(null, null, intent,
19848                        null, null, 0, null, null,
19849                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19850                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19851            }
19852        } finally {
19853            Binder.restoreCallingIdentity(ident);
19854        }
19855    }
19856
19857    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19858            final int newUserId) {
19859        final int N = mUserSwitchObservers.beginBroadcast();
19860        if (N > 0) {
19861            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19862                int mCount = 0;
19863                @Override
19864                public void sendResult(Bundle data) throws RemoteException {
19865                    synchronized (ActivityManagerService.this) {
19866                        if (mCurUserSwitchCallback == this) {
19867                            mCount++;
19868                            if (mCount == N) {
19869                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19870                            }
19871                        }
19872                    }
19873                }
19874            };
19875            synchronized (this) {
19876                uss.switching = true;
19877                mCurUserSwitchCallback = callback;
19878            }
19879            for (int i=0; i<N; i++) {
19880                try {
19881                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19882                            newUserId, callback);
19883                } catch (RemoteException e) {
19884                }
19885            }
19886        } else {
19887            synchronized (this) {
19888                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19889            }
19890        }
19891        mUserSwitchObservers.finishBroadcast();
19892    }
19893
19894    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19895        synchronized (this) {
19896            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19897            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19898        }
19899    }
19900
19901    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19902        mCurUserSwitchCallback = null;
19903        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19904        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19905                oldUserId, newUserId, uss));
19906    }
19907
19908    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
19909        synchronized (this) {
19910            if (foreground) {
19911                moveUserToForeground(uss, oldUserId, newUserId);
19912            }
19913        }
19914
19915        completeSwitchAndInitalize(uss, newUserId, true, false);
19916    }
19917
19918    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
19919        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19920        if (homeInFront) {
19921            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19922        } else {
19923            mStackSupervisor.resumeTopActivitiesLocked();
19924        }
19925        EventLogTags.writeAmSwitchUser(newUserId);
19926        getUserManagerLocked().onUserForeground(newUserId);
19927        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19928    }
19929
19930    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
19931        completeSwitchAndInitalize(uss, newUserId, false, true);
19932    }
19933
19934    void completeSwitchAndInitalize(UserState uss, int newUserId,
19935            boolean clearInitializing, boolean clearSwitching) {
19936        boolean unfrozen = false;
19937        synchronized (this) {
19938            if (clearInitializing) {
19939                uss.initializing = false;
19940                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19941            }
19942            if (clearSwitching) {
19943                uss.switching = false;
19944            }
19945            if (!uss.switching && !uss.initializing) {
19946                mWindowManager.stopFreezingScreen();
19947                unfrozen = true;
19948            }
19949        }
19950        if (unfrozen) {
19951            final int N = mUserSwitchObservers.beginBroadcast();
19952            for (int i=0; i<N; i++) {
19953                try {
19954                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19955                } catch (RemoteException e) {
19956                }
19957            }
19958            mUserSwitchObservers.finishBroadcast();
19959        }
19960        stopGuestUserIfBackground();
19961    }
19962
19963    /**
19964     * Stops the guest user if it has gone to the background.
19965     */
19966    private void stopGuestUserIfBackground() {
19967        synchronized (this) {
19968            final int num = mUserLru.size();
19969            for (int i = 0; i < num; i++) {
19970                Integer oldUserId = mUserLru.get(i);
19971                UserState oldUss = mStartedUsers.get(oldUserId);
19972                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19973                        || oldUss.mState == UserState.STATE_STOPPING
19974                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
19975                    continue;
19976                }
19977                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19978                if (userInfo.isGuest()) {
19979                    // This is a user to be stopped.
19980                    stopUserLocked(oldUserId, null);
19981                    break;
19982                }
19983            }
19984        }
19985    }
19986
19987    void scheduleStartProfilesLocked() {
19988        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19989            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19990                    DateUtils.SECOND_IN_MILLIS);
19991        }
19992    }
19993
19994    void startProfilesLocked() {
19995        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19996        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19997                mCurrentUserId, false /* enabledOnly */);
19998        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19999        for (UserInfo user : profiles) {
20000            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20001                    && user.id != mCurrentUserId) {
20002                toStart.add(user);
20003            }
20004        }
20005        final int n = toStart.size();
20006        int i = 0;
20007        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20008            startUserInBackground(toStart.get(i).id);
20009        }
20010        if (i < n) {
20011            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20012        }
20013    }
20014
20015    void finishUserBoot(UserState uss) {
20016        synchronized (this) {
20017            if (uss.mState == UserState.STATE_BOOTING
20018                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20019                uss.mState = UserState.STATE_RUNNING;
20020                final int userId = uss.mHandle.getIdentifier();
20021                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20022                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20023                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20024                broadcastIntentLocked(null, null, intent,
20025                        null, null, 0, null, null,
20026                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
20027                        null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20028            }
20029        }
20030    }
20031
20032    void finishUserSwitch(UserState uss) {
20033        synchronized (this) {
20034            finishUserBoot(uss);
20035
20036            startProfilesLocked();
20037
20038            int num = mUserLru.size();
20039            int i = 0;
20040            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20041                Integer oldUserId = mUserLru.get(i);
20042                UserState oldUss = mStartedUsers.get(oldUserId);
20043                if (oldUss == null) {
20044                    // Shouldn't happen, but be sane if it does.
20045                    mUserLru.remove(i);
20046                    num--;
20047                    continue;
20048                }
20049                if (oldUss.mState == UserState.STATE_STOPPING
20050                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20051                    // This user is already stopping, doesn't count.
20052                    num--;
20053                    i++;
20054                    continue;
20055                }
20056                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20057                    // Owner and current can't be stopped, but count as running.
20058                    i++;
20059                    continue;
20060                }
20061                // This is a user to be stopped.
20062                stopUserLocked(oldUserId, null);
20063                num--;
20064                i++;
20065            }
20066        }
20067    }
20068
20069    @Override
20070    public int stopUser(final int userId, final IStopUserCallback callback) {
20071        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20072                != PackageManager.PERMISSION_GRANTED) {
20073            String msg = "Permission Denial: switchUser() from pid="
20074                    + Binder.getCallingPid()
20075                    + ", uid=" + Binder.getCallingUid()
20076                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20077            Slog.w(TAG, msg);
20078            throw new SecurityException(msg);
20079        }
20080        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20081            throw new IllegalArgumentException("Can't stop primary user " + userId);
20082        }
20083        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20084        synchronized (this) {
20085            return stopUserLocked(userId, callback);
20086        }
20087    }
20088
20089    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20090        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20091        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20092            return ActivityManager.USER_OP_IS_CURRENT;
20093        }
20094
20095        final UserState uss = mStartedUsers.get(userId);
20096        if (uss == null) {
20097            // User is not started, nothing to do...  but we do need to
20098            // callback if requested.
20099            if (callback != null) {
20100                mHandler.post(new Runnable() {
20101                    @Override
20102                    public void run() {
20103                        try {
20104                            callback.userStopped(userId);
20105                        } catch (RemoteException e) {
20106                        }
20107                    }
20108                });
20109            }
20110            return ActivityManager.USER_OP_SUCCESS;
20111        }
20112
20113        if (callback != null) {
20114            uss.mStopCallbacks.add(callback);
20115        }
20116
20117        if (uss.mState != UserState.STATE_STOPPING
20118                && uss.mState != UserState.STATE_SHUTDOWN) {
20119            uss.mState = UserState.STATE_STOPPING;
20120            updateStartedUserArrayLocked();
20121
20122            long ident = Binder.clearCallingIdentity();
20123            try {
20124                // We are going to broadcast ACTION_USER_STOPPING and then
20125                // once that is done send a final ACTION_SHUTDOWN and then
20126                // stop the user.
20127                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20128                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20129                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20130                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20131                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20132                // This is the result receiver for the final shutdown broadcast.
20133                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20134                    @Override
20135                    public void performReceive(Intent intent, int resultCode, String data,
20136                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20137                        finishUserStop(uss);
20138                    }
20139                };
20140                // This is the result receiver for the initial stopping broadcast.
20141                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20142                    @Override
20143                    public void performReceive(Intent intent, int resultCode, String data,
20144                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20145                        // On to the next.
20146                        synchronized (ActivityManagerService.this) {
20147                            if (uss.mState != UserState.STATE_STOPPING) {
20148                                // Whoops, we are being started back up.  Abort, abort!
20149                                return;
20150                            }
20151                            uss.mState = UserState.STATE_SHUTDOWN;
20152                        }
20153                        mBatteryStatsService.noteEvent(
20154                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20155                                Integer.toString(userId), userId);
20156                        mSystemServiceManager.stopUser(userId);
20157                        broadcastIntentLocked(null, null, shutdownIntent,
20158                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20159                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20160                    }
20161                };
20162                // Kick things off.
20163                broadcastIntentLocked(null, null, stoppingIntent,
20164                        null, stoppingReceiver, 0, null, null,
20165                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20166                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20167            } finally {
20168                Binder.restoreCallingIdentity(ident);
20169            }
20170        }
20171
20172        return ActivityManager.USER_OP_SUCCESS;
20173    }
20174
20175    void finishUserStop(UserState uss) {
20176        final int userId = uss.mHandle.getIdentifier();
20177        boolean stopped;
20178        ArrayList<IStopUserCallback> callbacks;
20179        synchronized (this) {
20180            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20181            if (mStartedUsers.get(userId) != uss) {
20182                stopped = false;
20183            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20184                stopped = false;
20185            } else {
20186                stopped = true;
20187                // User can no longer run.
20188                mStartedUsers.remove(userId);
20189                mUserLru.remove(Integer.valueOf(userId));
20190                updateStartedUserArrayLocked();
20191
20192                // Clean up all state and processes associated with the user.
20193                // Kill all the processes for the user.
20194                forceStopUserLocked(userId, "finish user");
20195            }
20196
20197            // Explicitly remove the old information in mRecentTasks.
20198            mRecentTasks.removeTasksForUserLocked(userId);
20199        }
20200
20201        for (int i=0; i<callbacks.size(); i++) {
20202            try {
20203                if (stopped) callbacks.get(i).userStopped(userId);
20204                else callbacks.get(i).userStopAborted(userId);
20205            } catch (RemoteException e) {
20206            }
20207        }
20208
20209        if (stopped) {
20210            mSystemServiceManager.cleanupUser(userId);
20211            synchronized (this) {
20212                mStackSupervisor.removeUserLocked(userId);
20213            }
20214        }
20215    }
20216
20217    @Override
20218    public UserInfo getCurrentUser() {
20219        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20220                != PackageManager.PERMISSION_GRANTED) && (
20221                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20222                != PackageManager.PERMISSION_GRANTED)) {
20223            String msg = "Permission Denial: getCurrentUser() from pid="
20224                    + Binder.getCallingPid()
20225                    + ", uid=" + Binder.getCallingUid()
20226                    + " requires " + INTERACT_ACROSS_USERS;
20227            Slog.w(TAG, msg);
20228            throw new SecurityException(msg);
20229        }
20230        synchronized (this) {
20231            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20232            return getUserManagerLocked().getUserInfo(userId);
20233        }
20234    }
20235
20236    int getCurrentUserIdLocked() {
20237        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20238    }
20239
20240    @Override
20241    public boolean isUserRunning(int userId, boolean orStopped) {
20242        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20243                != PackageManager.PERMISSION_GRANTED) {
20244            String msg = "Permission Denial: isUserRunning() from pid="
20245                    + Binder.getCallingPid()
20246                    + ", uid=" + Binder.getCallingUid()
20247                    + " requires " + INTERACT_ACROSS_USERS;
20248            Slog.w(TAG, msg);
20249            throw new SecurityException(msg);
20250        }
20251        synchronized (this) {
20252            return isUserRunningLocked(userId, orStopped);
20253        }
20254    }
20255
20256    boolean isUserRunningLocked(int userId, boolean orStopped) {
20257        UserState state = mStartedUsers.get(userId);
20258        if (state == null) {
20259            return false;
20260        }
20261        if (orStopped) {
20262            return true;
20263        }
20264        return state.mState != UserState.STATE_STOPPING
20265                && state.mState != UserState.STATE_SHUTDOWN;
20266    }
20267
20268    @Override
20269    public int[] getRunningUserIds() {
20270        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20271                != PackageManager.PERMISSION_GRANTED) {
20272            String msg = "Permission Denial: isUserRunning() from pid="
20273                    + Binder.getCallingPid()
20274                    + ", uid=" + Binder.getCallingUid()
20275                    + " requires " + INTERACT_ACROSS_USERS;
20276            Slog.w(TAG, msg);
20277            throw new SecurityException(msg);
20278        }
20279        synchronized (this) {
20280            return mStartedUserArray;
20281        }
20282    }
20283
20284    private void updateStartedUserArrayLocked() {
20285        int num = 0;
20286        for (int i=0; i<mStartedUsers.size();  i++) {
20287            UserState uss = mStartedUsers.valueAt(i);
20288            // This list does not include stopping users.
20289            if (uss.mState != UserState.STATE_STOPPING
20290                    && uss.mState != UserState.STATE_SHUTDOWN) {
20291                num++;
20292            }
20293        }
20294        mStartedUserArray = new int[num];
20295        num = 0;
20296        for (int i=0; i<mStartedUsers.size();  i++) {
20297            UserState uss = mStartedUsers.valueAt(i);
20298            if (uss.mState != UserState.STATE_STOPPING
20299                    && uss.mState != UserState.STATE_SHUTDOWN) {
20300                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20301                num++;
20302            }
20303        }
20304    }
20305
20306    @Override
20307    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20308        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20309                != PackageManager.PERMISSION_GRANTED) {
20310            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20311                    + Binder.getCallingPid()
20312                    + ", uid=" + Binder.getCallingUid()
20313                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20314            Slog.w(TAG, msg);
20315            throw new SecurityException(msg);
20316        }
20317
20318        mUserSwitchObservers.register(observer);
20319    }
20320
20321    @Override
20322    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20323        mUserSwitchObservers.unregister(observer);
20324    }
20325
20326    int[] getUsersLocked() {
20327        UserManagerService ums = getUserManagerLocked();
20328        return ums != null ? ums.getUserIds() : new int[] { 0 };
20329    }
20330
20331    UserManagerService getUserManagerLocked() {
20332        if (mUserManager == null) {
20333            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20334            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20335        }
20336        return mUserManager;
20337    }
20338
20339    private int applyUserId(int uid, int userId) {
20340        return UserHandle.getUid(userId, uid);
20341    }
20342
20343    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20344        if (info == null) return null;
20345        ApplicationInfo newInfo = new ApplicationInfo(info);
20346        newInfo.uid = applyUserId(info.uid, userId);
20347        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20348                userId).getAbsolutePath();
20349        return newInfo;
20350    }
20351
20352    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20353        if (aInfo == null
20354                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20355            return aInfo;
20356        }
20357
20358        ActivityInfo info = new ActivityInfo(aInfo);
20359        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20360        return info;
20361    }
20362
20363    private final class LocalService extends ActivityManagerInternal {
20364        @Override
20365        public void onWakefulnessChanged(int wakefulness) {
20366            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20367        }
20368
20369        @Override
20370        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20371                String processName, String abiOverride, int uid, Runnable crashHandler) {
20372            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20373                    processName, abiOverride, uid, crashHandler);
20374        }
20375
20376        @Override
20377        public SleepToken acquireSleepToken(String tag) {
20378            Preconditions.checkNotNull(tag);
20379
20380            synchronized (ActivityManagerService.this) {
20381                SleepTokenImpl token = new SleepTokenImpl(tag);
20382                mSleepTokens.add(token);
20383                updateSleepIfNeededLocked();
20384                return token;
20385            }
20386        }
20387
20388        @Override
20389        public ComponentName getHomeActivityForUser(int userId) {
20390            synchronized (ActivityManagerService.this) {
20391                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20392                return homeActivity == null ? null : homeActivity.realActivity;
20393            }
20394        }
20395    }
20396
20397    private final class SleepTokenImpl extends SleepToken {
20398        private final String mTag;
20399        private final long mAcquireTime;
20400
20401        public SleepTokenImpl(String tag) {
20402            mTag = tag;
20403            mAcquireTime = SystemClock.uptimeMillis();
20404        }
20405
20406        @Override
20407        public void release() {
20408            synchronized (ActivityManagerService.this) {
20409                if (mSleepTokens.remove(this)) {
20410                    updateSleepIfNeededLocked();
20411                }
20412            }
20413        }
20414
20415        @Override
20416        public String toString() {
20417            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20418        }
20419    }
20420
20421    /**
20422     * An implementation of IAppTask, that allows an app to manage its own tasks via
20423     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20424     * only the process that calls getAppTasks() can call the AppTask methods.
20425     */
20426    class AppTaskImpl extends IAppTask.Stub {
20427        private int mTaskId;
20428        private int mCallingUid;
20429
20430        public AppTaskImpl(int taskId, int callingUid) {
20431            mTaskId = taskId;
20432            mCallingUid = callingUid;
20433        }
20434
20435        private void checkCaller() {
20436            if (mCallingUid != Binder.getCallingUid()) {
20437                throw new SecurityException("Caller " + mCallingUid
20438                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20439            }
20440        }
20441
20442        @Override
20443        public void finishAndRemoveTask() {
20444            checkCaller();
20445
20446            synchronized (ActivityManagerService.this) {
20447                long origId = Binder.clearCallingIdentity();
20448                try {
20449                    if (!removeTaskByIdLocked(mTaskId, false)) {
20450                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20451                    }
20452                } finally {
20453                    Binder.restoreCallingIdentity(origId);
20454                }
20455            }
20456        }
20457
20458        @Override
20459        public ActivityManager.RecentTaskInfo getTaskInfo() {
20460            checkCaller();
20461
20462            synchronized (ActivityManagerService.this) {
20463                long origId = Binder.clearCallingIdentity();
20464                try {
20465                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20466                    if (tr == null) {
20467                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20468                    }
20469                    return createRecentTaskInfoFromTaskRecord(tr);
20470                } finally {
20471                    Binder.restoreCallingIdentity(origId);
20472                }
20473            }
20474        }
20475
20476        @Override
20477        public void moveToFront() {
20478            checkCaller();
20479            // Will bring task to front if it already has a root activity.
20480            startActivityFromRecentsInner(mTaskId, null);
20481        }
20482
20483        @Override
20484        public int startActivity(IBinder whoThread, String callingPackage,
20485                Intent intent, String resolvedType, Bundle options) {
20486            checkCaller();
20487
20488            int callingUser = UserHandle.getCallingUserId();
20489            TaskRecord tr;
20490            IApplicationThread appThread;
20491            synchronized (ActivityManagerService.this) {
20492                tr = mRecentTasks.taskForIdLocked(mTaskId);
20493                if (tr == null) {
20494                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20495                }
20496                appThread = ApplicationThreadNative.asInterface(whoThread);
20497                if (appThread == null) {
20498                    throw new IllegalArgumentException("Bad app thread " + appThread);
20499                }
20500            }
20501            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20502                    resolvedType, null, null, null, null, 0, 0, null, null,
20503                    null, options, callingUser, null, tr);
20504        }
20505
20506        @Override
20507        public void setExcludeFromRecents(boolean exclude) {
20508            checkCaller();
20509
20510            synchronized (ActivityManagerService.this) {
20511                long origId = Binder.clearCallingIdentity();
20512                try {
20513                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20514                    if (tr == null) {
20515                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20516                    }
20517                    Intent intent = tr.getBaseIntent();
20518                    if (exclude) {
20519                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20520                    } else {
20521                        intent.setFlags(intent.getFlags()
20522                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20523                    }
20524                } finally {
20525                    Binder.restoreCallingIdentity(origId);
20526                }
20527            }
20528        }
20529    }
20530}
20531