ActivityManagerService.java revision ece0f4f5198e9e9cb60e96f036baf22c73411bec
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static com.android.server.am.ActivityManagerDebugConfig.*;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
36import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
37import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
38import static org.xmlpull.v1.XmlPullParser.START_TAG;
39
40import android.Manifest;
41import android.app.AppOpsManager;
42import android.app.ApplicationThreadNative;
43import android.app.IActivityContainer;
44import android.app.IActivityContainerCallback;
45import android.app.IAppTask;
46import android.app.ITaskStackListener;
47import android.app.ProfilerInfo;
48import android.app.assist.AssistContent;
49import android.app.assist.AssistStructure;
50import android.app.usage.UsageEvents;
51import android.app.usage.UsageStatsManagerInternal;
52import android.appwidget.AppWidgetManager;
53import android.content.pm.PermissionInfo;
54import android.content.res.Resources;
55import android.graphics.Bitmap;
56import android.graphics.Point;
57import android.graphics.Rect;
58import android.os.BatteryStats;
59import android.os.PersistableBundle;
60import android.os.PowerManager;
61import android.os.Trace;
62import android.os.TransactionTooLargeException;
63import android.os.WorkSource;
64import android.os.storage.IMountService;
65import android.os.storage.StorageManager;
66import android.service.voice.IVoiceInteractionSession;
67import android.util.ArrayMap;
68import android.util.ArraySet;
69import android.util.DebugUtils;
70import android.util.SparseIntArray;
71import android.view.Display;
72
73import com.android.internal.R;
74import com.android.internal.annotations.GuardedBy;
75import com.android.internal.app.DumpHeapActivity;
76import com.android.internal.app.IAppOpsService;
77import com.android.internal.app.IVoiceInteractor;
78import com.android.internal.app.ProcessMap;
79import com.android.internal.app.ProcessStats;
80import com.android.internal.os.BackgroundThread;
81import com.android.internal.os.BatteryStatsImpl;
82import com.android.internal.os.IResultReceiver;
83import com.android.internal.os.ProcessCpuTracker;
84import com.android.internal.os.TransferPipe;
85import com.android.internal.os.Zygote;
86import com.android.internal.util.ArrayUtils;
87import com.android.internal.util.FastPrintWriter;
88import com.android.internal.util.FastXmlSerializer;
89import com.android.internal.util.MemInfoReader;
90import com.android.internal.util.Preconditions;
91import com.android.server.AppOpsService;
92import com.android.server.AttributeCache;
93import com.android.server.IntentResolver;
94import com.android.server.LocalServices;
95import com.android.server.ServiceThread;
96import com.android.server.SystemService;
97import com.android.server.SystemServiceManager;
98import com.android.server.Watchdog;
99import com.android.server.am.ActivityStack.ActivityState;
100import com.android.server.firewall.IntentFirewall;
101import com.android.server.pm.Installer;
102import com.android.server.pm.UserManagerService;
103import com.android.server.statusbar.StatusBarManagerInternal;
104import com.android.server.wm.AppTransition;
105import com.android.server.wm.WindowManagerService;
106import com.google.android.collect.Lists;
107import com.google.android.collect.Maps;
108
109import libcore.io.IoUtils;
110import libcore.util.EmptyArray;
111
112import org.xmlpull.v1.XmlPullParser;
113import org.xmlpull.v1.XmlPullParserException;
114import org.xmlpull.v1.XmlSerializer;
115
116import android.app.Activity;
117import android.app.ActivityManager;
118import android.app.ActivityManager.RunningTaskInfo;
119import android.app.ActivityManager.StackInfo;
120import android.app.ActivityManagerInternal;
121import android.app.ActivityManagerInternal.SleepToken;
122import android.app.ActivityManagerNative;
123import android.app.ActivityOptions;
124import android.app.ActivityThread;
125import android.app.AlertDialog;
126import android.app.AppGlobals;
127import android.app.ApplicationErrorReport;
128import android.app.Dialog;
129import android.app.IActivityController;
130import android.app.IApplicationThread;
131import android.app.IInstrumentationWatcher;
132import android.app.INotificationManager;
133import android.app.IProcessObserver;
134import android.app.IServiceConnection;
135import android.app.IStopUserCallback;
136import android.app.IUidObserver;
137import android.app.IUiAutomationConnection;
138import android.app.IUserSwitchObserver;
139import android.app.Instrumentation;
140import android.app.Notification;
141import android.app.NotificationManager;
142import android.app.PendingIntent;
143import android.app.backup.IBackupManager;
144import android.content.ActivityNotFoundException;
145import android.content.BroadcastReceiver;
146import android.content.ClipData;
147import android.content.ComponentCallbacks2;
148import android.content.ComponentName;
149import android.content.ContentProvider;
150import android.content.ContentResolver;
151import android.content.Context;
152import android.content.DialogInterface;
153import android.content.IContentProvider;
154import android.content.IIntentReceiver;
155import android.content.IIntentSender;
156import android.content.Intent;
157import android.content.IntentFilter;
158import android.content.IntentSender;
159import android.content.pm.ActivityInfo;
160import android.content.pm.ApplicationInfo;
161import android.content.pm.ConfigurationInfo;
162import android.content.pm.IPackageDataObserver;
163import android.content.pm.IPackageManager;
164import android.content.pm.InstrumentationInfo;
165import android.content.pm.PackageInfo;
166import android.content.pm.PackageManager;
167import android.content.pm.ParceledListSlice;
168import android.content.pm.UserInfo;
169import android.content.pm.PackageManager.NameNotFoundException;
170import android.content.pm.PathPermission;
171import android.content.pm.ProviderInfo;
172import android.content.pm.ResolveInfo;
173import android.content.pm.ServiceInfo;
174import android.content.res.CompatibilityInfo;
175import android.content.res.Configuration;
176import android.net.Proxy;
177import android.net.ProxyInfo;
178import android.net.Uri;
179import android.os.Binder;
180import android.os.Build;
181import android.os.Bundle;
182import android.os.Debug;
183import android.os.DropBoxManager;
184import android.os.Environment;
185import android.os.FactoryTest;
186import android.os.FileObserver;
187import android.os.FileUtils;
188import android.os.Handler;
189import android.os.IBinder;
190import android.os.IPermissionController;
191import android.os.IProcessInfoService;
192import android.os.IRemoteCallback;
193import android.os.IUserManager;
194import android.os.Looper;
195import android.os.Message;
196import android.os.Parcel;
197import android.os.ParcelFileDescriptor;
198import android.os.PowerManagerInternal;
199import android.os.Process;
200import android.os.RemoteCallbackList;
201import android.os.RemoteException;
202import android.os.SELinux;
203import android.os.ServiceManager;
204import android.os.StrictMode;
205import android.os.SystemClock;
206import android.os.SystemProperties;
207import android.os.UpdateLock;
208import android.os.UserHandle;
209import android.os.UserManager;
210import android.provider.Settings;
211import android.text.format.DateUtils;
212import android.text.format.Time;
213import android.util.AtomicFile;
214import android.util.EventLog;
215import android.util.Log;
216import android.util.Pair;
217import android.util.PrintWriterPrinter;
218import android.util.Slog;
219import android.util.SparseArray;
220import android.util.TimeUtils;
221import android.util.Xml;
222import android.view.Gravity;
223import android.view.LayoutInflater;
224import android.view.View;
225import android.view.WindowManager;
226
227import dalvik.system.VMRuntime;
228
229import java.io.BufferedInputStream;
230import java.io.BufferedOutputStream;
231import java.io.DataInputStream;
232import java.io.DataOutputStream;
233import java.io.File;
234import java.io.FileDescriptor;
235import java.io.FileInputStream;
236import java.io.FileNotFoundException;
237import java.io.FileOutputStream;
238import java.io.IOException;
239import java.io.InputStreamReader;
240import java.io.PrintWriter;
241import java.io.StringWriter;
242import java.lang.ref.WeakReference;
243import java.nio.charset.StandardCharsets;
244import java.util.ArrayList;
245import java.util.Arrays;
246import java.util.Collections;
247import java.util.Comparator;
248import java.util.HashMap;
249import java.util.HashSet;
250import java.util.Iterator;
251import java.util.List;
252import java.util.Locale;
253import java.util.Map;
254import java.util.Set;
255import java.util.concurrent.atomic.AtomicBoolean;
256import java.util.concurrent.atomic.AtomicLong;
257
258public final class ActivityManagerService extends ActivityManagerNative
259        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
260
261    // File that stores last updated system version and called preboot receivers
262    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
263
264    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
265    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
266    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
267    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
268    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
269    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
270    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
271    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
272    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
273    private static final String TAG_LRU = TAG + POSTFIX_LRU;
274    private static final String TAG_MU = TAG + POSTFIX_MU;
275    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
276    private static final String TAG_POWER = TAG + POSTFIX_POWER;
277    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
278    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
279    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
280    private static final String TAG_PSS = TAG + POSTFIX_PSS;
281    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
282    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
283    private static final String TAG_STACK = TAG + POSTFIX_STACK;
284    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
285    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
286    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
287    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
288    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
289
290    /** Control over CPU and battery monitoring */
291    // write battery stats every 30 minutes.
292    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
293    static final boolean MONITOR_CPU_USAGE = true;
294    // don't sample cpu less than every 5 seconds.
295    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
296    // wait possibly forever for next cpu sample.
297    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
298    static final boolean MONITOR_THREAD_CPU_USAGE = false;
299
300    // The flags that are set for all calls we make to the package manager.
301    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
302
303    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
304
305    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
306
307    // Amount of time after a call to stopAppSwitches() during which we will
308    // prevent further untrusted switches from happening.
309    static final long APP_SWITCH_DELAY_TIME = 5*1000;
310
311    // How long we wait for a launched process to attach to the activity manager
312    // before we decide it's never going to come up for real.
313    static final int PROC_START_TIMEOUT = 10*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, when the process was
317    // started with a wrapper for instrumentation (such as Valgrind) because it
318    // could take much longer than usual.
319    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
320
321    // How long to wait after going idle before forcing apps to GC.
322    static final int GC_TIMEOUT = 5*1000;
323
324    // The minimum amount of time between successive GC requests for a process.
325    static final int GC_MIN_INTERVAL = 60*1000;
326
327    // The minimum amount of time between successive PSS requests for a process.
328    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
329
330    // The minimum amount of time between successive PSS requests for a process
331    // when the request is due to the memory state being lowered.
332    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
333
334    // The rate at which we check for apps using excessive power -- 15 mins.
335    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
336
337    // The minimum sample duration we will allow before deciding we have
338    // enough data on wake locks to start killing things.
339    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
340
341    // The minimum sample duration we will allow before deciding we have
342    // enough data on CPU usage to start killing things.
343    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
344
345    // How long we allow a receiver to run before giving up on it.
346    static final int BROADCAST_FG_TIMEOUT = 10*1000;
347    static final int BROADCAST_BG_TIMEOUT = 60*1000;
348
349    // How long we wait until we timeout on key dispatching.
350    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
351
352    // How long we wait until we timeout on key dispatching during instrumentation.
353    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
354
355    // Amount of time we wait for observers to handle a user switch before
356    // giving up on them and unfreezing the screen.
357    static final int USER_SWITCH_TIMEOUT = 2*1000;
358
359    // This is the amount of time an app needs to be running a foreground service before
360    // we will consider it to be doing interaction for usage stats.
361    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
362
363    // Maximum number of users we allow to be running at a time.
364    static final int MAX_RUNNING_USERS = 3;
365
366    // How long to wait in getAssistContextExtras for the activity and foreground services
367    // to respond with the result.
368    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
369
370    // How long top wait when going through the modern assist (which doesn't need to block
371    // on getting this result before starting to launch its UI).
372    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
373
374    // Maximum number of persisted Uri grants a package is allowed
375    static final int MAX_PERSISTED_URI_GRANTS = 128;
376
377    static final int MY_PID = Process.myPid();
378
379    static final String[] EMPTY_STRING_ARRAY = new String[0];
380
381    // How many bytes to write into the dropbox log before truncating
382    static final int DROPBOX_MAX_SIZE = 256 * 1024;
383
384    // Access modes for handleIncomingUser.
385    static final int ALLOW_NON_FULL = 0;
386    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
387    static final int ALLOW_FULL_ONLY = 2;
388
389    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
390
391    // Delay in notifying task stack change listeners (in millis)
392    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
393
394    // Necessary ApplicationInfo flags to mark an app as persistent
395    private static final int PERSISTENT_MASK =
396            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
397
398    /** All system services */
399    SystemServiceManager mSystemServiceManager;
400
401    private Installer mInstaller;
402
403    /** Run all ActivityStacks through this */
404    ActivityStackSupervisor mStackSupervisor;
405
406    /** Task stack change listeners. */
407    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
408            new RemoteCallbackList<ITaskStackListener>();
409
410    public IntentFirewall mIntentFirewall;
411
412    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
413    // default actuion automatically.  Important for devices without direct input
414    // devices.
415    private boolean mShowDialogs = true;
416
417    BroadcastQueue mFgBroadcastQueue;
418    BroadcastQueue mBgBroadcastQueue;
419    // Convenient for easy iteration over the queues. Foreground is first
420    // so that dispatch of foreground broadcasts gets precedence.
421    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
422
423    BroadcastQueue broadcastQueueForIntent(Intent intent) {
424        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
425        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
426                "Broadcast intent " + intent + " on "
427                + (isFg ? "foreground" : "background") + " queue");
428        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
429    }
430
431    /**
432     * Activity we have told the window manager to have key focus.
433     */
434    ActivityRecord mFocusedActivity = null;
435
436    /**
437     * User id of the last activity mFocusedActivity was set to.
438     */
439    private int mLastFocusedUserId;
440
441    /**
442     * If non-null, we are tracking the time the user spends in the currently focused app.
443     */
444    private AppTimeTracker mCurAppTimeTracker;
445
446    /**
447     * List of intents that were used to start the most recent tasks.
448     */
449    private final RecentTasks mRecentTasks;
450
451    /**
452     * For addAppTask: cached of the last activity component that was added.
453     */
454    ComponentName mLastAddedTaskComponent;
455
456    /**
457     * For addAppTask: cached of the last activity uid that was added.
458     */
459    int mLastAddedTaskUid;
460
461    /**
462     * For addAppTask: cached of the last ActivityInfo that was added.
463     */
464    ActivityInfo mLastAddedTaskActivity;
465
466    /**
467     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
468     */
469    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
470
471    /**
472     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
473     */
474    String mDeviceOwnerName;
475
476    public class PendingAssistExtras extends Binder implements Runnable {
477        public final ActivityRecord activity;
478        public final Bundle extras;
479        public final Intent intent;
480        public final String hint;
481        public final IResultReceiver receiver;
482        public final int userHandle;
483        public boolean haveResult = false;
484        public Bundle result = null;
485        public AssistStructure structure = null;
486        public AssistContent content = null;
487        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
488                String _hint, IResultReceiver _receiver, int _userHandle) {
489            activity = _activity;
490            extras = _extras;
491            intent = _intent;
492            hint = _hint;
493            receiver = _receiver;
494            userHandle = _userHandle;
495        }
496        @Override
497        public void run() {
498            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
499            synchronized (ActivityManagerService.this) {
500                synchronized (this) {
501                    haveResult = true;
502                    notifyAll();
503                }
504                pendingAssistExtrasTimedOutLocked(this);
505            }
506        }
507    }
508
509    final ArrayList<PendingAssistExtras> mPendingAssistExtras
510            = new ArrayList<PendingAssistExtras>();
511
512    /**
513     * Process management.
514     */
515    final ProcessList mProcessList = new ProcessList();
516
517    /**
518     * All of the applications we currently have running organized by name.
519     * The keys are strings of the application package name (as
520     * returned by the package manager), and the keys are ApplicationRecord
521     * objects.
522     */
523    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
524
525    /**
526     * Tracking long-term execution of processes to look for abuse and other
527     * bad app behavior.
528     */
529    final ProcessStatsService mProcessStats;
530
531    /**
532     * The currently running isolated processes.
533     */
534    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
535
536    /**
537     * Counter for assigning isolated process uids, to avoid frequently reusing the
538     * same ones.
539     */
540    int mNextIsolatedProcessUid = 0;
541
542    /**
543     * The currently running heavy-weight process, if any.
544     */
545    ProcessRecord mHeavyWeightProcess = null;
546
547    /**
548     * The last time that various processes have crashed.
549     */
550    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
551
552    /**
553     * Information about a process that is currently marked as bad.
554     */
555    static final class BadProcessInfo {
556        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
557            this.time = time;
558            this.shortMsg = shortMsg;
559            this.longMsg = longMsg;
560            this.stack = stack;
561        }
562
563        final long time;
564        final String shortMsg;
565        final String longMsg;
566        final String stack;
567    }
568
569    /**
570     * Set of applications that we consider to be bad, and will reject
571     * incoming broadcasts from (which the user has no control over).
572     * Processes are added to this set when they have crashed twice within
573     * a minimum amount of time; they are removed from it when they are
574     * later restarted (hopefully due to some user action).  The value is the
575     * time it was added to the list.
576     */
577    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
578
579    /**
580     * All of the processes we currently have running organized by pid.
581     * The keys are the pid running the application.
582     *
583     * <p>NOTE: This object is protected by its own lock, NOT the global
584     * activity manager lock!
585     */
586    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
587
588    /**
589     * All of the processes that have been forced to be foreground.  The key
590     * is the pid of the caller who requested it (we hold a death
591     * link on it).
592     */
593    abstract class ForegroundToken implements IBinder.DeathRecipient {
594        int pid;
595        IBinder token;
596    }
597    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
598
599    /**
600     * List of records for processes that someone had tried to start before the
601     * system was ready.  We don't start them at that point, but ensure they
602     * are started by the time booting is complete.
603     */
604    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
605
606    /**
607     * List of persistent applications that are in the process
608     * of being started.
609     */
610    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
611
612    /**
613     * Processes that are being forcibly torn down.
614     */
615    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
616
617    /**
618     * List of running applications, sorted by recent usage.
619     * The first entry in the list is the least recently used.
620     */
621    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
622
623    /**
624     * Where in mLruProcesses that the processes hosting activities start.
625     */
626    int mLruProcessActivityStart = 0;
627
628    /**
629     * Where in mLruProcesses that the processes hosting services start.
630     * This is after (lower index) than mLruProcessesActivityStart.
631     */
632    int mLruProcessServiceStart = 0;
633
634    /**
635     * List of processes that should gc as soon as things are idle.
636     */
637    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
638
639    /**
640     * Processes we want to collect PSS data from.
641     */
642    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
643
644    /**
645     * Last time we requested PSS data of all processes.
646     */
647    long mLastFullPssTime = SystemClock.uptimeMillis();
648
649    /**
650     * If set, the next time we collect PSS data we should do a full collection
651     * with data from native processes and the kernel.
652     */
653    boolean mFullPssPending = false;
654
655    /**
656     * This is the process holding what we currently consider to be
657     * the "home" activity.
658     */
659    ProcessRecord mHomeProcess;
660
661    /**
662     * This is the process holding the activity the user last visited that
663     * is in a different process from the one they are currently in.
664     */
665    ProcessRecord mPreviousProcess;
666
667    /**
668     * The time at which the previous process was last visible.
669     */
670    long mPreviousProcessVisibleTime;
671
672    /**
673     * Track all uids that have actively running processes.
674     */
675    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
676
677    /**
678     * Which uses have been started, so are allowed to run code.
679     */
680    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
681
682    /**
683     * LRU list of history of current users.  Most recently current is at the end.
684     */
685    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
686
687    /**
688     * Constant array of the users that are currently started.
689     */
690    int[] mStartedUserArray = new int[] { 0 };
691
692    /**
693     * Registered observers of the user switching mechanics.
694     */
695    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
696            = new RemoteCallbackList<IUserSwitchObserver>();
697
698    /**
699     * Currently active user switch.
700     */
701    Object mCurUserSwitchCallback;
702
703    /**
704     * Packages that the user has asked to have run in screen size
705     * compatibility mode instead of filling the screen.
706     */
707    final CompatModePackages mCompatModePackages;
708
709    /**
710     * Set of IntentSenderRecord objects that are currently active.
711     */
712    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
713            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
714
715    /**
716     * Fingerprints (hashCode()) of stack traces that we've
717     * already logged DropBox entries for.  Guarded by itself.  If
718     * something (rogue user app) forces this over
719     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
720     */
721    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
722    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
723
724    /**
725     * Strict Mode background batched logging state.
726     *
727     * The string buffer is guarded by itself, and its lock is also
728     * used to determine if another batched write is already
729     * in-flight.
730     */
731    private final StringBuilder mStrictModeBuffer = new StringBuilder();
732
733    /**
734     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
735     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
736     */
737    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
738
739    /**
740     * Resolver for broadcast intents to registered receivers.
741     * Holds BroadcastFilter (subclass of IntentFilter).
742     */
743    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
744            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
745        @Override
746        protected boolean allowFilterResult(
747                BroadcastFilter filter, List<BroadcastFilter> dest) {
748            IBinder target = filter.receiverList.receiver.asBinder();
749            for (int i = dest.size() - 1; i >= 0; i--) {
750                if (dest.get(i).receiverList.receiver.asBinder() == target) {
751                    return false;
752                }
753            }
754            return true;
755        }
756
757        @Override
758        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
759            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
760                    || userId == filter.owningUserId) {
761                return super.newResult(filter, match, userId);
762            }
763            return null;
764        }
765
766        @Override
767        protected BroadcastFilter[] newArray(int size) {
768            return new BroadcastFilter[size];
769        }
770
771        @Override
772        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
773            return packageName.equals(filter.packageName);
774        }
775    };
776
777    /**
778     * State of all active sticky broadcasts per user.  Keys are the action of the
779     * sticky Intent, values are an ArrayList of all broadcasted intents with
780     * that action (which should usually be one).  The SparseArray is keyed
781     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
782     * for stickies that are sent to all users.
783     */
784    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
785            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
786
787    final ActiveServices mServices;
788
789    final static class Association {
790        final int mSourceUid;
791        final String mSourceProcess;
792        final int mTargetUid;
793        final ComponentName mTargetComponent;
794        final String mTargetProcess;
795
796        int mCount;
797        long mTime;
798
799        int mNesting;
800        long mStartTime;
801
802        Association(int sourceUid, String sourceProcess, int targetUid,
803                ComponentName targetComponent, String targetProcess) {
804            mSourceUid = sourceUid;
805            mSourceProcess = sourceProcess;
806            mTargetUid = targetUid;
807            mTargetComponent = targetComponent;
808            mTargetProcess = targetProcess;
809        }
810    }
811
812    /**
813     * When service association tracking is enabled, this is all of the associations we
814     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
815     * -> association data.
816     */
817    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
818            mAssociations = new SparseArray<>();
819    boolean mTrackingAssociations;
820
821    /**
822     * Backup/restore process management
823     */
824    String mBackupAppName = null;
825    BackupRecord mBackupTarget = null;
826
827    final ProviderMap mProviderMap;
828
829    /**
830     * List of content providers who have clients waiting for them.  The
831     * application is currently being launched and the provider will be
832     * removed from this list once it is published.
833     */
834    final ArrayList<ContentProviderRecord> mLaunchingProviders
835            = new ArrayList<ContentProviderRecord>();
836
837    /**
838     * File storing persisted {@link #mGrantedUriPermissions}.
839     */
840    private final AtomicFile mGrantFile;
841
842    /** XML constants used in {@link #mGrantFile} */
843    private static final String TAG_URI_GRANTS = "uri-grants";
844    private static final String TAG_URI_GRANT = "uri-grant";
845    private static final String ATTR_USER_HANDLE = "userHandle";
846    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
847    private static final String ATTR_TARGET_USER_ID = "targetUserId";
848    private static final String ATTR_SOURCE_PKG = "sourcePkg";
849    private static final String ATTR_TARGET_PKG = "targetPkg";
850    private static final String ATTR_URI = "uri";
851    private static final String ATTR_MODE_FLAGS = "modeFlags";
852    private static final String ATTR_CREATED_TIME = "createdTime";
853    private static final String ATTR_PREFIX = "prefix";
854
855    /**
856     * Global set of specific {@link Uri} permissions that have been granted.
857     * This optimized lookup structure maps from {@link UriPermission#targetUid}
858     * to {@link UriPermission#uri} to {@link UriPermission}.
859     */
860    @GuardedBy("this")
861    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
862            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
863
864    public static class GrantUri {
865        public final int sourceUserId;
866        public final Uri uri;
867        public boolean prefix;
868
869        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
870            this.sourceUserId = sourceUserId;
871            this.uri = uri;
872            this.prefix = prefix;
873        }
874
875        @Override
876        public int hashCode() {
877            int hashCode = 1;
878            hashCode = 31 * hashCode + sourceUserId;
879            hashCode = 31 * hashCode + uri.hashCode();
880            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
881            return hashCode;
882        }
883
884        @Override
885        public boolean equals(Object o) {
886            if (o instanceof GrantUri) {
887                GrantUri other = (GrantUri) o;
888                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
889                        && prefix == other.prefix;
890            }
891            return false;
892        }
893
894        @Override
895        public String toString() {
896            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
897            if (prefix) result += " [prefix]";
898            return result;
899        }
900
901        public String toSafeString() {
902            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
903            if (prefix) result += " [prefix]";
904            return result;
905        }
906
907        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
908            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
909                    ContentProvider.getUriWithoutUserId(uri), false);
910        }
911    }
912
913    CoreSettingsObserver mCoreSettingsObserver;
914
915    /**
916     * Thread-local storage used to carry caller permissions over through
917     * indirect content-provider access.
918     */
919    private class Identity {
920        public final IBinder token;
921        public final int pid;
922        public final int uid;
923
924        Identity(IBinder _token, int _pid, int _uid) {
925            token = _token;
926            pid = _pid;
927            uid = _uid;
928        }
929    }
930
931    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
932
933    /**
934     * All information we have collected about the runtime performance of
935     * any user id that can impact battery performance.
936     */
937    final BatteryStatsService mBatteryStatsService;
938
939    /**
940     * Information about component usage
941     */
942    UsageStatsManagerInternal mUsageStatsService;
943
944    /**
945     * Information about and control over application operations
946     */
947    final AppOpsService mAppOpsService;
948
949    /**
950     * Save recent tasks information across reboots.
951     */
952    final TaskPersister mTaskPersister;
953
954    /**
955     * Current configuration information.  HistoryRecord objects are given
956     * a reference to this object to indicate which configuration they are
957     * currently running in, so this object must be kept immutable.
958     */
959    Configuration mConfiguration = new Configuration();
960
961    /**
962     * Current sequencing integer of the configuration, for skipping old
963     * configurations.
964     */
965    int mConfigurationSeq = 0;
966
967    /**
968     * Hardware-reported OpenGLES version.
969     */
970    final int GL_ES_VERSION;
971
972    /**
973     * List of initialization arguments to pass to all processes when binding applications to them.
974     * For example, references to the commonly used services.
975     */
976    HashMap<String, IBinder> mAppBindArgs;
977
978    /**
979     * Temporary to avoid allocations.  Protected by main lock.
980     */
981    final StringBuilder mStringBuilder = new StringBuilder(256);
982
983    /**
984     * Used to control how we initialize the service.
985     */
986    ComponentName mTopComponent;
987    String mTopAction = Intent.ACTION_MAIN;
988    String mTopData;
989    boolean mProcessesReady = false;
990    boolean mSystemReady = false;
991    boolean mBooting = false;
992    boolean mCallFinishBooting = false;
993    boolean mBootAnimationComplete = false;
994    boolean mWaitingUpdate = false;
995    boolean mDidUpdate = false;
996    boolean mOnBattery = false;
997    boolean mLaunchWarningShown = false;
998
999    Context mContext;
1000
1001    int mFactoryTest;
1002
1003    boolean mCheckedForSetup;
1004
1005    /**
1006     * The time at which we will allow normal application switches again,
1007     * after a call to {@link #stopAppSwitches()}.
1008     */
1009    long mAppSwitchesAllowedTime;
1010
1011    /**
1012     * This is set to true after the first switch after mAppSwitchesAllowedTime
1013     * is set; any switches after that will clear the time.
1014     */
1015    boolean mDidAppSwitch;
1016
1017    /**
1018     * Last time (in realtime) at which we checked for power usage.
1019     */
1020    long mLastPowerCheckRealtime;
1021
1022    /**
1023     * Last time (in uptime) at which we checked for power usage.
1024     */
1025    long mLastPowerCheckUptime;
1026
1027    /**
1028     * Set while we are wanting to sleep, to prevent any
1029     * activities from being started/resumed.
1030     */
1031    private boolean mSleeping = false;
1032
1033    /**
1034     * The process state used for processes that are running the top activities.
1035     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1036     */
1037    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1038
1039    /**
1040     * Set while we are running a voice interaction.  This overrides
1041     * sleeping while it is active.
1042     */
1043    private IVoiceInteractionSession mRunningVoice;
1044
1045    /**
1046     * For some direct access we need to power manager.
1047     */
1048    PowerManagerInternal mLocalPowerManager;
1049
1050    /**
1051     * We want to hold a wake lock while running a voice interaction session, since
1052     * this may happen with the screen off and we need to keep the CPU running to
1053     * be able to continue to interact with the user.
1054     */
1055    PowerManager.WakeLock mVoiceWakeLock;
1056
1057    /**
1058     * State of external calls telling us if the device is awake or asleep.
1059     */
1060    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1061
1062    /**
1063     * A list of tokens that cause the top activity to be put to sleep.
1064     * They are used by components that may hide and block interaction with underlying
1065     * activities.
1066     */
1067    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1068
1069    static final int LOCK_SCREEN_HIDDEN = 0;
1070    static final int LOCK_SCREEN_LEAVING = 1;
1071    static final int LOCK_SCREEN_SHOWN = 2;
1072    /**
1073     * State of external call telling us if the lock screen is shown.
1074     */
1075    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1076
1077    /**
1078     * Set if we are shutting down the system, similar to sleeping.
1079     */
1080    boolean mShuttingDown = false;
1081
1082    /**
1083     * Current sequence id for oom_adj computation traversal.
1084     */
1085    int mAdjSeq = 0;
1086
1087    /**
1088     * Current sequence id for process LRU updating.
1089     */
1090    int mLruSeq = 0;
1091
1092    /**
1093     * Keep track of the non-cached/empty process we last found, to help
1094     * determine how to distribute cached/empty processes next time.
1095     */
1096    int mNumNonCachedProcs = 0;
1097
1098    /**
1099     * Keep track of the number of cached hidden procs, to balance oom adj
1100     * distribution between those and empty procs.
1101     */
1102    int mNumCachedHiddenProcs = 0;
1103
1104    /**
1105     * Keep track of the number of service processes we last found, to
1106     * determine on the next iteration which should be B services.
1107     */
1108    int mNumServiceProcs = 0;
1109    int mNewNumAServiceProcs = 0;
1110    int mNewNumServiceProcs = 0;
1111
1112    /**
1113     * Allow the current computed overall memory level of the system to go down?
1114     * This is set to false when we are killing processes for reasons other than
1115     * memory management, so that the now smaller process list will not be taken as
1116     * an indication that memory is tighter.
1117     */
1118    boolean mAllowLowerMemLevel = false;
1119
1120    /**
1121     * The last computed memory level, for holding when we are in a state that
1122     * processes are going away for other reasons.
1123     */
1124    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1125
1126    /**
1127     * The last total number of process we have, to determine if changes actually look
1128     * like a shrinking number of process due to lower RAM.
1129     */
1130    int mLastNumProcesses;
1131
1132    /**
1133     * The uptime of the last time we performed idle maintenance.
1134     */
1135    long mLastIdleTime = SystemClock.uptimeMillis();
1136
1137    /**
1138     * Total time spent with RAM that has been added in the past since the last idle time.
1139     */
1140    long mLowRamTimeSinceLastIdle = 0;
1141
1142    /**
1143     * If RAM is currently low, when that horrible situation started.
1144     */
1145    long mLowRamStartTime = 0;
1146
1147    /**
1148     * For reporting to battery stats the current top application.
1149     */
1150    private String mCurResumedPackage = null;
1151    private int mCurResumedUid = -1;
1152
1153    /**
1154     * For reporting to battery stats the apps currently running foreground
1155     * service.  The ProcessMap is package/uid tuples; each of these contain
1156     * an array of the currently foreground processes.
1157     */
1158    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1159            = new ProcessMap<ArrayList<ProcessRecord>>();
1160
1161    /**
1162     * This is set if we had to do a delayed dexopt of an app before launching
1163     * it, to increase the ANR timeouts in that case.
1164     */
1165    boolean mDidDexOpt;
1166
1167    /**
1168     * Set if the systemServer made a call to enterSafeMode.
1169     */
1170    boolean mSafeMode;
1171
1172    /**
1173     * If true, we are running under a test environment so will sample PSS from processes
1174     * much more rapidly to try to collect better data when the tests are rapidly
1175     * running through apps.
1176     */
1177    boolean mTestPssMode = false;
1178
1179    String mDebugApp = null;
1180    boolean mWaitForDebugger = false;
1181    boolean mDebugTransient = false;
1182    String mOrigDebugApp = null;
1183    boolean mOrigWaitForDebugger = false;
1184    boolean mAlwaysFinishActivities = false;
1185    IActivityController mController = null;
1186    String mProfileApp = null;
1187    ProcessRecord mProfileProc = null;
1188    String mProfileFile;
1189    ParcelFileDescriptor mProfileFd;
1190    int mSamplingInterval = 0;
1191    boolean mAutoStopProfiler = false;
1192    int mProfileType = 0;
1193    String mOpenGlTraceApp = null;
1194    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1195    String mMemWatchDumpProcName;
1196    String mMemWatchDumpFile;
1197    int mMemWatchDumpPid;
1198    int mMemWatchDumpUid;
1199
1200    final long[] mTmpLong = new long[1];
1201
1202    static final class ProcessChangeItem {
1203        static final int CHANGE_ACTIVITIES = 1<<0;
1204        static final int CHANGE_PROCESS_STATE = 1<<1;
1205        int changes;
1206        int uid;
1207        int pid;
1208        int processState;
1209        boolean foregroundActivities;
1210    }
1211
1212    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1213    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1214
1215    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1216    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1217
1218    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1219    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1220
1221    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1222    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1223
1224    /**
1225     * Runtime CPU use collection thread.  This object's lock is used to
1226     * perform synchronization with the thread (notifying it to run).
1227     */
1228    final Thread mProcessCpuThread;
1229
1230    /**
1231     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1232     * Must acquire this object's lock when accessing it.
1233     * NOTE: this lock will be held while doing long operations (trawling
1234     * through all processes in /proc), so it should never be acquired by
1235     * any critical paths such as when holding the main activity manager lock.
1236     */
1237    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1238            MONITOR_THREAD_CPU_USAGE);
1239    final AtomicLong mLastCpuTime = new AtomicLong(0);
1240    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1241
1242    long mLastWriteTime = 0;
1243
1244    /**
1245     * Used to retain an update lock when the foreground activity is in
1246     * immersive mode.
1247     */
1248    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1249
1250    /**
1251     * Set to true after the system has finished booting.
1252     */
1253    boolean mBooted = false;
1254
1255    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1256    int mProcessLimitOverride = -1;
1257
1258    WindowManagerService mWindowManager;
1259
1260    final ActivityThread mSystemThread;
1261
1262    // Holds the current foreground user's id
1263    int mCurrentUserId = 0;
1264    // Holds the target user's id during a user switch
1265    int mTargetUserId = UserHandle.USER_NULL;
1266    // If there are multiple profiles for the current user, their ids are here
1267    // Currently only the primary user can have managed profiles
1268    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1269
1270    /**
1271     * Mapping from each known user ID to the profile group ID it is associated with.
1272     */
1273    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1274
1275    private UserManagerService mUserManager;
1276
1277    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1278        final ProcessRecord mApp;
1279        final int mPid;
1280        final IApplicationThread mAppThread;
1281
1282        AppDeathRecipient(ProcessRecord app, int pid,
1283                IApplicationThread thread) {
1284            if (DEBUG_ALL) Slog.v(
1285                TAG, "New death recipient " + this
1286                + " for thread " + thread.asBinder());
1287            mApp = app;
1288            mPid = pid;
1289            mAppThread = thread;
1290        }
1291
1292        @Override
1293        public void binderDied() {
1294            if (DEBUG_ALL) Slog.v(
1295                TAG, "Death received in " + this
1296                + " for thread " + mAppThread.asBinder());
1297            synchronized(ActivityManagerService.this) {
1298                appDiedLocked(mApp, mPid, mAppThread, true);
1299            }
1300        }
1301    }
1302
1303    static final int SHOW_ERROR_MSG = 1;
1304    static final int SHOW_NOT_RESPONDING_MSG = 2;
1305    static final int SHOW_FACTORY_ERROR_MSG = 3;
1306    static final int UPDATE_CONFIGURATION_MSG = 4;
1307    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1308    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1309    static final int SERVICE_TIMEOUT_MSG = 12;
1310    static final int UPDATE_TIME_ZONE = 13;
1311    static final int SHOW_UID_ERROR_MSG = 14;
1312    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1313    static final int PROC_START_TIMEOUT_MSG = 20;
1314    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1315    static final int KILL_APPLICATION_MSG = 22;
1316    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1317    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1318    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1319    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1320    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1321    static final int CLEAR_DNS_CACHE_MSG = 28;
1322    static final int UPDATE_HTTP_PROXY_MSG = 29;
1323    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1324    static final int DISPATCH_PROCESSES_CHANGED = 31;
1325    static final int DISPATCH_PROCESS_DIED = 32;
1326    static final int REPORT_MEM_USAGE_MSG = 33;
1327    static final int REPORT_USER_SWITCH_MSG = 34;
1328    static final int CONTINUE_USER_SWITCH_MSG = 35;
1329    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1330    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1331    static final int PERSIST_URI_GRANTS_MSG = 38;
1332    static final int REQUEST_ALL_PSS_MSG = 39;
1333    static final int START_PROFILES_MSG = 40;
1334    static final int UPDATE_TIME = 41;
1335    static final int SYSTEM_USER_START_MSG = 42;
1336    static final int SYSTEM_USER_CURRENT_MSG = 43;
1337    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1338    static final int FINISH_BOOTING_MSG = 45;
1339    static final int START_USER_SWITCH_MSG = 46;
1340    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1341    static final int DISMISS_DIALOG_MSG = 48;
1342    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1343    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1344    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1345    static final int DELETE_DUMPHEAP_MSG = 52;
1346    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1347    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1348    static final int REPORT_TIME_TRACKER_MSG = 55;
1349
1350    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1351    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1352    static final int FIRST_COMPAT_MODE_MSG = 300;
1353    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1354
1355    CompatModeDialog mCompatModeDialog;
1356    long mLastMemUsageReportTime = 0;
1357
1358    /**
1359     * Flag whether the current user is a "monkey", i.e. whether
1360     * the UI is driven by a UI automation tool.
1361     */
1362    private boolean mUserIsMonkey;
1363
1364    /** Flag whether the device has a Recents UI */
1365    boolean mHasRecents;
1366
1367    /** The dimensions of the thumbnails in the Recents UI. */
1368    int mThumbnailWidth;
1369    int mThumbnailHeight;
1370
1371    final ServiceThread mHandlerThread;
1372    final MainHandler mHandler;
1373    final UiHandler mUiHandler;
1374
1375    final class UiHandler extends Handler {
1376        public UiHandler() {
1377            super(com.android.server.UiThread.get().getLooper(), null, true);
1378        }
1379
1380        @Override
1381        public void handleMessage(Message msg) {
1382            switch (msg.what) {
1383            case SHOW_ERROR_MSG: {
1384                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1385                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1386                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1387                synchronized (ActivityManagerService.this) {
1388                    ProcessRecord proc = (ProcessRecord)data.get("app");
1389                    AppErrorResult res = (AppErrorResult) data.get("result");
1390                    if (proc != null && proc.crashDialog != null) {
1391                        Slog.e(TAG, "App already has crash dialog: " + proc);
1392                        if (res != null) {
1393                            res.set(0);
1394                        }
1395                        return;
1396                    }
1397                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1398                            >= Process.FIRST_APPLICATION_UID
1399                            && proc.pid != MY_PID);
1400                    for (int userId : mCurrentProfileIds) {
1401                        isBackground &= (proc.userId != userId);
1402                    }
1403                    if (isBackground && !showBackground) {
1404                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1405                        if (res != null) {
1406                            res.set(0);
1407                        }
1408                        return;
1409                    }
1410                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1411                        Dialog d = new AppErrorDialog(mContext,
1412                                ActivityManagerService.this, res, proc);
1413                        d.show();
1414                        proc.crashDialog = d;
1415                    } else {
1416                        // The device is asleep, so just pretend that the user
1417                        // saw a crash dialog and hit "force quit".
1418                        if (res != null) {
1419                            res.set(0);
1420                        }
1421                    }
1422                }
1423
1424                ensureBootCompleted();
1425            } break;
1426            case SHOW_NOT_RESPONDING_MSG: {
1427                synchronized (ActivityManagerService.this) {
1428                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1429                    ProcessRecord proc = (ProcessRecord)data.get("app");
1430                    if (proc != null && proc.anrDialog != null) {
1431                        Slog.e(TAG, "App already has anr dialog: " + proc);
1432                        return;
1433                    }
1434
1435                    Intent intent = new Intent("android.intent.action.ANR");
1436                    if (!mProcessesReady) {
1437                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1438                                | Intent.FLAG_RECEIVER_FOREGROUND);
1439                    }
1440                    broadcastIntentLocked(null, null, intent,
1441                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1442                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1443
1444                    if (mShowDialogs) {
1445                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1446                                mContext, proc, (ActivityRecord)data.get("activity"),
1447                                msg.arg1 != 0);
1448                        d.show();
1449                        proc.anrDialog = d;
1450                    } else {
1451                        // Just kill the app if there is no dialog to be shown.
1452                        killAppAtUsersRequest(proc, null);
1453                    }
1454                }
1455
1456                ensureBootCompleted();
1457            } break;
1458            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1459                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1460                synchronized (ActivityManagerService.this) {
1461                    ProcessRecord proc = (ProcessRecord) data.get("app");
1462                    if (proc == null) {
1463                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1464                        break;
1465                    }
1466                    if (proc.crashDialog != null) {
1467                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1468                        return;
1469                    }
1470                    AppErrorResult res = (AppErrorResult) data.get("result");
1471                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1472                        Dialog d = new StrictModeViolationDialog(mContext,
1473                                ActivityManagerService.this, res, proc);
1474                        d.show();
1475                        proc.crashDialog = d;
1476                    } else {
1477                        // The device is asleep, so just pretend that the user
1478                        // saw a crash dialog and hit "force quit".
1479                        res.set(0);
1480                    }
1481                }
1482                ensureBootCompleted();
1483            } break;
1484            case SHOW_FACTORY_ERROR_MSG: {
1485                Dialog d = new FactoryErrorDialog(
1486                    mContext, msg.getData().getCharSequence("msg"));
1487                d.show();
1488                ensureBootCompleted();
1489            } break;
1490            case WAIT_FOR_DEBUGGER_MSG: {
1491                synchronized (ActivityManagerService.this) {
1492                    ProcessRecord app = (ProcessRecord)msg.obj;
1493                    if (msg.arg1 != 0) {
1494                        if (!app.waitedForDebugger) {
1495                            Dialog d = new AppWaitingForDebuggerDialog(
1496                                    ActivityManagerService.this,
1497                                    mContext, app);
1498                            app.waitDialog = d;
1499                            app.waitedForDebugger = true;
1500                            d.show();
1501                        }
1502                    } else {
1503                        if (app.waitDialog != null) {
1504                            app.waitDialog.dismiss();
1505                            app.waitDialog = null;
1506                        }
1507                    }
1508                }
1509            } break;
1510            case SHOW_UID_ERROR_MSG: {
1511                if (mShowDialogs) {
1512                    AlertDialog d = new BaseErrorDialog(mContext);
1513                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1514                    d.setCancelable(false);
1515                    d.setTitle(mContext.getText(R.string.android_system_label));
1516                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1517                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1518                            obtainMessage(DISMISS_DIALOG_MSG, d));
1519                    d.show();
1520                }
1521            } break;
1522            case SHOW_FINGERPRINT_ERROR_MSG: {
1523                if (mShowDialogs) {
1524                    AlertDialog d = new BaseErrorDialog(mContext);
1525                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1526                    d.setCancelable(false);
1527                    d.setTitle(mContext.getText(R.string.android_system_label));
1528                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1529                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1530                            obtainMessage(DISMISS_DIALOG_MSG, d));
1531                    d.show();
1532                }
1533            } break;
1534            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1535                synchronized (ActivityManagerService.this) {
1536                    ActivityRecord ar = (ActivityRecord) msg.obj;
1537                    if (mCompatModeDialog != null) {
1538                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1539                                ar.info.applicationInfo.packageName)) {
1540                            return;
1541                        }
1542                        mCompatModeDialog.dismiss();
1543                        mCompatModeDialog = null;
1544                    }
1545                    if (ar != null && false) {
1546                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1547                                ar.packageName)) {
1548                            int mode = mCompatModePackages.computeCompatModeLocked(
1549                                    ar.info.applicationInfo);
1550                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1551                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1552                                mCompatModeDialog = new CompatModeDialog(
1553                                        ActivityManagerService.this, mContext,
1554                                        ar.info.applicationInfo);
1555                                mCompatModeDialog.show();
1556                            }
1557                        }
1558                    }
1559                }
1560                break;
1561            }
1562            case START_USER_SWITCH_MSG: {
1563                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1564                break;
1565            }
1566            case DISMISS_DIALOG_MSG: {
1567                final Dialog d = (Dialog) msg.obj;
1568                d.dismiss();
1569                break;
1570            }
1571            case DISPATCH_PROCESSES_CHANGED: {
1572                dispatchProcessesChanged();
1573                break;
1574            }
1575            case DISPATCH_PROCESS_DIED: {
1576                final int pid = msg.arg1;
1577                final int uid = msg.arg2;
1578                dispatchProcessDied(pid, uid);
1579                break;
1580            }
1581            case DISPATCH_UIDS_CHANGED_MSG: {
1582                dispatchUidsChanged();
1583            } break;
1584            }
1585        }
1586    }
1587
1588    final class MainHandler extends Handler {
1589        public MainHandler(Looper looper) {
1590            super(looper, null, true);
1591        }
1592
1593        @Override
1594        public void handleMessage(Message msg) {
1595            switch (msg.what) {
1596            case UPDATE_CONFIGURATION_MSG: {
1597                final ContentResolver resolver = mContext.getContentResolver();
1598                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1599            } break;
1600            case GC_BACKGROUND_PROCESSES_MSG: {
1601                synchronized (ActivityManagerService.this) {
1602                    performAppGcsIfAppropriateLocked();
1603                }
1604            } break;
1605            case SERVICE_TIMEOUT_MSG: {
1606                if (mDidDexOpt) {
1607                    mDidDexOpt = false;
1608                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1609                    nmsg.obj = msg.obj;
1610                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1611                    return;
1612                }
1613                mServices.serviceTimeout((ProcessRecord)msg.obj);
1614            } break;
1615            case UPDATE_TIME_ZONE: {
1616                synchronized (ActivityManagerService.this) {
1617                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1618                        ProcessRecord r = mLruProcesses.get(i);
1619                        if (r.thread != null) {
1620                            try {
1621                                r.thread.updateTimeZone();
1622                            } catch (RemoteException ex) {
1623                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1624                            }
1625                        }
1626                    }
1627                }
1628            } break;
1629            case CLEAR_DNS_CACHE_MSG: {
1630                synchronized (ActivityManagerService.this) {
1631                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1632                        ProcessRecord r = mLruProcesses.get(i);
1633                        if (r.thread != null) {
1634                            try {
1635                                r.thread.clearDnsCache();
1636                            } catch (RemoteException ex) {
1637                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1638                            }
1639                        }
1640                    }
1641                }
1642            } break;
1643            case UPDATE_HTTP_PROXY_MSG: {
1644                ProxyInfo proxy = (ProxyInfo)msg.obj;
1645                String host = "";
1646                String port = "";
1647                String exclList = "";
1648                Uri pacFileUrl = Uri.EMPTY;
1649                if (proxy != null) {
1650                    host = proxy.getHost();
1651                    port = Integer.toString(proxy.getPort());
1652                    exclList = proxy.getExclusionListAsString();
1653                    pacFileUrl = proxy.getPacFileUrl();
1654                }
1655                synchronized (ActivityManagerService.this) {
1656                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1657                        ProcessRecord r = mLruProcesses.get(i);
1658                        if (r.thread != null) {
1659                            try {
1660                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1661                            } catch (RemoteException ex) {
1662                                Slog.w(TAG, "Failed to update http proxy for: " +
1663                                        r.info.processName);
1664                            }
1665                        }
1666                    }
1667                }
1668            } break;
1669            case PROC_START_TIMEOUT_MSG: {
1670                if (mDidDexOpt) {
1671                    mDidDexOpt = false;
1672                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1673                    nmsg.obj = msg.obj;
1674                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1675                    return;
1676                }
1677                ProcessRecord app = (ProcessRecord)msg.obj;
1678                synchronized (ActivityManagerService.this) {
1679                    processStartTimedOutLocked(app);
1680                }
1681            } break;
1682            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1683                synchronized (ActivityManagerService.this) {
1684                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1685                }
1686            } break;
1687            case KILL_APPLICATION_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    int appid = msg.arg1;
1690                    boolean restart = (msg.arg2 == 1);
1691                    Bundle bundle = (Bundle)msg.obj;
1692                    String pkg = bundle.getString("pkg");
1693                    String reason = bundle.getString("reason");
1694                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1695                            false, UserHandle.USER_ALL, reason);
1696                }
1697            } break;
1698            case FINALIZE_PENDING_INTENT_MSG: {
1699                ((PendingIntentRecord)msg.obj).completeFinalize();
1700            } break;
1701            case POST_HEAVY_NOTIFICATION_MSG: {
1702                INotificationManager inm = NotificationManager.getService();
1703                if (inm == null) {
1704                    return;
1705                }
1706
1707                ActivityRecord root = (ActivityRecord)msg.obj;
1708                ProcessRecord process = root.app;
1709                if (process == null) {
1710                    return;
1711                }
1712
1713                try {
1714                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1715                    String text = mContext.getString(R.string.heavy_weight_notification,
1716                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1717                    Notification notification = new Notification();
1718                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1719                    notification.when = 0;
1720                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1721                    notification.tickerText = text;
1722                    notification.defaults = 0; // please be quiet
1723                    notification.sound = null;
1724                    notification.vibrate = null;
1725                    notification.color = mContext.getColor(
1726                            com.android.internal.R.color.system_notification_accent_color);
1727                    notification.setLatestEventInfo(context, text,
1728                            mContext.getText(R.string.heavy_weight_notification_detail),
1729                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1730                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1731                                    new UserHandle(root.userId)));
1732
1733                    try {
1734                        int[] outId = new int[1];
1735                        inm.enqueueNotificationWithTag("android", "android", null,
1736                                R.string.heavy_weight_notification,
1737                                notification, outId, root.userId);
1738                    } catch (RuntimeException e) {
1739                        Slog.w(ActivityManagerService.TAG,
1740                                "Error showing notification for heavy-weight app", e);
1741                    } catch (RemoteException e) {
1742                    }
1743                } catch (NameNotFoundException e) {
1744                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1745                }
1746            } break;
1747            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1748                INotificationManager inm = NotificationManager.getService();
1749                if (inm == null) {
1750                    return;
1751                }
1752                try {
1753                    inm.cancelNotificationWithTag("android", null,
1754                            R.string.heavy_weight_notification,  msg.arg1);
1755                } catch (RuntimeException e) {
1756                    Slog.w(ActivityManagerService.TAG,
1757                            "Error canceling notification for service", e);
1758                } catch (RemoteException e) {
1759                }
1760            } break;
1761            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1762                synchronized (ActivityManagerService.this) {
1763                    checkExcessivePowerUsageLocked(true);
1764                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1765                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1766                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1767                }
1768            } break;
1769            case REPORT_MEM_USAGE_MSG: {
1770                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1771                Thread thread = new Thread() {
1772                    @Override public void run() {
1773                        reportMemUsage(memInfos);
1774                    }
1775                };
1776                thread.start();
1777                break;
1778            }
1779            case REPORT_USER_SWITCH_MSG: {
1780                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1781                break;
1782            }
1783            case CONTINUE_USER_SWITCH_MSG: {
1784                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1785                break;
1786            }
1787            case USER_SWITCH_TIMEOUT_MSG: {
1788                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case IMMERSIVE_MODE_LOCK_MSG: {
1792                final boolean nextState = (msg.arg1 != 0);
1793                if (mUpdateLock.isHeld() != nextState) {
1794                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1795                            "Applying new update lock state '" + nextState
1796                            + "' for " + (ActivityRecord)msg.obj);
1797                    if (nextState) {
1798                        mUpdateLock.acquire();
1799                    } else {
1800                        mUpdateLock.release();
1801                    }
1802                }
1803                break;
1804            }
1805            case PERSIST_URI_GRANTS_MSG: {
1806                writeGrantedUriPermissions();
1807                break;
1808            }
1809            case REQUEST_ALL_PSS_MSG: {
1810                synchronized (ActivityManagerService.this) {
1811                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1812                }
1813                break;
1814            }
1815            case START_PROFILES_MSG: {
1816                synchronized (ActivityManagerService.this) {
1817                    startProfilesLocked();
1818                }
1819                break;
1820            }
1821            case UPDATE_TIME: {
1822                synchronized (ActivityManagerService.this) {
1823                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1824                        ProcessRecord r = mLruProcesses.get(i);
1825                        if (r.thread != null) {
1826                            try {
1827                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1828                            } catch (RemoteException ex) {
1829                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1830                            }
1831                        }
1832                    }
1833                }
1834                break;
1835            }
1836            case SYSTEM_USER_START_MSG: {
1837                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1838                        Integer.toString(msg.arg1), msg.arg1);
1839                mSystemServiceManager.startUser(msg.arg1);
1840                break;
1841            }
1842            case SYSTEM_USER_CURRENT_MSG: {
1843                mBatteryStatsService.noteEvent(
1844                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1845                        Integer.toString(msg.arg2), msg.arg2);
1846                mBatteryStatsService.noteEvent(
1847                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1848                        Integer.toString(msg.arg1), msg.arg1);
1849                mSystemServiceManager.switchUser(msg.arg1);
1850                break;
1851            }
1852            case ENTER_ANIMATION_COMPLETE_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1855                    if (r != null && r.app != null && r.app.thread != null) {
1856                        try {
1857                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1858                        } catch (RemoteException e) {
1859                        }
1860                    }
1861                }
1862                break;
1863            }
1864            case FINISH_BOOTING_MSG: {
1865                if (msg.arg1 != 0) {
1866                    finishBooting();
1867                }
1868                if (msg.arg2 != 0) {
1869                    enableScreenAfterBoot();
1870                }
1871                break;
1872            }
1873            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1874                try {
1875                    Locale l = (Locale) msg.obj;
1876                    IBinder service = ServiceManager.getService("mount");
1877                    IMountService mountService = IMountService.Stub.asInterface(service);
1878                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1879                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1880                } catch (RemoteException e) {
1881                    Log.e(TAG, "Error storing locale for decryption UI", e);
1882                }
1883                break;
1884            }
1885            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1886                synchronized (ActivityManagerService.this) {
1887                    int i = mTaskStackListeners.beginBroadcast();
1888                    while (i > 0) {
1889                        i--;
1890                        try {
1891                            // Make a one-way callback to the listener
1892                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1893                        } catch (RemoteException e){
1894                            // Handled by the RemoteCallbackList
1895                        }
1896                    }
1897                    mTaskStackListeners.finishBroadcast();
1898                }
1899                break;
1900            }
1901            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1902                final int uid = msg.arg1;
1903                final byte[] firstPacket = (byte[]) msg.obj;
1904
1905                synchronized (mPidsSelfLocked) {
1906                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1907                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1908                        if (p.uid == uid) {
1909                            try {
1910                                p.thread.notifyCleartextNetwork(firstPacket);
1911                            } catch (RemoteException ignored) {
1912                            }
1913                        }
1914                    }
1915                }
1916                break;
1917            }
1918            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1919                final String procName;
1920                final int uid;
1921                final long memLimit;
1922                final String reportPackage;
1923                synchronized (ActivityManagerService.this) {
1924                    procName = mMemWatchDumpProcName;
1925                    uid = mMemWatchDumpUid;
1926                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1927                    if (val == null) {
1928                        val = mMemWatchProcesses.get(procName, 0);
1929                    }
1930                    if (val != null) {
1931                        memLimit = val.first;
1932                        reportPackage = val.second;
1933                    } else {
1934                        memLimit = 0;
1935                        reportPackage = null;
1936                    }
1937                }
1938                if (procName == null) {
1939                    return;
1940                }
1941
1942                if (DEBUG_PSS) Slog.d(TAG_PSS,
1943                        "Showing dump heap notification from " + procName + "/" + uid);
1944
1945                INotificationManager inm = NotificationManager.getService();
1946                if (inm == null) {
1947                    return;
1948                }
1949
1950                String text = mContext.getString(R.string.dump_heap_notification, procName);
1951                Notification notification = new Notification();
1952                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1953                notification.when = 0;
1954                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1955                notification.tickerText = text;
1956                notification.defaults = 0; // please be quiet
1957                notification.sound = null;
1958                notification.vibrate = null;
1959                notification.color = mContext.getColor(
1960                        com.android.internal.R.color.system_notification_accent_color);
1961                Intent deleteIntent = new Intent();
1962                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1963                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1964                        deleteIntent, 0, UserHandle.OWNER);
1965                Intent intent = new Intent();
1966                intent.setClassName("android", DumpHeapActivity.class.getName());
1967                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1968                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1969                if (reportPackage != null) {
1970                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1971                }
1972                int userId = UserHandle.getUserId(uid);
1973                notification.setLatestEventInfo(mContext, text,
1974                        mContext.getText(R.string.dump_heap_notification_detail),
1975                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1976                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1977                                new UserHandle(userId)));
1978
1979                try {
1980                    int[] outId = new int[1];
1981                    inm.enqueueNotificationWithTag("android", "android", null,
1982                            R.string.dump_heap_notification,
1983                            notification, outId, userId);
1984                } catch (RuntimeException e) {
1985                    Slog.w(ActivityManagerService.TAG,
1986                            "Error showing notification for dump heap", e);
1987                } catch (RemoteException e) {
1988                }
1989            } break;
1990            case DELETE_DUMPHEAP_MSG: {
1991                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1992                        DumpHeapActivity.JAVA_URI,
1993                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1994                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1995                        UserHandle.myUserId());
1996                synchronized (ActivityManagerService.this) {
1997                    mMemWatchDumpFile = null;
1998                    mMemWatchDumpProcName = null;
1999                    mMemWatchDumpPid = -1;
2000                    mMemWatchDumpUid = -1;
2001                }
2002            } break;
2003            case FOREGROUND_PROFILE_CHANGED_MSG: {
2004                dispatchForegroundProfileChanged(msg.arg1);
2005            } break;
2006            case REPORT_TIME_TRACKER_MSG: {
2007                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2008                tracker.deliverResult(mContext);
2009            } break;
2010            }
2011        }
2012    };
2013
2014    static final int COLLECT_PSS_BG_MSG = 1;
2015
2016    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2017        @Override
2018        public void handleMessage(Message msg) {
2019            switch (msg.what) {
2020            case COLLECT_PSS_BG_MSG: {
2021                long start = SystemClock.uptimeMillis();
2022                MemInfoReader memInfo = null;
2023                synchronized (ActivityManagerService.this) {
2024                    if (mFullPssPending) {
2025                        mFullPssPending = false;
2026                        memInfo = new MemInfoReader();
2027                    }
2028                }
2029                if (memInfo != null) {
2030                    updateCpuStatsNow();
2031                    long nativeTotalPss = 0;
2032                    synchronized (mProcessCpuTracker) {
2033                        final int N = mProcessCpuTracker.countStats();
2034                        for (int j=0; j<N; j++) {
2035                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2036                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2037                                // This is definitely an application process; skip it.
2038                                continue;
2039                            }
2040                            synchronized (mPidsSelfLocked) {
2041                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2042                                    // This is one of our own processes; skip it.
2043                                    continue;
2044                                }
2045                            }
2046                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2047                        }
2048                    }
2049                    memInfo.readMemInfo();
2050                    synchronized (ActivityManagerService.this) {
2051                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2052                                + (SystemClock.uptimeMillis()-start) + "ms");
2053                        final long cachedKb = memInfo.getCachedSizeKb();
2054                        final long freeKb = memInfo.getFreeSizeKb();
2055                        final long zramKb = memInfo.getZramTotalSizeKb();
2056                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2057                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2058                                kernelKb*1024, nativeTotalPss*1024);
2059                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2060                                nativeTotalPss);
2061                    }
2062                }
2063
2064                int num = 0;
2065                long[] tmp = new long[1];
2066                do {
2067                    ProcessRecord proc;
2068                    int procState;
2069                    int pid;
2070                    long lastPssTime;
2071                    synchronized (ActivityManagerService.this) {
2072                        if (mPendingPssProcesses.size() <= 0) {
2073                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2074                                    "Collected PSS of " + num + " processes in "
2075                                    + (SystemClock.uptimeMillis() - start) + "ms");
2076                            mPendingPssProcesses.clear();
2077                            return;
2078                        }
2079                        proc = mPendingPssProcesses.remove(0);
2080                        procState = proc.pssProcState;
2081                        lastPssTime = proc.lastPssTime;
2082                        if (proc.thread != null && procState == proc.setProcState
2083                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2084                                        < SystemClock.uptimeMillis()) {
2085                            pid = proc.pid;
2086                        } else {
2087                            proc = null;
2088                            pid = 0;
2089                        }
2090                    }
2091                    if (proc != null) {
2092                        long pss = Debug.getPss(pid, tmp, null);
2093                        synchronized (ActivityManagerService.this) {
2094                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2095                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2096                                num++;
2097                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2098                                        SystemClock.uptimeMillis());
2099                            }
2100                        }
2101                    }
2102                } while (true);
2103            }
2104            }
2105        }
2106    };
2107
2108    public void setSystemProcess() {
2109        try {
2110            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2111            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2112            ServiceManager.addService("meminfo", new MemBinder(this));
2113            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2114            ServiceManager.addService("dbinfo", new DbBinder(this));
2115            if (MONITOR_CPU_USAGE) {
2116                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2117            }
2118            ServiceManager.addService("permission", new PermissionController(this));
2119            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2120
2121            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2122                    "android", STOCK_PM_FLAGS);
2123            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2124
2125            synchronized (this) {
2126                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2127                app.persistent = true;
2128                app.pid = MY_PID;
2129                app.maxAdj = ProcessList.SYSTEM_ADJ;
2130                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2131                synchronized (mPidsSelfLocked) {
2132                    mPidsSelfLocked.put(app.pid, app);
2133                }
2134                updateLruProcessLocked(app, false, null);
2135                updateOomAdjLocked();
2136            }
2137        } catch (PackageManager.NameNotFoundException e) {
2138            throw new RuntimeException(
2139                    "Unable to find android system package", e);
2140        }
2141    }
2142
2143    public void setWindowManager(WindowManagerService wm) {
2144        mWindowManager = wm;
2145        mStackSupervisor.setWindowManager(wm);
2146    }
2147
2148    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2149        mUsageStatsService = usageStatsManager;
2150    }
2151
2152    public void startObservingNativeCrashes() {
2153        final NativeCrashListener ncl = new NativeCrashListener(this);
2154        ncl.start();
2155    }
2156
2157    public IAppOpsService getAppOpsService() {
2158        return mAppOpsService;
2159    }
2160
2161    static class MemBinder extends Binder {
2162        ActivityManagerService mActivityManagerService;
2163        MemBinder(ActivityManagerService activityManagerService) {
2164            mActivityManagerService = activityManagerService;
2165        }
2166
2167        @Override
2168        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2169            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2170                    != PackageManager.PERMISSION_GRANTED) {
2171                pw.println("Permission Denial: can't dump meminfo from from pid="
2172                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2173                        + " without permission " + android.Manifest.permission.DUMP);
2174                return;
2175            }
2176
2177            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2178        }
2179    }
2180
2181    static class GraphicsBinder extends Binder {
2182        ActivityManagerService mActivityManagerService;
2183        GraphicsBinder(ActivityManagerService activityManagerService) {
2184            mActivityManagerService = activityManagerService;
2185        }
2186
2187        @Override
2188        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2189            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2190                    != PackageManager.PERMISSION_GRANTED) {
2191                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2192                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2193                        + " without permission " + android.Manifest.permission.DUMP);
2194                return;
2195            }
2196
2197            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2198        }
2199    }
2200
2201    static class DbBinder extends Binder {
2202        ActivityManagerService mActivityManagerService;
2203        DbBinder(ActivityManagerService activityManagerService) {
2204            mActivityManagerService = activityManagerService;
2205        }
2206
2207        @Override
2208        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2209            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2210                    != PackageManager.PERMISSION_GRANTED) {
2211                pw.println("Permission Denial: can't dump dbinfo from from pid="
2212                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2213                        + " without permission " + android.Manifest.permission.DUMP);
2214                return;
2215            }
2216
2217            mActivityManagerService.dumpDbInfo(fd, pw, args);
2218        }
2219    }
2220
2221    static class CpuBinder extends Binder {
2222        ActivityManagerService mActivityManagerService;
2223        CpuBinder(ActivityManagerService activityManagerService) {
2224            mActivityManagerService = activityManagerService;
2225        }
2226
2227        @Override
2228        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2229            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2230                    != PackageManager.PERMISSION_GRANTED) {
2231                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2232                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2233                        + " without permission " + android.Manifest.permission.DUMP);
2234                return;
2235            }
2236
2237            synchronized (mActivityManagerService.mProcessCpuTracker) {
2238                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2239                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2240                        SystemClock.uptimeMillis()));
2241            }
2242        }
2243    }
2244
2245    public static final class Lifecycle extends SystemService {
2246        private final ActivityManagerService mService;
2247
2248        public Lifecycle(Context context) {
2249            super(context);
2250            mService = new ActivityManagerService(context);
2251        }
2252
2253        @Override
2254        public void onStart() {
2255            mService.start();
2256        }
2257
2258        public ActivityManagerService getService() {
2259            return mService;
2260        }
2261    }
2262
2263    // Note: This method is invoked on the main thread but may need to attach various
2264    // handlers to other threads.  So take care to be explicit about the looper.
2265    public ActivityManagerService(Context systemContext) {
2266        mContext = systemContext;
2267        mFactoryTest = FactoryTest.getMode();
2268        mSystemThread = ActivityThread.currentActivityThread();
2269
2270        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2271
2272        mHandlerThread = new ServiceThread(TAG,
2273                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2274        mHandlerThread.start();
2275        mHandler = new MainHandler(mHandlerThread.getLooper());
2276        mUiHandler = new UiHandler();
2277
2278        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2279                "foreground", BROADCAST_FG_TIMEOUT, false);
2280        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2281                "background", BROADCAST_BG_TIMEOUT, true);
2282        mBroadcastQueues[0] = mFgBroadcastQueue;
2283        mBroadcastQueues[1] = mBgBroadcastQueue;
2284
2285        mServices = new ActiveServices(this);
2286        mProviderMap = new ProviderMap(this);
2287
2288        // TODO: Move creation of battery stats service outside of activity manager service.
2289        File dataDir = Environment.getDataDirectory();
2290        File systemDir = new File(dataDir, "system");
2291        systemDir.mkdirs();
2292        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2293        mBatteryStatsService.getActiveStatistics().readLocked();
2294        mBatteryStatsService.scheduleWriteToDisk();
2295        mOnBattery = DEBUG_POWER ? true
2296                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2297        mBatteryStatsService.getActiveStatistics().setCallback(this);
2298
2299        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2300
2301        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2302
2303        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2304
2305        // User 0 is the first and only user that runs at boot.
2306        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2307        mUserLru.add(UserHandle.USER_OWNER);
2308        updateStartedUserArrayLocked();
2309
2310        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2311            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2312
2313        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2314
2315        mConfiguration.setToDefaults();
2316        mConfiguration.setLocale(Locale.getDefault());
2317
2318        mConfigurationSeq = mConfiguration.seq = 1;
2319        mProcessCpuTracker.init();
2320
2321        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2322        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2323        mRecentTasks = new RecentTasks(this);
2324        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2325        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2326
2327        mProcessCpuThread = new Thread("CpuTracker") {
2328            @Override
2329            public void run() {
2330                while (true) {
2331                    try {
2332                        try {
2333                            synchronized(this) {
2334                                final long now = SystemClock.uptimeMillis();
2335                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2336                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2337                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2338                                //        + ", write delay=" + nextWriteDelay);
2339                                if (nextWriteDelay < nextCpuDelay) {
2340                                    nextCpuDelay = nextWriteDelay;
2341                                }
2342                                if (nextCpuDelay > 0) {
2343                                    mProcessCpuMutexFree.set(true);
2344                                    this.wait(nextCpuDelay);
2345                                }
2346                            }
2347                        } catch (InterruptedException e) {
2348                        }
2349                        updateCpuStatsNow();
2350                    } catch (Exception e) {
2351                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2352                    }
2353                }
2354            }
2355        };
2356
2357        Watchdog.getInstance().addMonitor(this);
2358        Watchdog.getInstance().addThread(mHandler);
2359    }
2360
2361    public void setSystemServiceManager(SystemServiceManager mgr) {
2362        mSystemServiceManager = mgr;
2363    }
2364
2365    public void setInstaller(Installer installer) {
2366        mInstaller = installer;
2367    }
2368
2369    private void start() {
2370        Process.removeAllProcessGroups();
2371        mProcessCpuThread.start();
2372
2373        mBatteryStatsService.publish(mContext);
2374        mAppOpsService.publish(mContext);
2375        Slog.d("AppOps", "AppOpsService published");
2376        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2377    }
2378
2379    public void initPowerManagement() {
2380        mStackSupervisor.initPowerManagement();
2381        mBatteryStatsService.initPowerManagement();
2382        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2383        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2384        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2385        mVoiceWakeLock.setReferenceCounted(false);
2386    }
2387
2388    @Override
2389    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2390            throws RemoteException {
2391        if (code == SYSPROPS_TRANSACTION) {
2392            // We need to tell all apps about the system property change.
2393            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2394            synchronized(this) {
2395                final int NP = mProcessNames.getMap().size();
2396                for (int ip=0; ip<NP; ip++) {
2397                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2398                    final int NA = apps.size();
2399                    for (int ia=0; ia<NA; ia++) {
2400                        ProcessRecord app = apps.valueAt(ia);
2401                        if (app.thread != null) {
2402                            procs.add(app.thread.asBinder());
2403                        }
2404                    }
2405                }
2406            }
2407
2408            int N = procs.size();
2409            for (int i=0; i<N; i++) {
2410                Parcel data2 = Parcel.obtain();
2411                try {
2412                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2413                } catch (RemoteException e) {
2414                }
2415                data2.recycle();
2416            }
2417        }
2418        try {
2419            return super.onTransact(code, data, reply, flags);
2420        } catch (RuntimeException e) {
2421            // The activity manager only throws security exceptions, so let's
2422            // log all others.
2423            if (!(e instanceof SecurityException)) {
2424                Slog.wtf(TAG, "Activity Manager Crash", e);
2425            }
2426            throw e;
2427        }
2428    }
2429
2430    void updateCpuStats() {
2431        final long now = SystemClock.uptimeMillis();
2432        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2433            return;
2434        }
2435        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2436            synchronized (mProcessCpuThread) {
2437                mProcessCpuThread.notify();
2438            }
2439        }
2440    }
2441
2442    void updateCpuStatsNow() {
2443        synchronized (mProcessCpuTracker) {
2444            mProcessCpuMutexFree.set(false);
2445            final long now = SystemClock.uptimeMillis();
2446            boolean haveNewCpuStats = false;
2447
2448            if (MONITOR_CPU_USAGE &&
2449                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2450                mLastCpuTime.set(now);
2451                mProcessCpuTracker.update();
2452                if (mProcessCpuTracker.hasGoodLastStats()) {
2453                    haveNewCpuStats = true;
2454                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2455                    //Slog.i(TAG, "Total CPU usage: "
2456                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2457
2458                    // Slog the cpu usage if the property is set.
2459                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2460                        int user = mProcessCpuTracker.getLastUserTime();
2461                        int system = mProcessCpuTracker.getLastSystemTime();
2462                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2463                        int irq = mProcessCpuTracker.getLastIrqTime();
2464                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2465                        int idle = mProcessCpuTracker.getLastIdleTime();
2466
2467                        int total = user + system + iowait + irq + softIrq + idle;
2468                        if (total == 0) total = 1;
2469
2470                        EventLog.writeEvent(EventLogTags.CPU,
2471                                ((user+system+iowait+irq+softIrq) * 100) / total,
2472                                (user * 100) / total,
2473                                (system * 100) / total,
2474                                (iowait * 100) / total,
2475                                (irq * 100) / total,
2476                                (softIrq * 100) / total);
2477                    }
2478                }
2479            }
2480
2481            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2482            synchronized(bstats) {
2483                synchronized(mPidsSelfLocked) {
2484                    if (haveNewCpuStats) {
2485                        final int perc = bstats.startAddingCpuLocked();
2486                        if (perc >= 0) {
2487                            int remainUTime = 0;
2488                            int remainSTime = 0;
2489                            int totalUTime = 0;
2490                            int totalSTime = 0;
2491                            final int N = mProcessCpuTracker.countStats();
2492                            for (int i=0; i<N; i++) {
2493                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2494                                if (!st.working) {
2495                                    continue;
2496                                }
2497                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2498                                int otherUTime = (st.rel_utime*perc)/100;
2499                                int otherSTime = (st.rel_stime*perc)/100;
2500                                remainUTime += otherUTime;
2501                                remainSTime += otherSTime;
2502                                totalUTime += st.rel_utime;
2503                                totalSTime += st.rel_stime;
2504                                if (pr != null) {
2505                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2506                                    if (ps == null || !ps.isActive()) {
2507                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2508                                                pr.info.uid, pr.processName);
2509                                    }
2510                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2511                                            st.rel_stime - otherSTime);
2512                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2513                                } else {
2514                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2515                                    if (ps == null || !ps.isActive()) {
2516                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2517                                                bstats.mapUid(st.uid), st.name);
2518                                    }
2519                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2520                                            st.rel_stime - otherSTime);
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(perc, remainUTime,
2530                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2531                                    iowaitTime, irqTime, softIrqTime, idleTime);
2532                        }
2533                    }
2534                }
2535
2536                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2537                    mLastWriteTime = now;
2538                    mBatteryStatsService.scheduleWriteToDisk();
2539                }
2540            }
2541        }
2542    }
2543
2544    @Override
2545    public void batteryNeedsCpuUpdate() {
2546        updateCpuStatsNow();
2547    }
2548
2549    @Override
2550    public void batteryPowerChanged(boolean onBattery) {
2551        // When plugging in, update the CPU stats first before changing
2552        // the plug state.
2553        updateCpuStatsNow();
2554        synchronized (this) {
2555            synchronized(mPidsSelfLocked) {
2556                mOnBattery = DEBUG_POWER ? true : onBattery;
2557            }
2558        }
2559    }
2560
2561    @Override
2562    public void batterySendBroadcast(Intent intent) {
2563        broadcastIntentLocked(null, null, intent, null,
2564                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
2565                Process.SYSTEM_UID, UserHandle.USER_ALL);
2566    }
2567
2568    /**
2569     * Initialize the application bind args. These are passed to each
2570     * process when the bindApplication() IPC is sent to the process. They're
2571     * lazily setup to make sure the services are running when they're asked for.
2572     */
2573    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2574        if (mAppBindArgs == null) {
2575            mAppBindArgs = new HashMap<>();
2576
2577            // Isolated processes won't get this optimization, so that we don't
2578            // violate the rules about which services they have access to.
2579            if (!isolated) {
2580                // Setup the application init args
2581                mAppBindArgs.put("package", ServiceManager.getService("package"));
2582                mAppBindArgs.put("window", ServiceManager.getService("window"));
2583                mAppBindArgs.put(Context.ALARM_SERVICE,
2584                        ServiceManager.getService(Context.ALARM_SERVICE));
2585            }
2586        }
2587        return mAppBindArgs;
2588    }
2589
2590    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2591        if (r != null && mFocusedActivity != r) {
2592            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2593            ActivityRecord last = mFocusedActivity;
2594            mFocusedActivity = r;
2595            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2596                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2597                if (mCurAppTimeTracker != r.appTimeTracker) {
2598                    // We are switching app tracking.  Complete the current one.
2599                    if (mCurAppTimeTracker != null) {
2600                        mCurAppTimeTracker.stop();
2601                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2602                                mCurAppTimeTracker).sendToTarget();
2603                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2604                        mCurAppTimeTracker = null;
2605                    }
2606                    if (r.appTimeTracker != null) {
2607                        mCurAppTimeTracker = r.appTimeTracker;
2608                        startTimeTrackingFocusedActivityLocked();
2609                    }
2610                } else {
2611                    startTimeTrackingFocusedActivityLocked();
2612                }
2613            } else {
2614                r.appTimeTracker = null;
2615            }
2616            if (r.task != null && r.task.voiceInteractor != null) {
2617                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2618            } else {
2619                finishRunningVoiceLocked();
2620                if (last != null && last.task.voiceSession != null) {
2621                    // We had been in a voice interaction session, but now focused has
2622                    // move to something different.  Just finish the session, we can't
2623                    // return to it and retain the proper state and synchronization with
2624                    // the voice interaction service.
2625                    finishVoiceTask(last.task.voiceSession);
2626                }
2627            }
2628            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2629                mWindowManager.setFocusedApp(r.appToken, true);
2630            }
2631            applyUpdateLockStateLocked(r);
2632            if (mFocusedActivity.userId != mLastFocusedUserId) {
2633                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2634                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2635                        mFocusedActivity.userId, 0));
2636                mLastFocusedUserId = mFocusedActivity.userId;
2637            }
2638        }
2639        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2640                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2641                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2642    }
2643
2644    final void clearFocusedActivity(ActivityRecord r) {
2645        if (mFocusedActivity == r) {
2646            ActivityStack stack = mStackSupervisor.getFocusedStack();
2647            if (stack != null) {
2648                ActivityRecord top = stack.topActivity();
2649                if (top != null && top.userId != mLastFocusedUserId) {
2650                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2651                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2652                                    top.userId, 0));
2653                    mLastFocusedUserId = top.userId;
2654                }
2655            }
2656            mFocusedActivity = null;
2657            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2658        }
2659    }
2660
2661    @Override
2662    public void setFocusedStack(int stackId) {
2663        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2664        synchronized (ActivityManagerService.this) {
2665            ActivityStack stack = mStackSupervisor.getStack(stackId);
2666            if (stack != null) {
2667                ActivityRecord r = stack.topRunningActivityLocked(null);
2668                if (r != null) {
2669                    setFocusedActivityLocked(r, "setFocusedStack");
2670                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2671                }
2672            }
2673        }
2674    }
2675
2676    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2677    @Override
2678    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2679        synchronized (ActivityManagerService.this) {
2680            if (listener != null) {
2681                mTaskStackListeners.register(listener);
2682            }
2683        }
2684    }
2685
2686    @Override
2687    public void notifyActivityDrawn(IBinder token) {
2688        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2689        synchronized (this) {
2690            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2691            if (r != null) {
2692                r.task.stack.notifyActivityDrawnLocked(r);
2693            }
2694        }
2695    }
2696
2697    final void applyUpdateLockStateLocked(ActivityRecord r) {
2698        // Modifications to the UpdateLock state are done on our handler, outside
2699        // the activity manager's locks.  The new state is determined based on the
2700        // state *now* of the relevant activity record.  The object is passed to
2701        // the handler solely for logging detail, not to be consulted/modified.
2702        final boolean nextState = r != null && r.immersive;
2703        mHandler.sendMessage(
2704                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2705    }
2706
2707    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2708        Message msg = Message.obtain();
2709        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2710        msg.obj = r.task.askedCompatMode ? null : r;
2711        mUiHandler.sendMessage(msg);
2712    }
2713
2714    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2715            String what, Object obj, ProcessRecord srcApp) {
2716        app.lastActivityTime = now;
2717
2718        if (app.activities.size() > 0) {
2719            // Don't want to touch dependent processes that are hosting activities.
2720            return index;
2721        }
2722
2723        int lrui = mLruProcesses.lastIndexOf(app);
2724        if (lrui < 0) {
2725            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2726                    + what + " " + obj + " from " + srcApp);
2727            return index;
2728        }
2729
2730        if (lrui >= index) {
2731            // Don't want to cause this to move dependent processes *back* in the
2732            // list as if they were less frequently used.
2733            return index;
2734        }
2735
2736        if (lrui >= mLruProcessActivityStart) {
2737            // Don't want to touch dependent processes that are hosting activities.
2738            return index;
2739        }
2740
2741        mLruProcesses.remove(lrui);
2742        if (index > 0) {
2743            index--;
2744        }
2745        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2746                + " in LRU list: " + app);
2747        mLruProcesses.add(index, app);
2748        return index;
2749    }
2750
2751    final void removeLruProcessLocked(ProcessRecord app) {
2752        int lrui = mLruProcesses.lastIndexOf(app);
2753        if (lrui >= 0) {
2754            if (!app.killed) {
2755                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2756                Process.killProcessQuiet(app.pid);
2757                Process.killProcessGroup(app.info.uid, app.pid);
2758            }
2759            if (lrui <= mLruProcessActivityStart) {
2760                mLruProcessActivityStart--;
2761            }
2762            if (lrui <= mLruProcessServiceStart) {
2763                mLruProcessServiceStart--;
2764            }
2765            mLruProcesses.remove(lrui);
2766        }
2767    }
2768
2769    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2770            ProcessRecord client) {
2771        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2772                || app.treatLikeActivity;
2773        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2774        if (!activityChange && hasActivity) {
2775            // The process has activities, so we are only allowing activity-based adjustments
2776            // to move it.  It should be kept in the front of the list with other
2777            // processes that have activities, and we don't want those to change their
2778            // order except due to activity operations.
2779            return;
2780        }
2781
2782        mLruSeq++;
2783        final long now = SystemClock.uptimeMillis();
2784        app.lastActivityTime = now;
2785
2786        // First a quick reject: if the app is already at the position we will
2787        // put it, then there is nothing to do.
2788        if (hasActivity) {
2789            final int N = mLruProcesses.size();
2790            if (N > 0 && mLruProcesses.get(N-1) == app) {
2791                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2792                return;
2793            }
2794        } else {
2795            if (mLruProcessServiceStart > 0
2796                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2797                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2798                return;
2799            }
2800        }
2801
2802        int lrui = mLruProcesses.lastIndexOf(app);
2803
2804        if (app.persistent && lrui >= 0) {
2805            // We don't care about the position of persistent processes, as long as
2806            // they are in the list.
2807            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2808            return;
2809        }
2810
2811        /* In progress: compute new position first, so we can avoid doing work
2812           if the process is not actually going to move.  Not yet working.
2813        int addIndex;
2814        int nextIndex;
2815        boolean inActivity = false, inService = false;
2816        if (hasActivity) {
2817            // Process has activities, put it at the very tipsy-top.
2818            addIndex = mLruProcesses.size();
2819            nextIndex = mLruProcessServiceStart;
2820            inActivity = true;
2821        } else if (hasService) {
2822            // Process has services, put it at the top of the service list.
2823            addIndex = mLruProcessActivityStart;
2824            nextIndex = mLruProcessServiceStart;
2825            inActivity = true;
2826            inService = true;
2827        } else  {
2828            // Process not otherwise of interest, it goes to the top of the non-service area.
2829            addIndex = mLruProcessServiceStart;
2830            if (client != null) {
2831                int clientIndex = mLruProcesses.lastIndexOf(client);
2832                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2833                        + app);
2834                if (clientIndex >= 0 && addIndex > clientIndex) {
2835                    addIndex = clientIndex;
2836                }
2837            }
2838            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2839        }
2840
2841        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2842                + mLruProcessActivityStart + "): " + app);
2843        */
2844
2845        if (lrui >= 0) {
2846            if (lrui < mLruProcessActivityStart) {
2847                mLruProcessActivityStart--;
2848            }
2849            if (lrui < mLruProcessServiceStart) {
2850                mLruProcessServiceStart--;
2851            }
2852            /*
2853            if (addIndex > lrui) {
2854                addIndex--;
2855            }
2856            if (nextIndex > lrui) {
2857                nextIndex--;
2858            }
2859            */
2860            mLruProcesses.remove(lrui);
2861        }
2862
2863        /*
2864        mLruProcesses.add(addIndex, app);
2865        if (inActivity) {
2866            mLruProcessActivityStart++;
2867        }
2868        if (inService) {
2869            mLruProcessActivityStart++;
2870        }
2871        */
2872
2873        int nextIndex;
2874        if (hasActivity) {
2875            final int N = mLruProcesses.size();
2876            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2877                // Process doesn't have activities, but has clients with
2878                // activities...  move it up, but one below the top (the top
2879                // should always have a real activity).
2880                if (DEBUG_LRU) Slog.d(TAG_LRU,
2881                        "Adding to second-top of LRU activity list: " + app);
2882                mLruProcesses.add(N - 1, app);
2883                // To keep it from spamming the LRU list (by making a bunch of clients),
2884                // we will push down any other entries owned by the app.
2885                final int uid = app.info.uid;
2886                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2887                    ProcessRecord subProc = mLruProcesses.get(i);
2888                    if (subProc.info.uid == uid) {
2889                        // We want to push this one down the list.  If the process after
2890                        // it is for the same uid, however, don't do so, because we don't
2891                        // want them internally to be re-ordered.
2892                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2893                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2894                                    "Pushing uid " + uid + " swapping at " + i + ": "
2895                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2896                            ProcessRecord tmp = mLruProcesses.get(i);
2897                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2898                            mLruProcesses.set(i - 1, tmp);
2899                            i--;
2900                        }
2901                    } else {
2902                        // A gap, we can stop here.
2903                        break;
2904                    }
2905                }
2906            } else {
2907                // Process has activities, put it at the very tipsy-top.
2908                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2909                mLruProcesses.add(app);
2910            }
2911            nextIndex = mLruProcessServiceStart;
2912        } else if (hasService) {
2913            // Process has services, put it at the top of the service list.
2914            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2915            mLruProcesses.add(mLruProcessActivityStart, app);
2916            nextIndex = mLruProcessServiceStart;
2917            mLruProcessActivityStart++;
2918        } else  {
2919            // Process not otherwise of interest, it goes to the top of the non-service area.
2920            int index = mLruProcessServiceStart;
2921            if (client != null) {
2922                // If there is a client, don't allow the process to be moved up higher
2923                // in the list than that client.
2924                int clientIndex = mLruProcesses.lastIndexOf(client);
2925                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2926                        + " when updating " + app);
2927                if (clientIndex <= lrui) {
2928                    // Don't allow the client index restriction to push it down farther in the
2929                    // list than it already is.
2930                    clientIndex = lrui;
2931                }
2932                if (clientIndex >= 0 && index > clientIndex) {
2933                    index = clientIndex;
2934                }
2935            }
2936            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2937            mLruProcesses.add(index, app);
2938            nextIndex = index-1;
2939            mLruProcessActivityStart++;
2940            mLruProcessServiceStart++;
2941        }
2942
2943        // If the app is currently using a content provider or service,
2944        // bump those processes as well.
2945        for (int j=app.connections.size()-1; j>=0; j--) {
2946            ConnectionRecord cr = app.connections.valueAt(j);
2947            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2948                    && cr.binding.service.app != null
2949                    && cr.binding.service.app.lruSeq != mLruSeq
2950                    && !cr.binding.service.app.persistent) {
2951                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2952                        "service connection", cr, app);
2953            }
2954        }
2955        for (int j=app.conProviders.size()-1; j>=0; j--) {
2956            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2957            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2958                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2959                        "provider reference", cpr, app);
2960            }
2961        }
2962    }
2963
2964    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2965        if (uid == Process.SYSTEM_UID) {
2966            // The system gets to run in any process.  If there are multiple
2967            // processes with the same uid, just pick the first (this
2968            // should never happen).
2969            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2970            if (procs == null) return null;
2971            final int procCount = procs.size();
2972            for (int i = 0; i < procCount; i++) {
2973                final int procUid = procs.keyAt(i);
2974                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2975                    // Don't use an app process or different user process for system component.
2976                    continue;
2977                }
2978                return procs.valueAt(i);
2979            }
2980        }
2981        ProcessRecord proc = mProcessNames.get(processName, uid);
2982        if (false && proc != null && !keepIfLarge
2983                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2984                && proc.lastCachedPss >= 4000) {
2985            // Turn this condition on to cause killing to happen regularly, for testing.
2986            if (proc.baseProcessTracker != null) {
2987                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2988            }
2989            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2990        } else if (proc != null && !keepIfLarge
2991                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2992                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2993            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2994            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2995                if (proc.baseProcessTracker != null) {
2996                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2997                }
2998                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2999            }
3000        }
3001        return proc;
3002    }
3003
3004    void ensurePackageDexOpt(String packageName) {
3005        IPackageManager pm = AppGlobals.getPackageManager();
3006        try {
3007            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3008                mDidDexOpt = true;
3009            }
3010        } catch (RemoteException e) {
3011        }
3012    }
3013
3014    boolean isNextTransitionForward() {
3015        int transit = mWindowManager.getPendingAppTransition();
3016        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3017                || transit == AppTransition.TRANSIT_TASK_OPEN
3018                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3019    }
3020
3021    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3022            String processName, String abiOverride, int uid, Runnable crashHandler) {
3023        synchronized(this) {
3024            ApplicationInfo info = new ApplicationInfo();
3025            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3026            // For isolated processes, the former contains the parent's uid and the latter the
3027            // actual uid of the isolated process.
3028            // In the special case introduced by this method (which is, starting an isolated
3029            // process directly from the SystemServer without an actual parent app process) the
3030            // closest thing to a parent's uid is SYSTEM_UID.
3031            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3032            // the |isolated| logic in the ProcessRecord constructor.
3033            info.uid = Process.SYSTEM_UID;
3034            info.processName = processName;
3035            info.className = entryPoint;
3036            info.packageName = "android";
3037            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3038                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3039                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3040                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3041                    crashHandler);
3042            return proc != null ? proc.pid : 0;
3043        }
3044    }
3045
3046    final ProcessRecord startProcessLocked(String processName,
3047            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3048            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3049            boolean isolated, boolean keepIfLarge) {
3050        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3051                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3052                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3053                null /* crashHandler */);
3054    }
3055
3056    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3057            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3058            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3059            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3060        long startTime = SystemClock.elapsedRealtime();
3061        ProcessRecord app;
3062        if (!isolated) {
3063            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3064            checkTime(startTime, "startProcess: after getProcessRecord");
3065
3066            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3067                // If we are in the background, then check to see if this process
3068                // is bad.  If so, we will just silently fail.
3069                if (mBadProcesses.get(info.processName, info.uid) != null) {
3070                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3071                            + "/" + info.processName);
3072                    return null;
3073                }
3074            } else {
3075                // When the user is explicitly starting a process, then clear its
3076                // crash count so that we won't make it bad until they see at
3077                // least one crash dialog again, and make the process good again
3078                // if it had been bad.
3079                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3080                        + "/" + info.processName);
3081                mProcessCrashTimes.remove(info.processName, info.uid);
3082                if (mBadProcesses.get(info.processName, info.uid) != null) {
3083                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3084                            UserHandle.getUserId(info.uid), info.uid,
3085                            info.processName);
3086                    mBadProcesses.remove(info.processName, info.uid);
3087                    if (app != null) {
3088                        app.bad = false;
3089                    }
3090                }
3091            }
3092        } else {
3093            // If this is an isolated process, it can't re-use an existing process.
3094            app = null;
3095        }
3096
3097        // We don't have to do anything more if:
3098        // (1) There is an existing application record; and
3099        // (2) The caller doesn't think it is dead, OR there is no thread
3100        //     object attached to it so we know it couldn't have crashed; and
3101        // (3) There is a pid assigned to it, so it is either starting or
3102        //     already running.
3103        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3104                + " app=" + app + " knownToBeDead=" + knownToBeDead
3105                + " thread=" + (app != null ? app.thread : null)
3106                + " pid=" + (app != null ? app.pid : -1));
3107        if (app != null && app.pid > 0) {
3108            if (!knownToBeDead || app.thread == null) {
3109                // We already have the app running, or are waiting for it to
3110                // come up (we have a pid but not yet its thread), so keep it.
3111                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3112                // If this is a new package in the process, add the package to the list
3113                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3114                checkTime(startTime, "startProcess: done, added package to proc");
3115                return app;
3116            }
3117
3118            // An application record is attached to a previous process,
3119            // clean it up now.
3120            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3121            checkTime(startTime, "startProcess: bad proc running, killing");
3122            Process.killProcessGroup(app.info.uid, app.pid);
3123            handleAppDiedLocked(app, true, true);
3124            checkTime(startTime, "startProcess: done killing old proc");
3125        }
3126
3127        String hostingNameStr = hostingName != null
3128                ? hostingName.flattenToShortString() : null;
3129
3130        if (app == null) {
3131            checkTime(startTime, "startProcess: creating new process record");
3132            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3133            if (app == null) {
3134                Slog.w(TAG, "Failed making new process record for "
3135                        + processName + "/" + info.uid + " isolated=" + isolated);
3136                return null;
3137            }
3138            app.crashHandler = crashHandler;
3139            checkTime(startTime, "startProcess: done creating new process record");
3140        } else {
3141            // If this is a new package in the process, add the package to the list
3142            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3143            checkTime(startTime, "startProcess: added package to existing proc");
3144        }
3145
3146        // If the system is not ready yet, then hold off on starting this
3147        // process until it is.
3148        if (!mProcessesReady
3149                && !isAllowedWhileBooting(info)
3150                && !allowWhileBooting) {
3151            if (!mProcessesOnHold.contains(app)) {
3152                mProcessesOnHold.add(app);
3153            }
3154            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3155                    "System not ready, putting on hold: " + app);
3156            checkTime(startTime, "startProcess: returning with proc on hold");
3157            return app;
3158        }
3159
3160        checkTime(startTime, "startProcess: stepping in to startProcess");
3161        startProcessLocked(
3162                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3163        checkTime(startTime, "startProcess: done starting proc!");
3164        return (app.pid != 0) ? app : null;
3165    }
3166
3167    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3168        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3169    }
3170
3171    private final void startProcessLocked(ProcessRecord app,
3172            String hostingType, String hostingNameStr) {
3173        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3174                null /* entryPoint */, null /* entryPointArgs */);
3175    }
3176
3177    private final void startProcessLocked(ProcessRecord app, String hostingType,
3178            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3179        long startTime = SystemClock.elapsedRealtime();
3180        if (app.pid > 0 && app.pid != MY_PID) {
3181            checkTime(startTime, "startProcess: removing from pids map");
3182            synchronized (mPidsSelfLocked) {
3183                mPidsSelfLocked.remove(app.pid);
3184                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3185            }
3186            checkTime(startTime, "startProcess: done removing from pids map");
3187            app.setPid(0);
3188        }
3189
3190        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3191                "startProcessLocked removing on hold: " + app);
3192        mProcessesOnHold.remove(app);
3193
3194        checkTime(startTime, "startProcess: starting to update cpu stats");
3195        updateCpuStats();
3196        checkTime(startTime, "startProcess: done updating cpu stats");
3197
3198        try {
3199            try {
3200                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3201                    // This is caught below as if we had failed to fork zygote
3202                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3203                }
3204            } catch (RemoteException e) {
3205                throw e.rethrowAsRuntimeException();
3206            }
3207
3208            int uid = app.uid;
3209            int[] gids = null;
3210            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3211            if (!app.isolated) {
3212                int[] permGids = null;
3213                try {
3214                    checkTime(startTime, "startProcess: getting gids from package manager");
3215                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3216                            app.userId);
3217                } catch (RemoteException e) {
3218                    throw e.rethrowAsRuntimeException();
3219                }
3220
3221                /*
3222                 * Add shared application and profile GIDs so applications can share some
3223                 * resources like shared libraries and access user-wide resources
3224                 */
3225                if (ArrayUtils.isEmpty(permGids)) {
3226                    gids = new int[2];
3227                } else {
3228                    gids = new int[permGids.length + 2];
3229                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3230                }
3231                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3232                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3233            }
3234            checkTime(startTime, "startProcess: building args");
3235            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3236                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3237                        && mTopComponent != null
3238                        && app.processName.equals(mTopComponent.getPackageName())) {
3239                    uid = 0;
3240                }
3241                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3242                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3243                    uid = 0;
3244                }
3245            }
3246            int debugFlags = 0;
3247            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3248                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3249                // Also turn on CheckJNI for debuggable apps. It's quite
3250                // awkward to turn on otherwise.
3251                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3252            }
3253            // Run the app in safe mode if its manifest requests so or the
3254            // system is booted in safe mode.
3255            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3256                mSafeMode == true) {
3257                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3258            }
3259            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3260                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3261            }
3262            String jitDebugProperty = SystemProperties.get("debug.usejit");
3263            if ("true".equals(jitDebugProperty)) {
3264                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3265            } else if (!"false".equals(jitDebugProperty)) {
3266                // If we didn't force disable by setting false, defer to the dalvik vm options.
3267                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3268                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3269                }
3270            }
3271            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
3272            if ("true".equals(genCFIDebugProperty)) {
3273                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
3274            }
3275            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3276                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3277            }
3278            if ("1".equals(SystemProperties.get("debug.assert"))) {
3279                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3280            }
3281
3282            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3283            if (requiredAbi == null) {
3284                requiredAbi = Build.SUPPORTED_ABIS[0];
3285            }
3286
3287            String instructionSet = null;
3288            if (app.info.primaryCpuAbi != null) {
3289                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3290            }
3291
3292            app.gids = gids;
3293            app.requiredAbi = requiredAbi;
3294            app.instructionSet = instructionSet;
3295
3296            // Start the process.  It will either succeed and return a result containing
3297            // the PID of the new process, or else throw a RuntimeException.
3298            boolean isActivityProcess = (entryPoint == null);
3299            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3300            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3301                    app.processName);
3302            checkTime(startTime, "startProcess: asking zygote to start proc");
3303            Process.ProcessStartResult startResult = Process.start(entryPoint,
3304                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3305                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3306                    app.info.dataDir, entryPointArgs);
3307            checkTime(startTime, "startProcess: returned from zygote!");
3308            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3309
3310            if (app.isolated) {
3311                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3312            }
3313            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3314            checkTime(startTime, "startProcess: done updating battery stats");
3315
3316            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3317                    UserHandle.getUserId(uid), startResult.pid, uid,
3318                    app.processName, hostingType,
3319                    hostingNameStr != null ? hostingNameStr : "");
3320
3321            if (app.persistent) {
3322                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3323            }
3324
3325            checkTime(startTime, "startProcess: building log message");
3326            StringBuilder buf = mStringBuilder;
3327            buf.setLength(0);
3328            buf.append("Start proc ");
3329            buf.append(startResult.pid);
3330            buf.append(':');
3331            buf.append(app.processName);
3332            buf.append('/');
3333            UserHandle.formatUid(buf, uid);
3334            if (!isActivityProcess) {
3335                buf.append(" [");
3336                buf.append(entryPoint);
3337                buf.append("]");
3338            }
3339            buf.append(" for ");
3340            buf.append(hostingType);
3341            if (hostingNameStr != null) {
3342                buf.append(" ");
3343                buf.append(hostingNameStr);
3344            }
3345            Slog.i(TAG, buf.toString());
3346            app.setPid(startResult.pid);
3347            app.usingWrapper = startResult.usingWrapper;
3348            app.removed = false;
3349            app.killed = false;
3350            app.killedByAm = false;
3351            checkTime(startTime, "startProcess: starting to update pids map");
3352            synchronized (mPidsSelfLocked) {
3353                this.mPidsSelfLocked.put(startResult.pid, app);
3354                if (isActivityProcess) {
3355                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3356                    msg.obj = app;
3357                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3358                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3359                }
3360            }
3361            checkTime(startTime, "startProcess: done updating pids map");
3362        } catch (RuntimeException e) {
3363            // XXX do better error recovery.
3364            app.setPid(0);
3365            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3366            if (app.isolated) {
3367                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3368            }
3369            Slog.e(TAG, "Failure starting process " + app.processName, e);
3370        }
3371    }
3372
3373    void updateUsageStats(ActivityRecord component, boolean resumed) {
3374        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3375                "updateUsageStats: comp=" + component + "res=" + resumed);
3376        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3377        if (resumed) {
3378            if (mUsageStatsService != null) {
3379                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3380                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3381            }
3382            synchronized (stats) {
3383                stats.noteActivityResumedLocked(component.app.uid);
3384            }
3385        } else {
3386            if (mUsageStatsService != null) {
3387                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3388                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3389            }
3390            synchronized (stats) {
3391                stats.noteActivityPausedLocked(component.app.uid);
3392            }
3393        }
3394    }
3395
3396    Intent getHomeIntent() {
3397        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3398        intent.setComponent(mTopComponent);
3399        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3400            intent.addCategory(Intent.CATEGORY_HOME);
3401        }
3402        return intent;
3403    }
3404
3405    boolean startHomeActivityLocked(int userId, String reason) {
3406        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3407                && mTopAction == null) {
3408            // We are running in factory test mode, but unable to find
3409            // the factory test app, so just sit around displaying the
3410            // error message and don't try to start anything.
3411            return false;
3412        }
3413        Intent intent = getHomeIntent();
3414        ActivityInfo aInfo =
3415            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3416        if (aInfo != null) {
3417            intent.setComponent(new ComponentName(
3418                    aInfo.applicationInfo.packageName, aInfo.name));
3419            // Don't do this if the home app is currently being
3420            // instrumented.
3421            aInfo = new ActivityInfo(aInfo);
3422            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3423            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3424                    aInfo.applicationInfo.uid, true);
3425            if (app == null || app.instrumentationClass == null) {
3426                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3427                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3428            }
3429        }
3430
3431        return true;
3432    }
3433
3434    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3435        ActivityInfo ai = null;
3436        ComponentName comp = intent.getComponent();
3437        try {
3438            if (comp != null) {
3439                // Factory test.
3440                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3441            } else {
3442                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3443                        intent,
3444                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3445                        flags, userId);
3446
3447                if (info != null) {
3448                    ai = info.activityInfo;
3449                }
3450            }
3451        } catch (RemoteException e) {
3452            // ignore
3453        }
3454
3455        return ai;
3456    }
3457
3458    /**
3459     * Starts the "new version setup screen" if appropriate.
3460     */
3461    void startSetupActivityLocked() {
3462        // Only do this once per boot.
3463        if (mCheckedForSetup) {
3464            return;
3465        }
3466
3467        // We will show this screen if the current one is a different
3468        // version than the last one shown, and we are not running in
3469        // low-level factory test mode.
3470        final ContentResolver resolver = mContext.getContentResolver();
3471        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3472                Settings.Global.getInt(resolver,
3473                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3474            mCheckedForSetup = true;
3475
3476            // See if we should be showing the platform update setup UI.
3477            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3478            List<ResolveInfo> ris = mContext.getPackageManager()
3479                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3480
3481            // We don't allow third party apps to replace this.
3482            ResolveInfo ri = null;
3483            for (int i=0; ris != null && i<ris.size(); i++) {
3484                if ((ris.get(i).activityInfo.applicationInfo.flags
3485                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3486                    ri = ris.get(i);
3487                    break;
3488                }
3489            }
3490
3491            if (ri != null) {
3492                String vers = ri.activityInfo.metaData != null
3493                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3494                        : null;
3495                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3496                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3497                            Intent.METADATA_SETUP_VERSION);
3498                }
3499                String lastVers = Settings.Secure.getString(
3500                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3501                if (vers != null && !vers.equals(lastVers)) {
3502                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3503                    intent.setComponent(new ComponentName(
3504                            ri.activityInfo.packageName, ri.activityInfo.name));
3505                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3506                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3507                            null);
3508                }
3509            }
3510        }
3511    }
3512
3513    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3514        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3515    }
3516
3517    void enforceNotIsolatedCaller(String caller) {
3518        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3519            throw new SecurityException("Isolated process not allowed to call " + caller);
3520        }
3521    }
3522
3523    void enforceShellRestriction(String restriction, int userHandle) {
3524        if (Binder.getCallingUid() == Process.SHELL_UID) {
3525            if (userHandle < 0
3526                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3527                throw new SecurityException("Shell does not have permission to access user "
3528                        + userHandle);
3529            }
3530        }
3531    }
3532
3533    @Override
3534    public int getFrontActivityScreenCompatMode() {
3535        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3536        synchronized (this) {
3537            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3538        }
3539    }
3540
3541    @Override
3542    public void setFrontActivityScreenCompatMode(int mode) {
3543        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3544                "setFrontActivityScreenCompatMode");
3545        synchronized (this) {
3546            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3547        }
3548    }
3549
3550    @Override
3551    public int getPackageScreenCompatMode(String packageName) {
3552        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3553        synchronized (this) {
3554            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3555        }
3556    }
3557
3558    @Override
3559    public void setPackageScreenCompatMode(String packageName, int mode) {
3560        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3561                "setPackageScreenCompatMode");
3562        synchronized (this) {
3563            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3564        }
3565    }
3566
3567    @Override
3568    public boolean getPackageAskScreenCompat(String packageName) {
3569        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3570        synchronized (this) {
3571            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3572        }
3573    }
3574
3575    @Override
3576    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3577        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3578                "setPackageAskScreenCompat");
3579        synchronized (this) {
3580            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3581        }
3582    }
3583
3584    @Override
3585    public int getPackageProcessState(String packageName) {
3586        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3587        synchronized (this) {
3588            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3589                final ProcessRecord proc = mLruProcesses.get(i);
3590                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3591                        || procState > proc.setProcState) {
3592                    boolean found = false;
3593                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3594                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3595                            procState = proc.setProcState;
3596                            found = true;
3597                        }
3598                    }
3599                    if (proc.pkgDeps != null && !found) {
3600                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3601                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3602                                procState = proc.setProcState;
3603                                break;
3604                            }
3605                        }
3606                    }
3607                }
3608            }
3609        }
3610        return procState;
3611    }
3612
3613    @Override
3614    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3615        synchronized (this) {
3616            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3617            if (app == null) {
3618                return false;
3619            }
3620            if (app.trimMemoryLevel < level && app.thread != null &&
3621                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3622                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3623                try {
3624                    app.thread.scheduleTrimMemory(level);
3625                    app.trimMemoryLevel = level;
3626                    return true;
3627                } catch (RemoteException e) {
3628                    // Fallthrough to failure case.
3629                }
3630            }
3631        }
3632        return false;
3633    }
3634
3635    private void dispatchProcessesChanged() {
3636        int N;
3637        synchronized (this) {
3638            N = mPendingProcessChanges.size();
3639            if (mActiveProcessChanges.length < N) {
3640                mActiveProcessChanges = new ProcessChangeItem[N];
3641            }
3642            mPendingProcessChanges.toArray(mActiveProcessChanges);
3643            mPendingProcessChanges.clear();
3644            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3645                    "*** Delivering " + N + " process changes");
3646        }
3647
3648        int i = mProcessObservers.beginBroadcast();
3649        while (i > 0) {
3650            i--;
3651            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3652            if (observer != null) {
3653                try {
3654                    for (int j=0; j<N; j++) {
3655                        ProcessChangeItem item = mActiveProcessChanges[j];
3656                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3657                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3658                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3659                                    + item.uid + ": " + item.foregroundActivities);
3660                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3661                                    item.foregroundActivities);
3662                        }
3663                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3664                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3665                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3666                                    + ": " + item.processState);
3667                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3668                        }
3669                    }
3670                } catch (RemoteException e) {
3671                }
3672            }
3673        }
3674        mProcessObservers.finishBroadcast();
3675
3676        synchronized (this) {
3677            for (int j=0; j<N; j++) {
3678                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3679            }
3680        }
3681    }
3682
3683    private void dispatchProcessDied(int pid, int uid) {
3684        int i = mProcessObservers.beginBroadcast();
3685        while (i > 0) {
3686            i--;
3687            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3688            if (observer != null) {
3689                try {
3690                    observer.onProcessDied(pid, uid);
3691                } catch (RemoteException e) {
3692                }
3693            }
3694        }
3695        mProcessObservers.finishBroadcast();
3696    }
3697
3698    private void dispatchUidsChanged() {
3699        int N;
3700        synchronized (this) {
3701            N = mPendingUidChanges.size();
3702            if (mActiveUidChanges.length < N) {
3703                mActiveUidChanges = new UidRecord.ChangeItem[N];
3704            }
3705            for (int i=0; i<N; i++) {
3706                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3707                mActiveUidChanges[i] = change;
3708                change.uidRecord.pendingChange = null;
3709                change.uidRecord = null;
3710            }
3711            mPendingUidChanges.clear();
3712            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3713                    "*** Delivering " + N + " uid changes");
3714        }
3715
3716        if (mLocalPowerManager != null) {
3717            for (int j=0; j<N; j++) {
3718                UidRecord.ChangeItem item = mActiveUidChanges[j];
3719                if (item.gone) {
3720                    mLocalPowerManager.uidGone(item.uid);
3721                } else {
3722                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3723                }
3724            }
3725        }
3726
3727        int i = mUidObservers.beginBroadcast();
3728        while (i > 0) {
3729            i--;
3730            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3731            if (observer != null) {
3732                try {
3733                    for (int j=0; j<N; j++) {
3734                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3735                        if (item.gone) {
3736                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3737                                    "UID gone uid=" + item.uid);
3738                            observer.onUidGone(item.uid);
3739                        } else {
3740                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3741                                    "UID CHANGED uid=" + item.uid
3742                                    + ": " + item.processState);
3743                            observer.onUidStateChanged(item.uid, item.processState);
3744                        }
3745                    }
3746                } catch (RemoteException e) {
3747                }
3748            }
3749        }
3750        mUidObservers.finishBroadcast();
3751
3752        synchronized (this) {
3753            for (int j=0; j<N; j++) {
3754                mAvailUidChanges.add(mActiveUidChanges[j]);
3755            }
3756        }
3757    }
3758
3759    @Override
3760    public final int startActivity(IApplicationThread caller, String callingPackage,
3761            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3762            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3763        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3764            resultWho, requestCode, startFlags, profilerInfo, options,
3765            UserHandle.getCallingUserId());
3766    }
3767
3768    @Override
3769    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3770            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3771            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3772        enforceNotIsolatedCaller("startActivity");
3773        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3774                false, ALLOW_FULL_ONLY, "startActivity", null);
3775        // TODO: Switch to user app stacks here.
3776        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3777                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3778                profilerInfo, null, null, options, userId, null, null);
3779    }
3780
3781    @Override
3782    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3783            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3784            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3785
3786        // This is very dangerous -- it allows you to perform a start activity (including
3787        // permission grants) as any app that may launch one of your own activities.  So
3788        // we will only allow this to be done from activities that are part of the core framework,
3789        // and then only when they are running as the system.
3790        final ActivityRecord sourceRecord;
3791        final int targetUid;
3792        final String targetPackage;
3793        synchronized (this) {
3794            if (resultTo == null) {
3795                throw new SecurityException("Must be called from an activity");
3796            }
3797            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3798            if (sourceRecord == null) {
3799                throw new SecurityException("Called with bad activity token: " + resultTo);
3800            }
3801            if (!sourceRecord.info.packageName.equals("android")) {
3802                throw new SecurityException(
3803                        "Must be called from an activity that is declared in the android package");
3804            }
3805            if (sourceRecord.app == null) {
3806                throw new SecurityException("Called without a process attached to activity");
3807            }
3808            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3809                // This is still okay, as long as this activity is running under the
3810                // uid of the original calling activity.
3811                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3812                    throw new SecurityException(
3813                            "Calling activity in uid " + sourceRecord.app.uid
3814                                    + " must be system uid or original calling uid "
3815                                    + sourceRecord.launchedFromUid);
3816                }
3817            }
3818            targetUid = sourceRecord.launchedFromUid;
3819            targetPackage = sourceRecord.launchedFromPackage;
3820        }
3821
3822        if (userId == UserHandle.USER_NULL) {
3823            userId = UserHandle.getUserId(sourceRecord.app.uid);
3824        }
3825
3826        // TODO: Switch to user app stacks here.
3827        try {
3828            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3829                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3830                    null, null, options, userId, null, null);
3831            return ret;
3832        } catch (SecurityException e) {
3833            // XXX need to figure out how to propagate to original app.
3834            // A SecurityException here is generally actually a fault of the original
3835            // calling activity (such as a fairly granting permissions), so propagate it
3836            // back to them.
3837            /*
3838            StringBuilder msg = new StringBuilder();
3839            msg.append("While launching");
3840            msg.append(intent.toString());
3841            msg.append(": ");
3842            msg.append(e.getMessage());
3843            */
3844            throw e;
3845        }
3846    }
3847
3848    @Override
3849    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3850            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3851            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3852        enforceNotIsolatedCaller("startActivityAndWait");
3853        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3854                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3855        WaitResult res = new WaitResult();
3856        // TODO: Switch to user app stacks here.
3857        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3858                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3859                options, userId, null, null);
3860        return res;
3861    }
3862
3863    @Override
3864    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3865            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3866            int startFlags, Configuration config, Bundle options, int userId) {
3867        enforceNotIsolatedCaller("startActivityWithConfig");
3868        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3869                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3870        // TODO: Switch to user app stacks here.
3871        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3872                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3873                null, null, config, options, userId, null, null);
3874        return ret;
3875    }
3876
3877    @Override
3878    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3879            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3880            int requestCode, int flagsMask, int flagsValues, Bundle options)
3881            throws TransactionTooLargeException {
3882        enforceNotIsolatedCaller("startActivityIntentSender");
3883        // Refuse possible leaked file descriptors
3884        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3885            throw new IllegalArgumentException("File descriptors passed in Intent");
3886        }
3887
3888        IIntentSender sender = intent.getTarget();
3889        if (!(sender instanceof PendingIntentRecord)) {
3890            throw new IllegalArgumentException("Bad PendingIntent object");
3891        }
3892
3893        PendingIntentRecord pir = (PendingIntentRecord)sender;
3894
3895        synchronized (this) {
3896            // If this is coming from the currently resumed activity, it is
3897            // effectively saying that app switches are allowed at this point.
3898            final ActivityStack stack = getFocusedStack();
3899            if (stack.mResumedActivity != null &&
3900                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3901                mAppSwitchesAllowedTime = 0;
3902            }
3903        }
3904        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3905                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3906        return ret;
3907    }
3908
3909    @Override
3910    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3911            Intent intent, String resolvedType, IVoiceInteractionSession session,
3912            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3913            Bundle options, int userId) {
3914        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3915                != PackageManager.PERMISSION_GRANTED) {
3916            String msg = "Permission Denial: startVoiceActivity() from pid="
3917                    + Binder.getCallingPid()
3918                    + ", uid=" + Binder.getCallingUid()
3919                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3920            Slog.w(TAG, msg);
3921            throw new SecurityException(msg);
3922        }
3923        if (session == null || interactor == null) {
3924            throw new NullPointerException("null session or interactor");
3925        }
3926        userId = handleIncomingUser(callingPid, callingUid, userId,
3927                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3928        // TODO: Switch to user app stacks here.
3929        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3930                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3931                null, options, userId, null, null);
3932    }
3933
3934    @Override
3935    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3936        synchronized (this) {
3937            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3938                if (keepAwake) {
3939                    mVoiceWakeLock.acquire();
3940                } else {
3941                    mVoiceWakeLock.release();
3942                }
3943            }
3944        }
3945    }
3946
3947    @Override
3948    public boolean startNextMatchingActivity(IBinder callingActivity,
3949            Intent intent, Bundle options) {
3950        // Refuse possible leaked file descriptors
3951        if (intent != null && intent.hasFileDescriptors() == true) {
3952            throw new IllegalArgumentException("File descriptors passed in Intent");
3953        }
3954
3955        synchronized (this) {
3956            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3957            if (r == null) {
3958                ActivityOptions.abort(options);
3959                return false;
3960            }
3961            if (r.app == null || r.app.thread == null) {
3962                // The caller is not running...  d'oh!
3963                ActivityOptions.abort(options);
3964                return false;
3965            }
3966            intent = new Intent(intent);
3967            // The caller is not allowed to change the data.
3968            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3969            // And we are resetting to find the next component...
3970            intent.setComponent(null);
3971
3972            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3973
3974            ActivityInfo aInfo = null;
3975            try {
3976                List<ResolveInfo> resolves =
3977                    AppGlobals.getPackageManager().queryIntentActivities(
3978                            intent, r.resolvedType,
3979                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3980                            UserHandle.getCallingUserId());
3981
3982                // Look for the original activity in the list...
3983                final int N = resolves != null ? resolves.size() : 0;
3984                for (int i=0; i<N; i++) {
3985                    ResolveInfo rInfo = resolves.get(i);
3986                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3987                            && rInfo.activityInfo.name.equals(r.info.name)) {
3988                        // We found the current one...  the next matching is
3989                        // after it.
3990                        i++;
3991                        if (i<N) {
3992                            aInfo = resolves.get(i).activityInfo;
3993                        }
3994                        if (debug) {
3995                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3996                                    + "/" + r.info.name);
3997                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3998                                    + "/" + aInfo.name);
3999                        }
4000                        break;
4001                    }
4002                }
4003            } catch (RemoteException e) {
4004            }
4005
4006            if (aInfo == null) {
4007                // Nobody who is next!
4008                ActivityOptions.abort(options);
4009                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4010                return false;
4011            }
4012
4013            intent.setComponent(new ComponentName(
4014                    aInfo.applicationInfo.packageName, aInfo.name));
4015            intent.setFlags(intent.getFlags()&~(
4016                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4017                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4018                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4019                    Intent.FLAG_ACTIVITY_NEW_TASK));
4020
4021            // Okay now we need to start the new activity, replacing the
4022            // currently running activity.  This is a little tricky because
4023            // we want to start the new one as if the current one is finished,
4024            // but not finish the current one first so that there is no flicker.
4025            // And thus...
4026            final boolean wasFinishing = r.finishing;
4027            r.finishing = true;
4028
4029            // Propagate reply information over to the new activity.
4030            final ActivityRecord resultTo = r.resultTo;
4031            final String resultWho = r.resultWho;
4032            final int requestCode = r.requestCode;
4033            r.resultTo = null;
4034            if (resultTo != null) {
4035                resultTo.removeResultsLocked(r, resultWho, requestCode);
4036            }
4037
4038            final long origId = Binder.clearCallingIdentity();
4039            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4040                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4041                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4042                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4043            Binder.restoreCallingIdentity(origId);
4044
4045            r.finishing = wasFinishing;
4046            if (res != ActivityManager.START_SUCCESS) {
4047                return false;
4048            }
4049            return true;
4050        }
4051    }
4052
4053    @Override
4054    public final int startActivityFromRecents(int taskId, Bundle options) {
4055        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4056            String msg = "Permission Denial: startActivityFromRecents called without " +
4057                    START_TASKS_FROM_RECENTS;
4058            Slog.w(TAG, msg);
4059            throw new SecurityException(msg);
4060        }
4061        return startActivityFromRecentsInner(taskId, options);
4062    }
4063
4064    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4065        final TaskRecord task;
4066        final int callingUid;
4067        final String callingPackage;
4068        final Intent intent;
4069        final int userId;
4070        synchronized (this) {
4071            task = mRecentTasks.taskForIdLocked(taskId);
4072            if (task == null) {
4073                throw new IllegalArgumentException("Task " + taskId + " not found.");
4074            }
4075            if (task.getRootActivity() != null) {
4076                moveTaskToFrontLocked(task.taskId, 0, null);
4077                return ActivityManager.START_TASK_TO_FRONT;
4078            }
4079            callingUid = task.mCallingUid;
4080            callingPackage = task.mCallingPackage;
4081            intent = task.intent;
4082            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4083            userId = task.userId;
4084        }
4085        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4086                options, userId, null, task);
4087    }
4088
4089    final int startActivityInPackage(int uid, String callingPackage,
4090            Intent intent, String resolvedType, IBinder resultTo,
4091            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4092            IActivityContainer container, TaskRecord inTask) {
4093
4094        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4095                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4096
4097        // TODO: Switch to user app stacks here.
4098        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4099                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4100                null, null, null, options, userId, container, inTask);
4101        return ret;
4102    }
4103
4104    @Override
4105    public final int startActivities(IApplicationThread caller, String callingPackage,
4106            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4107            int userId) {
4108        enforceNotIsolatedCaller("startActivities");
4109        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4110                false, ALLOW_FULL_ONLY, "startActivity", null);
4111        // TODO: Switch to user app stacks here.
4112        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4113                resolvedTypes, resultTo, options, userId);
4114        return ret;
4115    }
4116
4117    final int startActivitiesInPackage(int uid, String callingPackage,
4118            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4119            Bundle options, int userId) {
4120
4121        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4122                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4123        // TODO: Switch to user app stacks here.
4124        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4125                resultTo, options, userId);
4126        return ret;
4127    }
4128
4129    @Override
4130    public void reportActivityFullyDrawn(IBinder token) {
4131        synchronized (this) {
4132            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4133            if (r == null) {
4134                return;
4135            }
4136            r.reportFullyDrawnLocked();
4137        }
4138    }
4139
4140    @Override
4141    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4142        synchronized (this) {
4143            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4144            if (r == null) {
4145                return;
4146            }
4147            if (r.task != null && r.task.mResizeable) {
4148                // Fixed screen orientation isn't supported with resizeable activities.
4149                return;
4150            }
4151            final long origId = Binder.clearCallingIdentity();
4152            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4153            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4154                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4155            if (config != null) {
4156                r.frozenBeforeDestroy = true;
4157                if (!updateConfigurationLocked(config, r, false, false)) {
4158                    mStackSupervisor.resumeTopActivitiesLocked();
4159                }
4160            }
4161            Binder.restoreCallingIdentity(origId);
4162        }
4163    }
4164
4165    @Override
4166    public int getRequestedOrientation(IBinder token) {
4167        synchronized (this) {
4168            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4169            if (r == null) {
4170                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4171            }
4172            return mWindowManager.getAppOrientation(r.appToken);
4173        }
4174    }
4175
4176    /**
4177     * This is the internal entry point for handling Activity.finish().
4178     *
4179     * @param token The Binder token referencing the Activity we want to finish.
4180     * @param resultCode Result code, if any, from this Activity.
4181     * @param resultData Result data (Intent), if any, from this Activity.
4182     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4183     *            the root Activity in the task.
4184     *
4185     * @return Returns true if the activity successfully finished, or false if it is still running.
4186     */
4187    @Override
4188    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4189            boolean finishTask) {
4190        // Refuse possible leaked file descriptors
4191        if (resultData != null && resultData.hasFileDescriptors() == true) {
4192            throw new IllegalArgumentException("File descriptors passed in Intent");
4193        }
4194
4195        synchronized(this) {
4196            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4197            if (r == null) {
4198                return true;
4199            }
4200            // Keep track of the root activity of the task before we finish it
4201            TaskRecord tr = r.task;
4202            ActivityRecord rootR = tr.getRootActivity();
4203            if (rootR == null) {
4204                Slog.w(TAG, "Finishing task with all activities already finished");
4205            }
4206            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4207            // finish.
4208            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4209                    mStackSupervisor.isLastLockedTask(tr)) {
4210                Slog.i(TAG, "Not finishing task in lock task mode");
4211                mStackSupervisor.showLockTaskToast();
4212                return false;
4213            }
4214            if (mController != null) {
4215                // Find the first activity that is not finishing.
4216                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4217                if (next != null) {
4218                    // ask watcher if this is allowed
4219                    boolean resumeOK = true;
4220                    try {
4221                        resumeOK = mController.activityResuming(next.packageName);
4222                    } catch (RemoteException e) {
4223                        mController = null;
4224                        Watchdog.getInstance().setActivityController(null);
4225                    }
4226
4227                    if (!resumeOK) {
4228                        Slog.i(TAG, "Not finishing activity because controller resumed");
4229                        return false;
4230                    }
4231                }
4232            }
4233            final long origId = Binder.clearCallingIdentity();
4234            try {
4235                boolean res;
4236                if (finishTask && r == rootR) {
4237                    // If requested, remove the task that is associated to this activity only if it
4238                    // was the root activity in the task. The result code and data is ignored
4239                    // because we don't support returning them across task boundaries.
4240                    res = removeTaskByIdLocked(tr.taskId, false);
4241                    if (!res) {
4242                        Slog.i(TAG, "Removing task failed to finish activity");
4243                    }
4244                } else {
4245                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4246                            resultData, "app-request", true);
4247                    if (!res) {
4248                        Slog.i(TAG, "Failed to finish by app-request");
4249                    }
4250                }
4251                return res;
4252            } finally {
4253                Binder.restoreCallingIdentity(origId);
4254            }
4255        }
4256    }
4257
4258    @Override
4259    public final void finishHeavyWeightApp() {
4260        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4261                != PackageManager.PERMISSION_GRANTED) {
4262            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4263                    + Binder.getCallingPid()
4264                    + ", uid=" + Binder.getCallingUid()
4265                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4266            Slog.w(TAG, msg);
4267            throw new SecurityException(msg);
4268        }
4269
4270        synchronized(this) {
4271            if (mHeavyWeightProcess == null) {
4272                return;
4273            }
4274
4275            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4276            for (int i = 0; i < activities.size(); i++) {
4277                ActivityRecord r = activities.get(i);
4278                if (!r.finishing && r.isInStackLocked()) {
4279                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4280                            null, "finish-heavy", true);
4281                }
4282            }
4283
4284            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4285                    mHeavyWeightProcess.userId, 0));
4286            mHeavyWeightProcess = null;
4287        }
4288    }
4289
4290    @Override
4291    public void crashApplication(int uid, int initialPid, String packageName,
4292            String message) {
4293        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4294                != PackageManager.PERMISSION_GRANTED) {
4295            String msg = "Permission Denial: crashApplication() from pid="
4296                    + Binder.getCallingPid()
4297                    + ", uid=" + Binder.getCallingUid()
4298                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4299            Slog.w(TAG, msg);
4300            throw new SecurityException(msg);
4301        }
4302
4303        synchronized(this) {
4304            ProcessRecord proc = null;
4305
4306            // Figure out which process to kill.  We don't trust that initialPid
4307            // still has any relation to current pids, so must scan through the
4308            // list.
4309            synchronized (mPidsSelfLocked) {
4310                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4311                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4312                    if (p.uid != uid) {
4313                        continue;
4314                    }
4315                    if (p.pid == initialPid) {
4316                        proc = p;
4317                        break;
4318                    }
4319                    if (p.pkgList.containsKey(packageName)) {
4320                        proc = p;
4321                    }
4322                }
4323            }
4324
4325            if (proc == null) {
4326                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4327                        + " initialPid=" + initialPid
4328                        + " packageName=" + packageName);
4329                return;
4330            }
4331
4332            if (proc.thread != null) {
4333                if (proc.pid == Process.myPid()) {
4334                    Log.w(TAG, "crashApplication: trying to crash self!");
4335                    return;
4336                }
4337                long ident = Binder.clearCallingIdentity();
4338                try {
4339                    proc.thread.scheduleCrash(message);
4340                } catch (RemoteException e) {
4341                }
4342                Binder.restoreCallingIdentity(ident);
4343            }
4344        }
4345    }
4346
4347    @Override
4348    public final void finishSubActivity(IBinder token, String resultWho,
4349            int requestCode) {
4350        synchronized(this) {
4351            final long origId = Binder.clearCallingIdentity();
4352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4353            if (r != null) {
4354                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4355            }
4356            Binder.restoreCallingIdentity(origId);
4357        }
4358    }
4359
4360    @Override
4361    public boolean finishActivityAffinity(IBinder token) {
4362        synchronized(this) {
4363            final long origId = Binder.clearCallingIdentity();
4364            try {
4365                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4366                if (r == null) {
4367                    return false;
4368                }
4369
4370                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4371                // can finish.
4372                final TaskRecord task = r.task;
4373                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4374                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4375                    mStackSupervisor.showLockTaskToast();
4376                    return false;
4377                }
4378                return task.stack.finishActivityAffinityLocked(r);
4379            } finally {
4380                Binder.restoreCallingIdentity(origId);
4381            }
4382        }
4383    }
4384
4385    @Override
4386    public void finishVoiceTask(IVoiceInteractionSession session) {
4387        synchronized(this) {
4388            final long origId = Binder.clearCallingIdentity();
4389            try {
4390                mStackSupervisor.finishVoiceTask(session);
4391            } finally {
4392                Binder.restoreCallingIdentity(origId);
4393            }
4394        }
4395
4396    }
4397
4398    @Override
4399    public boolean releaseActivityInstance(IBinder token) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            try {
4403                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404                if (r == null) {
4405                    return false;
4406                }
4407                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4408            } finally {
4409                Binder.restoreCallingIdentity(origId);
4410            }
4411        }
4412    }
4413
4414    @Override
4415    public void releaseSomeActivities(IApplicationThread appInt) {
4416        synchronized(this) {
4417            final long origId = Binder.clearCallingIdentity();
4418            try {
4419                ProcessRecord app = getRecordForAppLocked(appInt);
4420                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4421            } finally {
4422                Binder.restoreCallingIdentity(origId);
4423            }
4424        }
4425    }
4426
4427    @Override
4428    public boolean willActivityBeVisible(IBinder token) {
4429        synchronized(this) {
4430            ActivityStack stack = ActivityRecord.getStackLocked(token);
4431            if (stack != null) {
4432                return stack.willActivityBeVisibleLocked(token);
4433            }
4434            return false;
4435        }
4436    }
4437
4438    @Override
4439    public void overridePendingTransition(IBinder token, String packageName,
4440            int enterAnim, int exitAnim) {
4441        synchronized(this) {
4442            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4443            if (self == null) {
4444                return;
4445            }
4446
4447            final long origId = Binder.clearCallingIdentity();
4448
4449            if (self.state == ActivityState.RESUMED
4450                    || self.state == ActivityState.PAUSING) {
4451                mWindowManager.overridePendingAppTransition(packageName,
4452                        enterAnim, exitAnim, null);
4453            }
4454
4455            Binder.restoreCallingIdentity(origId);
4456        }
4457    }
4458
4459    /**
4460     * Main function for removing an existing process from the activity manager
4461     * as a result of that process going away.  Clears out all connections
4462     * to the process.
4463     */
4464    private final void handleAppDiedLocked(ProcessRecord app,
4465            boolean restarting, boolean allowRestart) {
4466        int pid = app.pid;
4467        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4468        if (!kept && !restarting) {
4469            removeLruProcessLocked(app);
4470            if (pid > 0) {
4471                ProcessList.remove(pid);
4472            }
4473        }
4474
4475        if (mProfileProc == app) {
4476            clearProfilerLocked();
4477        }
4478
4479        // Remove this application's activities from active lists.
4480        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4481
4482        app.activities.clear();
4483
4484        if (app.instrumentationClass != null) {
4485            Slog.w(TAG, "Crash of app " + app.processName
4486                  + " running instrumentation " + app.instrumentationClass);
4487            Bundle info = new Bundle();
4488            info.putString("shortMsg", "Process crashed.");
4489            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4490        }
4491
4492        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4493            // If there was nothing to resume, and we are not already
4494            // restarting this process, but there is a visible activity that
4495            // is hosted by the process...  then make sure all visible
4496            // activities are running, taking care of restarting this
4497            // process.
4498            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4499        }
4500    }
4501
4502    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4503        IBinder threadBinder = thread.asBinder();
4504        // Find the application record.
4505        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4506            ProcessRecord rec = mLruProcesses.get(i);
4507            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4508                return i;
4509            }
4510        }
4511        return -1;
4512    }
4513
4514    final ProcessRecord getRecordForAppLocked(
4515            IApplicationThread thread) {
4516        if (thread == null) {
4517            return null;
4518        }
4519
4520        int appIndex = getLRURecordIndexForAppLocked(thread);
4521        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4522    }
4523
4524    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4525        // If there are no longer any background processes running,
4526        // and the app that died was not running instrumentation,
4527        // then tell everyone we are now low on memory.
4528        boolean haveBg = false;
4529        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4530            ProcessRecord rec = mLruProcesses.get(i);
4531            if (rec.thread != null
4532                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4533                haveBg = true;
4534                break;
4535            }
4536        }
4537
4538        if (!haveBg) {
4539            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4540            if (doReport) {
4541                long now = SystemClock.uptimeMillis();
4542                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4543                    doReport = false;
4544                } else {
4545                    mLastMemUsageReportTime = now;
4546                }
4547            }
4548            final ArrayList<ProcessMemInfo> memInfos
4549                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4550            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4551            long now = SystemClock.uptimeMillis();
4552            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4553                ProcessRecord rec = mLruProcesses.get(i);
4554                if (rec == dyingProc || rec.thread == null) {
4555                    continue;
4556                }
4557                if (doReport) {
4558                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4559                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4560                }
4561                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4562                    // The low memory report is overriding any current
4563                    // state for a GC request.  Make sure to do
4564                    // heavy/important/visible/foreground processes first.
4565                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4566                        rec.lastRequestedGc = 0;
4567                    } else {
4568                        rec.lastRequestedGc = rec.lastLowMemory;
4569                    }
4570                    rec.reportLowMemory = true;
4571                    rec.lastLowMemory = now;
4572                    mProcessesToGc.remove(rec);
4573                    addProcessToGcListLocked(rec);
4574                }
4575            }
4576            if (doReport) {
4577                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4578                mHandler.sendMessage(msg);
4579            }
4580            scheduleAppGcsLocked();
4581        }
4582    }
4583
4584    final void appDiedLocked(ProcessRecord app) {
4585       appDiedLocked(app, app.pid, app.thread, false);
4586    }
4587
4588    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4589            boolean fromBinderDied) {
4590        // First check if this ProcessRecord is actually active for the pid.
4591        synchronized (mPidsSelfLocked) {
4592            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4593            if (curProc != app) {
4594                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4595                return;
4596            }
4597        }
4598
4599        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4600        synchronized (stats) {
4601            stats.noteProcessDiedLocked(app.info.uid, pid);
4602        }
4603
4604        if (!app.killed) {
4605            if (!fromBinderDied) {
4606                Process.killProcessQuiet(pid);
4607            }
4608            Process.killProcessGroup(app.info.uid, pid);
4609            app.killed = true;
4610        }
4611
4612        // Clean up already done if the process has been re-started.
4613        if (app.pid == pid && app.thread != null &&
4614                app.thread.asBinder() == thread.asBinder()) {
4615            boolean doLowMem = app.instrumentationClass == null;
4616            boolean doOomAdj = doLowMem;
4617            if (!app.killedByAm) {
4618                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4619                        + ") has died");
4620                mAllowLowerMemLevel = true;
4621            } else {
4622                // Note that we always want to do oom adj to update our state with the
4623                // new number of procs.
4624                mAllowLowerMemLevel = false;
4625                doLowMem = false;
4626            }
4627            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4628            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4629                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4630            handleAppDiedLocked(app, false, true);
4631
4632            if (doOomAdj) {
4633                updateOomAdjLocked();
4634            }
4635            if (doLowMem) {
4636                doLowMemReportIfNeededLocked(app);
4637            }
4638        } else if (app.pid != pid) {
4639            // A new process has already been started.
4640            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4641                    + ") has died and restarted (pid " + app.pid + ").");
4642            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4643        } else if (DEBUG_PROCESSES) {
4644            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4645                    + thread.asBinder());
4646        }
4647    }
4648
4649    /**
4650     * If a stack trace dump file is configured, dump process stack traces.
4651     * @param clearTraces causes the dump file to be erased prior to the new
4652     *    traces being written, if true; when false, the new traces will be
4653     *    appended to any existing file content.
4654     * @param firstPids of dalvik VM processes to dump stack traces for first
4655     * @param lastPids of dalvik VM processes to dump stack traces for last
4656     * @param nativeProcs optional list of native process names to dump stack crawls
4657     * @return file containing stack traces, or null if no dump file is configured
4658     */
4659    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4660            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4661        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4662        if (tracesPath == null || tracesPath.length() == 0) {
4663            return null;
4664        }
4665
4666        File tracesFile = new File(tracesPath);
4667        try {
4668            File tracesDir = tracesFile.getParentFile();
4669            if (!tracesDir.exists()) {
4670                tracesDir.mkdirs();
4671                if (!SELinux.restorecon(tracesDir)) {
4672                    return null;
4673                }
4674            }
4675            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4676
4677            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4678            tracesFile.createNewFile();
4679            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4680        } catch (IOException e) {
4681            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4682            return null;
4683        }
4684
4685        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4686        return tracesFile;
4687    }
4688
4689    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4690            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4691        // Use a FileObserver to detect when traces finish writing.
4692        // The order of traces is considered important to maintain for legibility.
4693        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4694            @Override
4695            public synchronized void onEvent(int event, String path) { notify(); }
4696        };
4697
4698        try {
4699            observer.startWatching();
4700
4701            // First collect all of the stacks of the most important pids.
4702            if (firstPids != null) {
4703                try {
4704                    int num = firstPids.size();
4705                    for (int i = 0; i < num; i++) {
4706                        synchronized (observer) {
4707                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4708                            observer.wait(200);  // Wait for write-close, give up after 200msec
4709                        }
4710                    }
4711                } catch (InterruptedException e) {
4712                    Slog.wtf(TAG, e);
4713                }
4714            }
4715
4716            // Next collect the stacks of the native pids
4717            if (nativeProcs != null) {
4718                int[] pids = Process.getPidsForCommands(nativeProcs);
4719                if (pids != null) {
4720                    for (int pid : pids) {
4721                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4722                    }
4723                }
4724            }
4725
4726            // Lastly, measure CPU usage.
4727            if (processCpuTracker != null) {
4728                processCpuTracker.init();
4729                System.gc();
4730                processCpuTracker.update();
4731                try {
4732                    synchronized (processCpuTracker) {
4733                        processCpuTracker.wait(500); // measure over 1/2 second.
4734                    }
4735                } catch (InterruptedException e) {
4736                }
4737                processCpuTracker.update();
4738
4739                // We'll take the stack crawls of just the top apps using CPU.
4740                final int N = processCpuTracker.countWorkingStats();
4741                int numProcs = 0;
4742                for (int i=0; i<N && numProcs<5; i++) {
4743                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4744                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4745                        numProcs++;
4746                        try {
4747                            synchronized (observer) {
4748                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4749                                observer.wait(200);  // Wait for write-close, give up after 200msec
4750                            }
4751                        } catch (InterruptedException e) {
4752                            Slog.wtf(TAG, e);
4753                        }
4754
4755                    }
4756                }
4757            }
4758        } finally {
4759            observer.stopWatching();
4760        }
4761    }
4762
4763    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4764        if (true || IS_USER_BUILD) {
4765            return;
4766        }
4767        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4768        if (tracesPath == null || tracesPath.length() == 0) {
4769            return;
4770        }
4771
4772        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4773        StrictMode.allowThreadDiskWrites();
4774        try {
4775            final File tracesFile = new File(tracesPath);
4776            final File tracesDir = tracesFile.getParentFile();
4777            final File tracesTmp = new File(tracesDir, "__tmp__");
4778            try {
4779                if (!tracesDir.exists()) {
4780                    tracesDir.mkdirs();
4781                    if (!SELinux.restorecon(tracesDir.getPath())) {
4782                        return;
4783                    }
4784                }
4785                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4786
4787                if (tracesFile.exists()) {
4788                    tracesTmp.delete();
4789                    tracesFile.renameTo(tracesTmp);
4790                }
4791                StringBuilder sb = new StringBuilder();
4792                Time tobj = new Time();
4793                tobj.set(System.currentTimeMillis());
4794                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4795                sb.append(": ");
4796                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4797                sb.append(" since ");
4798                sb.append(msg);
4799                FileOutputStream fos = new FileOutputStream(tracesFile);
4800                fos.write(sb.toString().getBytes());
4801                if (app == null) {
4802                    fos.write("\n*** No application process!".getBytes());
4803                }
4804                fos.close();
4805                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4806            } catch (IOException e) {
4807                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4808                return;
4809            }
4810
4811            if (app != null) {
4812                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4813                firstPids.add(app.pid);
4814                dumpStackTraces(tracesPath, firstPids, null, null, null);
4815            }
4816
4817            File lastTracesFile = null;
4818            File curTracesFile = null;
4819            for (int i=9; i>=0; i--) {
4820                String name = String.format(Locale.US, "slow%02d.txt", i);
4821                curTracesFile = new File(tracesDir, name);
4822                if (curTracesFile.exists()) {
4823                    if (lastTracesFile != null) {
4824                        curTracesFile.renameTo(lastTracesFile);
4825                    } else {
4826                        curTracesFile.delete();
4827                    }
4828                }
4829                lastTracesFile = curTracesFile;
4830            }
4831            tracesFile.renameTo(curTracesFile);
4832            if (tracesTmp.exists()) {
4833                tracesTmp.renameTo(tracesFile);
4834            }
4835        } finally {
4836            StrictMode.setThreadPolicy(oldPolicy);
4837        }
4838    }
4839
4840    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4841            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4842        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4843        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4844
4845        if (mController != null) {
4846            try {
4847                // 0 == continue, -1 = kill process immediately
4848                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4849                if (res < 0 && app.pid != MY_PID) {
4850                    app.kill("anr", true);
4851                }
4852            } catch (RemoteException e) {
4853                mController = null;
4854                Watchdog.getInstance().setActivityController(null);
4855            }
4856        }
4857
4858        long anrTime = SystemClock.uptimeMillis();
4859        if (MONITOR_CPU_USAGE) {
4860            updateCpuStatsNow();
4861        }
4862
4863        synchronized (this) {
4864            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4865            if (mShuttingDown) {
4866                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4867                return;
4868            } else if (app.notResponding) {
4869                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4870                return;
4871            } else if (app.crashing) {
4872                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4873                return;
4874            }
4875
4876            // In case we come through here for the same app before completing
4877            // this one, mark as anring now so we will bail out.
4878            app.notResponding = true;
4879
4880            // Log the ANR to the event log.
4881            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4882                    app.processName, app.info.flags, annotation);
4883
4884            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4885            firstPids.add(app.pid);
4886
4887            int parentPid = app.pid;
4888            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4889            if (parentPid != app.pid) firstPids.add(parentPid);
4890
4891            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4892
4893            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4894                ProcessRecord r = mLruProcesses.get(i);
4895                if (r != null && r.thread != null) {
4896                    int pid = r.pid;
4897                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4898                        if (r.persistent) {
4899                            firstPids.add(pid);
4900                        } else {
4901                            lastPids.put(pid, Boolean.TRUE);
4902                        }
4903                    }
4904                }
4905            }
4906        }
4907
4908        // Log the ANR to the main log.
4909        StringBuilder info = new StringBuilder();
4910        info.setLength(0);
4911        info.append("ANR in ").append(app.processName);
4912        if (activity != null && activity.shortComponentName != null) {
4913            info.append(" (").append(activity.shortComponentName).append(")");
4914        }
4915        info.append("\n");
4916        info.append("PID: ").append(app.pid).append("\n");
4917        if (annotation != null) {
4918            info.append("Reason: ").append(annotation).append("\n");
4919        }
4920        if (parent != null && parent != activity) {
4921            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4922        }
4923
4924        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4925
4926        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4927                NATIVE_STACKS_OF_INTEREST);
4928
4929        String cpuInfo = null;
4930        if (MONITOR_CPU_USAGE) {
4931            updateCpuStatsNow();
4932            synchronized (mProcessCpuTracker) {
4933                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4934            }
4935            info.append(processCpuTracker.printCurrentLoad());
4936            info.append(cpuInfo);
4937        }
4938
4939        info.append(processCpuTracker.printCurrentState(anrTime));
4940
4941        Slog.e(TAG, info.toString());
4942        if (tracesFile == null) {
4943            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4944            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4945        }
4946
4947        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4948                cpuInfo, tracesFile, null);
4949
4950        if (mController != null) {
4951            try {
4952                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4953                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4954                if (res != 0) {
4955                    if (res < 0 && app.pid != MY_PID) {
4956                        app.kill("anr", true);
4957                    } else {
4958                        synchronized (this) {
4959                            mServices.scheduleServiceTimeoutLocked(app);
4960                        }
4961                    }
4962                    return;
4963                }
4964            } catch (RemoteException e) {
4965                mController = null;
4966                Watchdog.getInstance().setActivityController(null);
4967            }
4968        }
4969
4970        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4971        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4972                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4973
4974        synchronized (this) {
4975            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4976
4977            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4978                app.kill("bg anr", true);
4979                return;
4980            }
4981
4982            // Set the app's notResponding state, and look up the errorReportReceiver
4983            makeAppNotRespondingLocked(app,
4984                    activity != null ? activity.shortComponentName : null,
4985                    annotation != null ? "ANR " + annotation : "ANR",
4986                    info.toString());
4987
4988            // Bring up the infamous App Not Responding dialog
4989            Message msg = Message.obtain();
4990            HashMap<String, Object> map = new HashMap<String, Object>();
4991            msg.what = SHOW_NOT_RESPONDING_MSG;
4992            msg.obj = map;
4993            msg.arg1 = aboveSystem ? 1 : 0;
4994            map.put("app", app);
4995            if (activity != null) {
4996                map.put("activity", activity);
4997            }
4998
4999            mUiHandler.sendMessage(msg);
5000        }
5001    }
5002
5003    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5004        if (!mLaunchWarningShown) {
5005            mLaunchWarningShown = true;
5006            mUiHandler.post(new Runnable() {
5007                @Override
5008                public void run() {
5009                    synchronized (ActivityManagerService.this) {
5010                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5011                        d.show();
5012                        mUiHandler.postDelayed(new Runnable() {
5013                            @Override
5014                            public void run() {
5015                                synchronized (ActivityManagerService.this) {
5016                                    d.dismiss();
5017                                    mLaunchWarningShown = false;
5018                                }
5019                            }
5020                        }, 4000);
5021                    }
5022                }
5023            });
5024        }
5025    }
5026
5027    @Override
5028    public boolean clearApplicationUserData(final String packageName,
5029            final IPackageDataObserver observer, int userId) {
5030        enforceNotIsolatedCaller("clearApplicationUserData");
5031        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5032            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5033        }
5034        int uid = Binder.getCallingUid();
5035        int pid = Binder.getCallingPid();
5036        userId = handleIncomingUser(pid, uid,
5037                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5038        long callingId = Binder.clearCallingIdentity();
5039        try {
5040            IPackageManager pm = AppGlobals.getPackageManager();
5041            int pkgUid = -1;
5042            synchronized(this) {
5043                try {
5044                    pkgUid = pm.getPackageUid(packageName, userId);
5045                } catch (RemoteException e) {
5046                }
5047                if (pkgUid == -1) {
5048                    Slog.w(TAG, "Invalid packageName: " + packageName);
5049                    if (observer != null) {
5050                        try {
5051                            observer.onRemoveCompleted(packageName, false);
5052                        } catch (RemoteException e) {
5053                            Slog.i(TAG, "Observer no longer exists.");
5054                        }
5055                    }
5056                    return false;
5057                }
5058                if (uid == pkgUid || checkComponentPermission(
5059                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5060                        pid, uid, -1, true)
5061                        == PackageManager.PERMISSION_GRANTED) {
5062                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5063                } else {
5064                    throw new SecurityException("PID " + pid + " does not have permission "
5065                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5066                                    + " of package " + packageName);
5067                }
5068
5069                // Remove all tasks match the cleared application package and user
5070                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5071                    final TaskRecord tr = mRecentTasks.get(i);
5072                    final String taskPackageName =
5073                            tr.getBaseIntent().getComponent().getPackageName();
5074                    if (tr.userId != userId) continue;
5075                    if (!taskPackageName.equals(packageName)) continue;
5076                    removeTaskByIdLocked(tr.taskId, false);
5077                }
5078            }
5079
5080            try {
5081                // Clear application user data
5082                pm.clearApplicationUserData(packageName, observer, userId);
5083
5084                synchronized(this) {
5085                    // Remove all permissions granted from/to this package
5086                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5087                }
5088
5089                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5090                        Uri.fromParts("package", packageName, null));
5091                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5092                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5093                        null, null, 0, null, null, null, false, false, userId);
5094            } catch (RemoteException e) {
5095            }
5096        } finally {
5097            Binder.restoreCallingIdentity(callingId);
5098        }
5099        return true;
5100    }
5101
5102    @Override
5103    public void killBackgroundProcesses(final String packageName, int userId) {
5104        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5105                != PackageManager.PERMISSION_GRANTED &&
5106                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5107                        != PackageManager.PERMISSION_GRANTED) {
5108            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5109                    + Binder.getCallingPid()
5110                    + ", uid=" + Binder.getCallingUid()
5111                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5112            Slog.w(TAG, msg);
5113            throw new SecurityException(msg);
5114        }
5115
5116        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5117                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5118        long callingId = Binder.clearCallingIdentity();
5119        try {
5120            IPackageManager pm = AppGlobals.getPackageManager();
5121            synchronized(this) {
5122                int appId = -1;
5123                try {
5124                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5125                } catch (RemoteException e) {
5126                }
5127                if (appId == -1) {
5128                    Slog.w(TAG, "Invalid packageName: " + packageName);
5129                    return;
5130                }
5131                killPackageProcessesLocked(packageName, appId, userId,
5132                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5133            }
5134        } finally {
5135            Binder.restoreCallingIdentity(callingId);
5136        }
5137    }
5138
5139    @Override
5140    public void killAllBackgroundProcesses() {
5141        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5142                != PackageManager.PERMISSION_GRANTED) {
5143            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5144                    + Binder.getCallingPid()
5145                    + ", uid=" + Binder.getCallingUid()
5146                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5147            Slog.w(TAG, msg);
5148            throw new SecurityException(msg);
5149        }
5150
5151        long callingId = Binder.clearCallingIdentity();
5152        try {
5153            synchronized(this) {
5154                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5155                final int NP = mProcessNames.getMap().size();
5156                for (int ip=0; ip<NP; ip++) {
5157                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5158                    final int NA = apps.size();
5159                    for (int ia=0; ia<NA; ia++) {
5160                        ProcessRecord app = apps.valueAt(ia);
5161                        if (app.persistent) {
5162                            // we don't kill persistent processes
5163                            continue;
5164                        }
5165                        if (app.removed) {
5166                            procs.add(app);
5167                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5168                            app.removed = true;
5169                            procs.add(app);
5170                        }
5171                    }
5172                }
5173
5174                int N = procs.size();
5175                for (int i=0; i<N; i++) {
5176                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5177                }
5178                mAllowLowerMemLevel = true;
5179                updateOomAdjLocked();
5180                doLowMemReportIfNeededLocked(null);
5181            }
5182        } finally {
5183            Binder.restoreCallingIdentity(callingId);
5184        }
5185    }
5186
5187    @Override
5188    public void forceStopPackage(final String packageName, int userId) {
5189        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5190                != PackageManager.PERMISSION_GRANTED) {
5191            String msg = "Permission Denial: forceStopPackage() from pid="
5192                    + Binder.getCallingPid()
5193                    + ", uid=" + Binder.getCallingUid()
5194                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5195            Slog.w(TAG, msg);
5196            throw new SecurityException(msg);
5197        }
5198        final int callingPid = Binder.getCallingPid();
5199        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5200                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            IPackageManager pm = AppGlobals.getPackageManager();
5204            synchronized(this) {
5205                int[] users = userId == UserHandle.USER_ALL
5206                        ? getUsersLocked() : new int[] { userId };
5207                for (int user : users) {
5208                    int pkgUid = -1;
5209                    try {
5210                        pkgUid = pm.getPackageUid(packageName, user);
5211                    } catch (RemoteException e) {
5212                    }
5213                    if (pkgUid == -1) {
5214                        Slog.w(TAG, "Invalid packageName: " + packageName);
5215                        continue;
5216                    }
5217                    try {
5218                        pm.setPackageStoppedState(packageName, true, user);
5219                    } catch (RemoteException e) {
5220                    } catch (IllegalArgumentException e) {
5221                        Slog.w(TAG, "Failed trying to unstop package "
5222                                + packageName + ": " + e);
5223                    }
5224                    if (isUserRunningLocked(user, false)) {
5225                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5226                    }
5227                }
5228            }
5229        } finally {
5230            Binder.restoreCallingIdentity(callingId);
5231        }
5232    }
5233
5234    @Override
5235    public void addPackageDependency(String packageName) {
5236        synchronized (this) {
5237            int callingPid = Binder.getCallingPid();
5238            if (callingPid == Process.myPid()) {
5239                //  Yeah, um, no.
5240                return;
5241            }
5242            ProcessRecord proc;
5243            synchronized (mPidsSelfLocked) {
5244                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5245            }
5246            if (proc != null) {
5247                if (proc.pkgDeps == null) {
5248                    proc.pkgDeps = new ArraySet<String>(1);
5249                }
5250                proc.pkgDeps.add(packageName);
5251            }
5252        }
5253    }
5254
5255    /*
5256     * The pkg name and app id have to be specified.
5257     */
5258    @Override
5259    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5260        if (pkg == null) {
5261            return;
5262        }
5263        // Make sure the uid is valid.
5264        if (appid < 0) {
5265            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5266            return;
5267        }
5268        int callerUid = Binder.getCallingUid();
5269        // Only the system server can kill an application
5270        if (callerUid == Process.SYSTEM_UID) {
5271            // Post an aysnc message to kill the application
5272            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5273            msg.arg1 = appid;
5274            msg.arg2 = 0;
5275            Bundle bundle = new Bundle();
5276            bundle.putString("pkg", pkg);
5277            bundle.putString("reason", reason);
5278            msg.obj = bundle;
5279            mHandler.sendMessage(msg);
5280        } else {
5281            throw new SecurityException(callerUid + " cannot kill pkg: " +
5282                    pkg);
5283        }
5284    }
5285
5286    @Override
5287    public void closeSystemDialogs(String reason) {
5288        enforceNotIsolatedCaller("closeSystemDialogs");
5289
5290        final int pid = Binder.getCallingPid();
5291        final int uid = Binder.getCallingUid();
5292        final long origId = Binder.clearCallingIdentity();
5293        try {
5294            synchronized (this) {
5295                // Only allow this from foreground processes, so that background
5296                // applications can't abuse it to prevent system UI from being shown.
5297                if (uid >= Process.FIRST_APPLICATION_UID) {
5298                    ProcessRecord proc;
5299                    synchronized (mPidsSelfLocked) {
5300                        proc = mPidsSelfLocked.get(pid);
5301                    }
5302                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5303                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5304                                + " from background process " + proc);
5305                        return;
5306                    }
5307                }
5308                closeSystemDialogsLocked(reason);
5309            }
5310        } finally {
5311            Binder.restoreCallingIdentity(origId);
5312        }
5313    }
5314
5315    void closeSystemDialogsLocked(String reason) {
5316        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5317        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5318                | Intent.FLAG_RECEIVER_FOREGROUND);
5319        if (reason != null) {
5320            intent.putExtra("reason", reason);
5321        }
5322        mWindowManager.closeSystemDialogs(reason);
5323
5324        mStackSupervisor.closeSystemDialogsLocked();
5325
5326        broadcastIntentLocked(null, null, intent, null,
5327                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5328                Process.SYSTEM_UID, UserHandle.USER_ALL);
5329    }
5330
5331    @Override
5332    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5333        enforceNotIsolatedCaller("getProcessMemoryInfo");
5334        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5335        for (int i=pids.length-1; i>=0; i--) {
5336            ProcessRecord proc;
5337            int oomAdj;
5338            synchronized (this) {
5339                synchronized (mPidsSelfLocked) {
5340                    proc = mPidsSelfLocked.get(pids[i]);
5341                    oomAdj = proc != null ? proc.setAdj : 0;
5342                }
5343            }
5344            infos[i] = new Debug.MemoryInfo();
5345            Debug.getMemoryInfo(pids[i], infos[i]);
5346            if (proc != null) {
5347                synchronized (this) {
5348                    if (proc.thread != null && proc.setAdj == oomAdj) {
5349                        // Record this for posterity if the process has been stable.
5350                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5351                                infos[i].getTotalUss(), false, proc.pkgList);
5352                    }
5353                }
5354            }
5355        }
5356        return infos;
5357    }
5358
5359    @Override
5360    public long[] getProcessPss(int[] pids) {
5361        enforceNotIsolatedCaller("getProcessPss");
5362        long[] pss = new long[pids.length];
5363        for (int i=pids.length-1; i>=0; i--) {
5364            ProcessRecord proc;
5365            int oomAdj;
5366            synchronized (this) {
5367                synchronized (mPidsSelfLocked) {
5368                    proc = mPidsSelfLocked.get(pids[i]);
5369                    oomAdj = proc != null ? proc.setAdj : 0;
5370                }
5371            }
5372            long[] tmpUss = new long[1];
5373            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5374            if (proc != null) {
5375                synchronized (this) {
5376                    if (proc.thread != null && proc.setAdj == oomAdj) {
5377                        // Record this for posterity if the process has been stable.
5378                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5379                    }
5380                }
5381            }
5382        }
5383        return pss;
5384    }
5385
5386    @Override
5387    public void killApplicationProcess(String processName, int uid) {
5388        if (processName == null) {
5389            return;
5390        }
5391
5392        int callerUid = Binder.getCallingUid();
5393        // Only the system server can kill an application
5394        if (callerUid == Process.SYSTEM_UID) {
5395            synchronized (this) {
5396                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5397                if (app != null && app.thread != null) {
5398                    try {
5399                        app.thread.scheduleSuicide();
5400                    } catch (RemoteException e) {
5401                        // If the other end already died, then our work here is done.
5402                    }
5403                } else {
5404                    Slog.w(TAG, "Process/uid not found attempting kill of "
5405                            + processName + " / " + uid);
5406                }
5407            }
5408        } else {
5409            throw new SecurityException(callerUid + " cannot kill app process: " +
5410                    processName);
5411        }
5412    }
5413
5414    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5415        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5416                false, true, false, false, UserHandle.getUserId(uid), reason);
5417        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5418                Uri.fromParts("package", packageName, null));
5419        if (!mProcessesReady) {
5420            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5421                    | Intent.FLAG_RECEIVER_FOREGROUND);
5422        }
5423        intent.putExtra(Intent.EXTRA_UID, uid);
5424        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5425        broadcastIntentLocked(null, null, intent,
5426                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5427                false, false,
5428                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5429    }
5430
5431    private void forceStopUserLocked(int userId, String reason) {
5432        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5433        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5434        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5435                | Intent.FLAG_RECEIVER_FOREGROUND);
5436        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5437        broadcastIntentLocked(null, null, intent,
5438                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5439                false, false,
5440                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5441    }
5442
5443    private final boolean killPackageProcessesLocked(String packageName, int appId,
5444            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5445            boolean doit, boolean evenPersistent, String reason) {
5446        ArrayList<ProcessRecord> procs = new ArrayList<>();
5447
5448        // Remove all processes this package may have touched: all with the
5449        // same UID (except for the system or root user), and all whose name
5450        // matches the package name.
5451        final int NP = mProcessNames.getMap().size();
5452        for (int ip=0; ip<NP; ip++) {
5453            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5454            final int NA = apps.size();
5455            for (int ia=0; ia<NA; ia++) {
5456                ProcessRecord app = apps.valueAt(ia);
5457                if (app.persistent && !evenPersistent) {
5458                    // we don't kill persistent processes
5459                    continue;
5460                }
5461                if (app.removed) {
5462                    if (doit) {
5463                        procs.add(app);
5464                    }
5465                    continue;
5466                }
5467
5468                // Skip process if it doesn't meet our oom adj requirement.
5469                if (app.setAdj < minOomAdj) {
5470                    continue;
5471                }
5472
5473                // If no package is specified, we call all processes under the
5474                // give user id.
5475                if (packageName == null) {
5476                    if (app.userId != userId) {
5477                        continue;
5478                    }
5479                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5480                        continue;
5481                    }
5482                // Package has been specified, we want to hit all processes
5483                // that match it.  We need to qualify this by the processes
5484                // that are running under the specified app and user ID.
5485                } else {
5486                    final boolean isDep = app.pkgDeps != null
5487                            && app.pkgDeps.contains(packageName);
5488                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5489                        continue;
5490                    }
5491                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5492                        continue;
5493                    }
5494                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5495                        continue;
5496                    }
5497                }
5498
5499                // Process has passed all conditions, kill it!
5500                if (!doit) {
5501                    return true;
5502                }
5503                app.removed = true;
5504                procs.add(app);
5505            }
5506        }
5507
5508        int N = procs.size();
5509        for (int i=0; i<N; i++) {
5510            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5511        }
5512        updateOomAdjLocked();
5513        return N > 0;
5514    }
5515
5516    private void cleanupDisabledPackageComponentsLocked(
5517            String packageName, int userId, String[] changedClasses) {
5518
5519        Set<String> disabledClasses = null;
5520        boolean packageDisabled = false;
5521        IPackageManager pm = AppGlobals.getPackageManager();
5522
5523        if (changedClasses == null) {
5524            // Nothing changed...
5525            return;
5526        }
5527
5528        // Determine enable/disable state of the package and its components.
5529        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5530        for (int i = changedClasses.length - 1; i >= 0; i--) {
5531            final String changedClass = changedClasses[i];
5532
5533            if (changedClass.equals(packageName)) {
5534                try {
5535                    // Entire package setting changed
5536                    enabled = pm.getApplicationEnabledSetting(packageName,
5537                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5538                } catch (Exception e) {
5539                    // No such package/component; probably racing with uninstall.  In any
5540                    // event it means we have nothing further to do here.
5541                    return;
5542                }
5543                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5544                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5545                if (packageDisabled) {
5546                    // Entire package is disabled.
5547                    // No need to continue to check component states.
5548                    disabledClasses = null;
5549                    break;
5550                }
5551            } else {
5552                try {
5553                    enabled = pm.getComponentEnabledSetting(
5554                            new ComponentName(packageName, changedClass),
5555                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5556                } catch (Exception e) {
5557                    // As above, probably racing with uninstall.
5558                    return;
5559                }
5560                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5561                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5562                    if (disabledClasses == null) {
5563                        disabledClasses = new ArraySet<>(changedClasses.length);
5564                    }
5565                    disabledClasses.add(changedClass);
5566                }
5567            }
5568        }
5569
5570        if (!packageDisabled && disabledClasses == null) {
5571            // Nothing to do here...
5572            return;
5573        }
5574
5575        // Clean-up disabled activities.
5576        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5577                packageName, disabledClasses, true, false, userId) && mBooted) {
5578            mStackSupervisor.resumeTopActivitiesLocked();
5579            mStackSupervisor.scheduleIdleLocked();
5580        }
5581
5582        // Clean-up disabled tasks
5583        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5584
5585        // Clean-up disabled services.
5586        mServices.bringDownDisabledPackageServicesLocked(
5587                packageName, disabledClasses, userId, false, true);
5588
5589        // Clean-up disabled providers.
5590        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5591        mProviderMap.collectPackageProvidersLocked(
5592                packageName, disabledClasses, true, false, userId, providers);
5593        for (int i = providers.size() - 1; i >= 0; i--) {
5594            removeDyingProviderLocked(null, providers.get(i), true);
5595        }
5596
5597        // Clean-up disabled broadcast receivers.
5598        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5599            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5600                    packageName, disabledClasses, userId, true);
5601        }
5602
5603    }
5604
5605    private final boolean forceStopPackageLocked(String packageName, int appId,
5606            boolean callerWillRestart, boolean purgeCache, boolean doit,
5607            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5608        int i;
5609
5610        if (userId == UserHandle.USER_ALL && packageName == null) {
5611            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5612        }
5613
5614        if (appId < 0 && packageName != null) {
5615            try {
5616                appId = UserHandle.getAppId(
5617                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5618            } catch (RemoteException e) {
5619            }
5620        }
5621
5622        if (doit) {
5623            if (packageName != null) {
5624                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5625                        + " user=" + userId + ": " + reason);
5626            } else {
5627                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5628            }
5629
5630            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5631            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5632                SparseArray<Long> ba = pmap.valueAt(ip);
5633                for (i = ba.size() - 1; i >= 0; i--) {
5634                    boolean remove = false;
5635                    final int entUid = ba.keyAt(i);
5636                    if (packageName != null) {
5637                        if (userId == UserHandle.USER_ALL) {
5638                            if (UserHandle.getAppId(entUid) == appId) {
5639                                remove = true;
5640                            }
5641                        } else {
5642                            if (entUid == UserHandle.getUid(userId, appId)) {
5643                                remove = true;
5644                            }
5645                        }
5646                    } else if (UserHandle.getUserId(entUid) == userId) {
5647                        remove = true;
5648                    }
5649                    if (remove) {
5650                        ba.removeAt(i);
5651                    }
5652                }
5653                if (ba.size() == 0) {
5654                    pmap.removeAt(ip);
5655                }
5656            }
5657        }
5658
5659        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5660                -100, callerWillRestart, true, doit, evenPersistent,
5661                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5662
5663        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5664                packageName, null, doit, evenPersistent, userId)) {
5665            if (!doit) {
5666                return true;
5667            }
5668            didSomething = true;
5669        }
5670
5671        if (mServices.bringDownDisabledPackageServicesLocked(
5672                packageName, null, userId, evenPersistent, doit)) {
5673            if (!doit) {
5674                return true;
5675            }
5676            didSomething = true;
5677        }
5678
5679        if (packageName == null) {
5680            // Remove all sticky broadcasts from this user.
5681            mStickyBroadcasts.remove(userId);
5682        }
5683
5684        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5685        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5686                userId, providers)) {
5687            if (!doit) {
5688                return true;
5689            }
5690            didSomething = true;
5691        }
5692        for (i = providers.size() - 1; i >= 0; i--) {
5693            removeDyingProviderLocked(null, providers.get(i), true);
5694        }
5695
5696        // Remove transient permissions granted from/to this package/user
5697        removeUriPermissionsForPackageLocked(packageName, userId, false);
5698
5699        if (doit) {
5700            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5701                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5702                        packageName, null, userId, doit);
5703            }
5704        }
5705
5706        if (packageName == null || uninstalling) {
5707            // Remove pending intents.  For now we only do this when force
5708            // stopping users, because we have some problems when doing this
5709            // for packages -- app widgets are not currently cleaned up for
5710            // such packages, so they can be left with bad pending intents.
5711            if (mIntentSenderRecords.size() > 0) {
5712                Iterator<WeakReference<PendingIntentRecord>> it
5713                        = mIntentSenderRecords.values().iterator();
5714                while (it.hasNext()) {
5715                    WeakReference<PendingIntentRecord> wpir = it.next();
5716                    if (wpir == null) {
5717                        it.remove();
5718                        continue;
5719                    }
5720                    PendingIntentRecord pir = wpir.get();
5721                    if (pir == null) {
5722                        it.remove();
5723                        continue;
5724                    }
5725                    if (packageName == null) {
5726                        // Stopping user, remove all objects for the user.
5727                        if (pir.key.userId != userId) {
5728                            // Not the same user, skip it.
5729                            continue;
5730                        }
5731                    } else {
5732                        if (UserHandle.getAppId(pir.uid) != appId) {
5733                            // Different app id, skip it.
5734                            continue;
5735                        }
5736                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5737                            // Different user, skip it.
5738                            continue;
5739                        }
5740                        if (!pir.key.packageName.equals(packageName)) {
5741                            // Different package, skip it.
5742                            continue;
5743                        }
5744                    }
5745                    if (!doit) {
5746                        return true;
5747                    }
5748                    didSomething = true;
5749                    it.remove();
5750                    pir.canceled = true;
5751                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5752                        pir.key.activity.pendingResults.remove(pir.ref);
5753                    }
5754                }
5755            }
5756        }
5757
5758        if (doit) {
5759            if (purgeCache && packageName != null) {
5760                AttributeCache ac = AttributeCache.instance();
5761                if (ac != null) {
5762                    ac.removePackage(packageName);
5763                }
5764            }
5765            if (mBooted) {
5766                mStackSupervisor.resumeTopActivitiesLocked();
5767                mStackSupervisor.scheduleIdleLocked();
5768            }
5769        }
5770
5771        return didSomething;
5772    }
5773
5774    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5775        ProcessRecord old = mProcessNames.remove(name, uid);
5776        if (old != null) {
5777            old.uidRecord.numProcs--;
5778            if (old.uidRecord.numProcs == 0) {
5779                // No more processes using this uid, tell clients it is gone.
5780                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5781                        "No more processes in " + old.uidRecord);
5782                enqueueUidChangeLocked(old.uidRecord, true);
5783                mActiveUids.remove(uid);
5784            }
5785            old.uidRecord = null;
5786        }
5787        mIsolatedProcesses.remove(uid);
5788        return old;
5789    }
5790
5791    private final void addProcessNameLocked(ProcessRecord proc) {
5792        // We shouldn't already have a process under this name, but just in case we
5793        // need to clean up whatever may be there now.
5794        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5795        if (old != null) {
5796            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5797        }
5798        UidRecord uidRec = mActiveUids.get(proc.uid);
5799        if (uidRec == null) {
5800            uidRec = new UidRecord(proc.uid);
5801            // This is the first appearance of the uid, report it now!
5802            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5803                    "Creating new process uid: " + uidRec);
5804            mActiveUids.put(proc.uid, uidRec);
5805            enqueueUidChangeLocked(uidRec, false);
5806        }
5807        proc.uidRecord = uidRec;
5808        uidRec.numProcs++;
5809        mProcessNames.put(proc.processName, proc.uid, proc);
5810        if (proc.isolated) {
5811            mIsolatedProcesses.put(proc.uid, proc);
5812        }
5813    }
5814
5815    private final boolean removeProcessLocked(ProcessRecord app,
5816            boolean callerWillRestart, boolean allowRestart, String reason) {
5817        final String name = app.processName;
5818        final int uid = app.uid;
5819        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5820            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5821
5822        removeProcessNameLocked(name, uid);
5823        if (mHeavyWeightProcess == app) {
5824            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5825                    mHeavyWeightProcess.userId, 0));
5826            mHeavyWeightProcess = null;
5827        }
5828        boolean needRestart = false;
5829        if (app.pid > 0 && app.pid != MY_PID) {
5830            int pid = app.pid;
5831            synchronized (mPidsSelfLocked) {
5832                mPidsSelfLocked.remove(pid);
5833                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5834            }
5835            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5836            if (app.isolated) {
5837                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5838            }
5839            boolean willRestart = false;
5840            if (app.persistent && !app.isolated) {
5841                if (!callerWillRestart) {
5842                    willRestart = true;
5843                } else {
5844                    needRestart = true;
5845                }
5846            }
5847            app.kill(reason, true);
5848            handleAppDiedLocked(app, willRestart, allowRestart);
5849            if (willRestart) {
5850                removeLruProcessLocked(app);
5851                addAppLocked(app.info, false, null /* ABI override */);
5852            }
5853        } else {
5854            mRemovedProcesses.add(app);
5855        }
5856
5857        return needRestart;
5858    }
5859
5860    private final void processStartTimedOutLocked(ProcessRecord app) {
5861        final int pid = app.pid;
5862        boolean gone = false;
5863        synchronized (mPidsSelfLocked) {
5864            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5865            if (knownApp != null && knownApp.thread == null) {
5866                mPidsSelfLocked.remove(pid);
5867                gone = true;
5868            }
5869        }
5870
5871        if (gone) {
5872            Slog.w(TAG, "Process " + app + " failed to attach");
5873            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5874                    pid, app.uid, app.processName);
5875            removeProcessNameLocked(app.processName, app.uid);
5876            if (mHeavyWeightProcess == app) {
5877                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5878                        mHeavyWeightProcess.userId, 0));
5879                mHeavyWeightProcess = null;
5880            }
5881            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5882            if (app.isolated) {
5883                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5884            }
5885            // Take care of any launching providers waiting for this process.
5886            checkAppInLaunchingProvidersLocked(app, true);
5887            // Take care of any services that are waiting for the process.
5888            mServices.processStartTimedOutLocked(app);
5889            app.kill("start timeout", true);
5890            removeLruProcessLocked(app);
5891            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5892                Slog.w(TAG, "Unattached app died before backup, skipping");
5893                try {
5894                    IBackupManager bm = IBackupManager.Stub.asInterface(
5895                            ServiceManager.getService(Context.BACKUP_SERVICE));
5896                    bm.agentDisconnected(app.info.packageName);
5897                } catch (RemoteException e) {
5898                    // Can't happen; the backup manager is local
5899                }
5900            }
5901            if (isPendingBroadcastProcessLocked(pid)) {
5902                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5903                skipPendingBroadcastLocked(pid);
5904            }
5905        } else {
5906            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5907        }
5908    }
5909
5910    private final boolean attachApplicationLocked(IApplicationThread thread,
5911            int pid) {
5912
5913        // Find the application record that is being attached...  either via
5914        // the pid if we are running in multiple processes, or just pull the
5915        // next app record if we are emulating process with anonymous threads.
5916        ProcessRecord app;
5917        if (pid != MY_PID && pid >= 0) {
5918            synchronized (mPidsSelfLocked) {
5919                app = mPidsSelfLocked.get(pid);
5920            }
5921        } else {
5922            app = null;
5923        }
5924
5925        if (app == null) {
5926            Slog.w(TAG, "No pending application record for pid " + pid
5927                    + " (IApplicationThread " + thread + "); dropping process");
5928            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5929            if (pid > 0 && pid != MY_PID) {
5930                Process.killProcessQuiet(pid);
5931                //TODO: Process.killProcessGroup(app.info.uid, pid);
5932            } else {
5933                try {
5934                    thread.scheduleExit();
5935                } catch (Exception e) {
5936                    // Ignore exceptions.
5937                }
5938            }
5939            return false;
5940        }
5941
5942        // If this application record is still attached to a previous
5943        // process, clean it up now.
5944        if (app.thread != null) {
5945            handleAppDiedLocked(app, true, true);
5946        }
5947
5948        // Tell the process all about itself.
5949
5950        if (DEBUG_ALL) Slog.v(
5951                TAG, "Binding process pid " + pid + " to record " + app);
5952
5953        final String processName = app.processName;
5954        try {
5955            AppDeathRecipient adr = new AppDeathRecipient(
5956                    app, pid, thread);
5957            thread.asBinder().linkToDeath(adr, 0);
5958            app.deathRecipient = adr;
5959        } catch (RemoteException e) {
5960            app.resetPackageList(mProcessStats);
5961            startProcessLocked(app, "link fail", processName);
5962            return false;
5963        }
5964
5965        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5966
5967        app.makeActive(thread, mProcessStats);
5968        app.curAdj = app.setAdj = -100;
5969        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5970        app.forcingToForeground = null;
5971        updateProcessForegroundLocked(app, false, false);
5972        app.hasShownUi = false;
5973        app.debugging = false;
5974        app.cached = false;
5975        app.killedByAm = false;
5976
5977        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5978
5979        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5980        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5981
5982        if (!normalMode) {
5983            Slog.i(TAG, "Launching preboot mode app: " + app);
5984        }
5985
5986        if (DEBUG_ALL) Slog.v(
5987            TAG, "New app record " + app
5988            + " thread=" + thread.asBinder() + " pid=" + pid);
5989        try {
5990            int testMode = IApplicationThread.DEBUG_OFF;
5991            if (mDebugApp != null && mDebugApp.equals(processName)) {
5992                testMode = mWaitForDebugger
5993                    ? IApplicationThread.DEBUG_WAIT
5994                    : IApplicationThread.DEBUG_ON;
5995                app.debugging = true;
5996                if (mDebugTransient) {
5997                    mDebugApp = mOrigDebugApp;
5998                    mWaitForDebugger = mOrigWaitForDebugger;
5999                }
6000            }
6001            String profileFile = app.instrumentationProfileFile;
6002            ParcelFileDescriptor profileFd = null;
6003            int samplingInterval = 0;
6004            boolean profileAutoStop = false;
6005            if (mProfileApp != null && mProfileApp.equals(processName)) {
6006                mProfileProc = app;
6007                profileFile = mProfileFile;
6008                profileFd = mProfileFd;
6009                samplingInterval = mSamplingInterval;
6010                profileAutoStop = mAutoStopProfiler;
6011            }
6012            boolean enableOpenGlTrace = false;
6013            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6014                enableOpenGlTrace = true;
6015                mOpenGlTraceApp = null;
6016            }
6017
6018            // If the app is being launched for restore or full backup, set it up specially
6019            boolean isRestrictedBackupMode = false;
6020            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6021                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6022                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6023                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6024            }
6025
6026            ensurePackageDexOpt(app.instrumentationInfo != null
6027                    ? app.instrumentationInfo.packageName
6028                    : app.info.packageName);
6029            if (app.instrumentationClass != null) {
6030                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6031            }
6032            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6033                    + processName + " with config " + mConfiguration);
6034            ApplicationInfo appInfo = app.instrumentationInfo != null
6035                    ? app.instrumentationInfo : app.info;
6036            app.compat = compatibilityInfoForPackageLocked(appInfo);
6037            if (profileFd != null) {
6038                profileFd = profileFd.dup();
6039            }
6040            ProfilerInfo profilerInfo = profileFile == null ? null
6041                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6042            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6043                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6044                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6045                    isRestrictedBackupMode || !normalMode, app.persistent,
6046                    new Configuration(mConfiguration), app.compat,
6047                    getCommonServicesLocked(app.isolated),
6048                    mCoreSettingsObserver.getCoreSettingsLocked());
6049            updateLruProcessLocked(app, false, null);
6050            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6051        } catch (Exception e) {
6052            // todo: Yikes!  What should we do?  For now we will try to
6053            // start another process, but that could easily get us in
6054            // an infinite loop of restarting processes...
6055            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6056
6057            app.resetPackageList(mProcessStats);
6058            app.unlinkDeathRecipient();
6059            startProcessLocked(app, "bind fail", processName);
6060            return false;
6061        }
6062
6063        // Remove this record from the list of starting applications.
6064        mPersistentStartingProcesses.remove(app);
6065        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6066                "Attach application locked removing on hold: " + app);
6067        mProcessesOnHold.remove(app);
6068
6069        boolean badApp = false;
6070        boolean didSomething = false;
6071
6072        // See if the top visible activity is waiting to run in this process...
6073        if (normalMode) {
6074            try {
6075                if (mStackSupervisor.attachApplicationLocked(app)) {
6076                    didSomething = true;
6077                }
6078            } catch (Exception e) {
6079                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6080                badApp = true;
6081            }
6082        }
6083
6084        // Find any services that should be running in this process...
6085        if (!badApp) {
6086            try {
6087                didSomething |= mServices.attachApplicationLocked(app, processName);
6088            } catch (Exception e) {
6089                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6090                badApp = true;
6091            }
6092        }
6093
6094        // Check if a next-broadcast receiver is in this process...
6095        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6096            try {
6097                didSomething |= sendPendingBroadcastsLocked(app);
6098            } catch (Exception e) {
6099                // If the app died trying to launch the receiver we declare it 'bad'
6100                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6101                badApp = true;
6102            }
6103        }
6104
6105        // Check whether the next backup agent is in this process...
6106        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6107            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6108                    "New app is backup target, launching agent for " + app);
6109            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6110            try {
6111                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6112                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6113                        mBackupTarget.backupMode);
6114            } catch (Exception e) {
6115                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6116                badApp = true;
6117            }
6118        }
6119
6120        if (badApp) {
6121            app.kill("error during init", true);
6122            handleAppDiedLocked(app, false, true);
6123            return false;
6124        }
6125
6126        if (!didSomething) {
6127            updateOomAdjLocked();
6128        }
6129
6130        return true;
6131    }
6132
6133    @Override
6134    public final void attachApplication(IApplicationThread thread) {
6135        synchronized (this) {
6136            int callingPid = Binder.getCallingPid();
6137            final long origId = Binder.clearCallingIdentity();
6138            attachApplicationLocked(thread, callingPid);
6139            Binder.restoreCallingIdentity(origId);
6140        }
6141    }
6142
6143    @Override
6144    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6145        final long origId = Binder.clearCallingIdentity();
6146        synchronized (this) {
6147            ActivityStack stack = ActivityRecord.getStackLocked(token);
6148            if (stack != null) {
6149                ActivityRecord r =
6150                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6151                if (stopProfiling) {
6152                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6153                        try {
6154                            mProfileFd.close();
6155                        } catch (IOException e) {
6156                        }
6157                        clearProfilerLocked();
6158                    }
6159                }
6160            }
6161        }
6162        Binder.restoreCallingIdentity(origId);
6163    }
6164
6165    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6166        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6167                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6168    }
6169
6170    void enableScreenAfterBoot() {
6171        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6172                SystemClock.uptimeMillis());
6173        mWindowManager.enableScreenAfterBoot();
6174
6175        synchronized (this) {
6176            updateEventDispatchingLocked();
6177        }
6178    }
6179
6180    @Override
6181    public void showBootMessage(final CharSequence msg, final boolean always) {
6182        if (Binder.getCallingUid() != Process.myUid()) {
6183            // These days only the core system can call this, so apps can't get in
6184            // the way of what we show about running them.
6185        }
6186        mWindowManager.showBootMessage(msg, always);
6187    }
6188
6189    @Override
6190    public void keyguardWaitingForActivityDrawn() {
6191        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6192        final long token = Binder.clearCallingIdentity();
6193        try {
6194            synchronized (this) {
6195                if (DEBUG_LOCKSCREEN) logLockScreen("");
6196                mWindowManager.keyguardWaitingForActivityDrawn();
6197                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6198                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6199                    updateSleepIfNeededLocked();
6200                }
6201            }
6202        } finally {
6203            Binder.restoreCallingIdentity(token);
6204        }
6205    }
6206
6207    @Override
6208    public void keyguardGoingAway(boolean disableWindowAnimations,
6209            boolean keyguardGoingToNotificationShade) {
6210        enforceNotIsolatedCaller("keyguardGoingAway");
6211        final long token = Binder.clearCallingIdentity();
6212        try {
6213            synchronized (this) {
6214                if (DEBUG_LOCKSCREEN) logLockScreen("");
6215                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6216                        keyguardGoingToNotificationShade);
6217                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6218                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6219                    updateSleepIfNeededLocked();
6220                }
6221            }
6222        } finally {
6223            Binder.restoreCallingIdentity(token);
6224        }
6225    }
6226
6227    final void finishBooting() {
6228        synchronized (this) {
6229            if (!mBootAnimationComplete) {
6230                mCallFinishBooting = true;
6231                return;
6232            }
6233            mCallFinishBooting = false;
6234        }
6235
6236        ArraySet<String> completedIsas = new ArraySet<String>();
6237        for (String abi : Build.SUPPORTED_ABIS) {
6238            Process.establishZygoteConnectionForAbi(abi);
6239            final String instructionSet = VMRuntime.getInstructionSet(abi);
6240            if (!completedIsas.contains(instructionSet)) {
6241                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6242                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6243                }
6244                completedIsas.add(instructionSet);
6245            }
6246        }
6247
6248        IntentFilter pkgFilter = new IntentFilter();
6249        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6250        pkgFilter.addDataScheme("package");
6251        mContext.registerReceiver(new BroadcastReceiver() {
6252            @Override
6253            public void onReceive(Context context, Intent intent) {
6254                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6255                if (pkgs != null) {
6256                    for (String pkg : pkgs) {
6257                        synchronized (ActivityManagerService.this) {
6258                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6259                                    0, "query restart")) {
6260                                setResultCode(Activity.RESULT_OK);
6261                                return;
6262                            }
6263                        }
6264                    }
6265                }
6266            }
6267        }, pkgFilter);
6268
6269        IntentFilter dumpheapFilter = new IntentFilter();
6270        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6271        mContext.registerReceiver(new BroadcastReceiver() {
6272            @Override
6273            public void onReceive(Context context, Intent intent) {
6274                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6275                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6276                } else {
6277                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6278                }
6279            }
6280        }, dumpheapFilter);
6281
6282        // Let system services know.
6283        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6284
6285        synchronized (this) {
6286            // Ensure that any processes we had put on hold are now started
6287            // up.
6288            final int NP = mProcessesOnHold.size();
6289            if (NP > 0) {
6290                ArrayList<ProcessRecord> procs =
6291                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6292                for (int ip=0; ip<NP; ip++) {
6293                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6294                            + procs.get(ip));
6295                    startProcessLocked(procs.get(ip), "on-hold", null);
6296                }
6297            }
6298
6299            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6300                // Start looking for apps that are abusing wake locks.
6301                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6302                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6303                // Tell anyone interested that we are done booting!
6304                SystemProperties.set("sys.boot_completed", "1");
6305
6306                // And trigger dev.bootcomplete if we are not showing encryption progress
6307                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6308                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6309                    SystemProperties.set("dev.bootcomplete", "1");
6310                }
6311                for (int i=0; i<mStartedUsers.size(); i++) {
6312                    UserStartedState uss = mStartedUsers.valueAt(i);
6313                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6314                        uss.mState = UserStartedState.STATE_RUNNING;
6315                        final int userId = mStartedUsers.keyAt(i);
6316                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6317                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6318                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6319                        broadcastIntentLocked(null, null, intent, null,
6320                                new IIntentReceiver.Stub() {
6321                                    @Override
6322                                    public void performReceive(Intent intent, int resultCode,
6323                                            String data, Bundle extras, boolean ordered,
6324                                            boolean sticky, int sendingUser) {
6325                                        synchronized (ActivityManagerService.this) {
6326                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6327                                                    true, false);
6328                                        }
6329                                    }
6330                                },
6331                                0, null, null,
6332                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6333                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6334                                userId);
6335                    }
6336                }
6337                scheduleStartProfilesLocked();
6338            }
6339        }
6340    }
6341
6342    @Override
6343    public void bootAnimationComplete() {
6344        final boolean callFinishBooting;
6345        synchronized (this) {
6346            callFinishBooting = mCallFinishBooting;
6347            mBootAnimationComplete = true;
6348        }
6349        if (callFinishBooting) {
6350            finishBooting();
6351        }
6352    }
6353
6354    final void ensureBootCompleted() {
6355        boolean booting;
6356        boolean enableScreen;
6357        synchronized (this) {
6358            booting = mBooting;
6359            mBooting = false;
6360            enableScreen = !mBooted;
6361            mBooted = true;
6362        }
6363
6364        if (booting) {
6365            finishBooting();
6366        }
6367
6368        if (enableScreen) {
6369            enableScreenAfterBoot();
6370        }
6371    }
6372
6373    @Override
6374    public final void activityResumed(IBinder token) {
6375        final long origId = Binder.clearCallingIdentity();
6376        synchronized(this) {
6377            ActivityStack stack = ActivityRecord.getStackLocked(token);
6378            if (stack != null) {
6379                ActivityRecord.activityResumedLocked(token);
6380            }
6381        }
6382        Binder.restoreCallingIdentity(origId);
6383    }
6384
6385    @Override
6386    public final void activityPaused(IBinder token) {
6387        final long origId = Binder.clearCallingIdentity();
6388        synchronized(this) {
6389            ActivityStack stack = ActivityRecord.getStackLocked(token);
6390            if (stack != null) {
6391                stack.activityPausedLocked(token, false);
6392            }
6393        }
6394        Binder.restoreCallingIdentity(origId);
6395    }
6396
6397    @Override
6398    public final void activityStopped(IBinder token, Bundle icicle,
6399            PersistableBundle persistentState, CharSequence description) {
6400        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6401
6402        // Refuse possible leaked file descriptors
6403        if (icicle != null && icicle.hasFileDescriptors()) {
6404            throw new IllegalArgumentException("File descriptors passed in Bundle");
6405        }
6406
6407        final long origId = Binder.clearCallingIdentity();
6408
6409        synchronized (this) {
6410            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6411            if (r != null) {
6412                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6413            }
6414        }
6415
6416        trimApplications();
6417
6418        Binder.restoreCallingIdentity(origId);
6419    }
6420
6421    @Override
6422    public final void activityDestroyed(IBinder token) {
6423        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6424        synchronized (this) {
6425            ActivityStack stack = ActivityRecord.getStackLocked(token);
6426            if (stack != null) {
6427                stack.activityDestroyedLocked(token, "activityDestroyed");
6428            }
6429        }
6430    }
6431
6432    @Override
6433    public final void backgroundResourcesReleased(IBinder token) {
6434        final long origId = Binder.clearCallingIdentity();
6435        try {
6436            synchronized (this) {
6437                ActivityStack stack = ActivityRecord.getStackLocked(token);
6438                if (stack != null) {
6439                    stack.backgroundResourcesReleased();
6440                }
6441            }
6442        } finally {
6443            Binder.restoreCallingIdentity(origId);
6444        }
6445    }
6446
6447    @Override
6448    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6449        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6450    }
6451
6452    @Override
6453    public final void notifyEnterAnimationComplete(IBinder token) {
6454        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6455    }
6456
6457    @Override
6458    public String getCallingPackage(IBinder token) {
6459        synchronized (this) {
6460            ActivityRecord r = getCallingRecordLocked(token);
6461            return r != null ? r.info.packageName : null;
6462        }
6463    }
6464
6465    @Override
6466    public ComponentName getCallingActivity(IBinder token) {
6467        synchronized (this) {
6468            ActivityRecord r = getCallingRecordLocked(token);
6469            return r != null ? r.intent.getComponent() : null;
6470        }
6471    }
6472
6473    private ActivityRecord getCallingRecordLocked(IBinder token) {
6474        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6475        if (r == null) {
6476            return null;
6477        }
6478        return r.resultTo;
6479    }
6480
6481    @Override
6482    public ComponentName getActivityClassForToken(IBinder token) {
6483        synchronized(this) {
6484            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6485            if (r == null) {
6486                return null;
6487            }
6488            return r.intent.getComponent();
6489        }
6490    }
6491
6492    @Override
6493    public String getPackageForToken(IBinder token) {
6494        synchronized(this) {
6495            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6496            if (r == null) {
6497                return null;
6498            }
6499            return r.packageName;
6500        }
6501    }
6502
6503    @Override
6504    public IIntentSender getIntentSender(int type,
6505            String packageName, IBinder token, String resultWho,
6506            int requestCode, Intent[] intents, String[] resolvedTypes,
6507            int flags, Bundle options, int userId) {
6508        enforceNotIsolatedCaller("getIntentSender");
6509        // Refuse possible leaked file descriptors
6510        if (intents != null) {
6511            if (intents.length < 1) {
6512                throw new IllegalArgumentException("Intents array length must be >= 1");
6513            }
6514            for (int i=0; i<intents.length; i++) {
6515                Intent intent = intents[i];
6516                if (intent != null) {
6517                    if (intent.hasFileDescriptors()) {
6518                        throw new IllegalArgumentException("File descriptors passed in Intent");
6519                    }
6520                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6521                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6522                        throw new IllegalArgumentException(
6523                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6524                    }
6525                    intents[i] = new Intent(intent);
6526                }
6527            }
6528            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6529                throw new IllegalArgumentException(
6530                        "Intent array length does not match resolvedTypes length");
6531            }
6532        }
6533        if (options != null) {
6534            if (options.hasFileDescriptors()) {
6535                throw new IllegalArgumentException("File descriptors passed in options");
6536            }
6537        }
6538
6539        synchronized(this) {
6540            int callingUid = Binder.getCallingUid();
6541            int origUserId = userId;
6542            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6543                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6544                    ALLOW_NON_FULL, "getIntentSender", null);
6545            if (origUserId == UserHandle.USER_CURRENT) {
6546                // We don't want to evaluate this until the pending intent is
6547                // actually executed.  However, we do want to always do the
6548                // security checking for it above.
6549                userId = UserHandle.USER_CURRENT;
6550            }
6551            try {
6552                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6553                    int uid = AppGlobals.getPackageManager()
6554                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6555                    if (!UserHandle.isSameApp(callingUid, uid)) {
6556                        String msg = "Permission Denial: getIntentSender() from pid="
6557                            + Binder.getCallingPid()
6558                            + ", uid=" + Binder.getCallingUid()
6559                            + ", (need uid=" + uid + ")"
6560                            + " is not allowed to send as package " + packageName;
6561                        Slog.w(TAG, msg);
6562                        throw new SecurityException(msg);
6563                    }
6564                }
6565
6566                return getIntentSenderLocked(type, packageName, callingUid, userId,
6567                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6568
6569            } catch (RemoteException e) {
6570                throw new SecurityException(e);
6571            }
6572        }
6573    }
6574
6575    IIntentSender getIntentSenderLocked(int type, String packageName,
6576            int callingUid, int userId, IBinder token, String resultWho,
6577            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6578            Bundle options) {
6579        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6580        ActivityRecord activity = null;
6581        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6582            activity = ActivityRecord.isInStackLocked(token);
6583            if (activity == null) {
6584                return null;
6585            }
6586            if (activity.finishing) {
6587                return null;
6588            }
6589        }
6590
6591        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6592        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6593        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6594        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6595                |PendingIntent.FLAG_UPDATE_CURRENT);
6596
6597        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6598                type, packageName, activity, resultWho,
6599                requestCode, intents, resolvedTypes, flags, options, userId);
6600        WeakReference<PendingIntentRecord> ref;
6601        ref = mIntentSenderRecords.get(key);
6602        PendingIntentRecord rec = ref != null ? ref.get() : null;
6603        if (rec != null) {
6604            if (!cancelCurrent) {
6605                if (updateCurrent) {
6606                    if (rec.key.requestIntent != null) {
6607                        rec.key.requestIntent.replaceExtras(intents != null ?
6608                                intents[intents.length - 1] : null);
6609                    }
6610                    if (intents != null) {
6611                        intents[intents.length-1] = rec.key.requestIntent;
6612                        rec.key.allIntents = intents;
6613                        rec.key.allResolvedTypes = resolvedTypes;
6614                    } else {
6615                        rec.key.allIntents = null;
6616                        rec.key.allResolvedTypes = null;
6617                    }
6618                }
6619                return rec;
6620            }
6621            rec.canceled = true;
6622            mIntentSenderRecords.remove(key);
6623        }
6624        if (noCreate) {
6625            return rec;
6626        }
6627        rec = new PendingIntentRecord(this, key, callingUid);
6628        mIntentSenderRecords.put(key, rec.ref);
6629        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6630            if (activity.pendingResults == null) {
6631                activity.pendingResults
6632                        = new HashSet<WeakReference<PendingIntentRecord>>();
6633            }
6634            activity.pendingResults.add(rec.ref);
6635        }
6636        return rec;
6637    }
6638
6639    @Override
6640    public void cancelIntentSender(IIntentSender sender) {
6641        if (!(sender instanceof PendingIntentRecord)) {
6642            return;
6643        }
6644        synchronized(this) {
6645            PendingIntentRecord rec = (PendingIntentRecord)sender;
6646            try {
6647                int uid = AppGlobals.getPackageManager()
6648                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6649                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6650                    String msg = "Permission Denial: cancelIntentSender() from pid="
6651                        + Binder.getCallingPid()
6652                        + ", uid=" + Binder.getCallingUid()
6653                        + " is not allowed to cancel packges "
6654                        + rec.key.packageName;
6655                    Slog.w(TAG, msg);
6656                    throw new SecurityException(msg);
6657                }
6658            } catch (RemoteException e) {
6659                throw new SecurityException(e);
6660            }
6661            cancelIntentSenderLocked(rec, true);
6662        }
6663    }
6664
6665    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6666        rec.canceled = true;
6667        mIntentSenderRecords.remove(rec.key);
6668        if (cleanActivity && rec.key.activity != null) {
6669            rec.key.activity.pendingResults.remove(rec.ref);
6670        }
6671    }
6672
6673    @Override
6674    public String getPackageForIntentSender(IIntentSender pendingResult) {
6675        if (!(pendingResult instanceof PendingIntentRecord)) {
6676            return null;
6677        }
6678        try {
6679            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6680            return res.key.packageName;
6681        } catch (ClassCastException e) {
6682        }
6683        return null;
6684    }
6685
6686    @Override
6687    public int getUidForIntentSender(IIntentSender sender) {
6688        if (sender instanceof PendingIntentRecord) {
6689            try {
6690                PendingIntentRecord res = (PendingIntentRecord)sender;
6691                return res.uid;
6692            } catch (ClassCastException e) {
6693            }
6694        }
6695        return -1;
6696    }
6697
6698    @Override
6699    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6700        if (!(pendingResult instanceof PendingIntentRecord)) {
6701            return false;
6702        }
6703        try {
6704            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6705            if (res.key.allIntents == null) {
6706                return false;
6707            }
6708            for (int i=0; i<res.key.allIntents.length; i++) {
6709                Intent intent = res.key.allIntents[i];
6710                if (intent.getPackage() != null && intent.getComponent() != null) {
6711                    return false;
6712                }
6713            }
6714            return true;
6715        } catch (ClassCastException e) {
6716        }
6717        return false;
6718    }
6719
6720    @Override
6721    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6722        if (!(pendingResult instanceof PendingIntentRecord)) {
6723            return false;
6724        }
6725        try {
6726            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6727            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6728                return true;
6729            }
6730            return false;
6731        } catch (ClassCastException e) {
6732        }
6733        return false;
6734    }
6735
6736    @Override
6737    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6738        if (!(pendingResult instanceof PendingIntentRecord)) {
6739            return null;
6740        }
6741        try {
6742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6743            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6744        } catch (ClassCastException e) {
6745        }
6746        return null;
6747    }
6748
6749    @Override
6750    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6751        if (!(pendingResult instanceof PendingIntentRecord)) {
6752            return null;
6753        }
6754        try {
6755            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6756            synchronized (this) {
6757                return getTagForIntentSenderLocked(res, prefix);
6758            }
6759        } catch (ClassCastException e) {
6760        }
6761        return null;
6762    }
6763
6764    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6765        final Intent intent = res.key.requestIntent;
6766        if (intent != null) {
6767            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6768                    || res.lastTagPrefix.equals(prefix))) {
6769                return res.lastTag;
6770            }
6771            res.lastTagPrefix = prefix;
6772            final StringBuilder sb = new StringBuilder(128);
6773            if (prefix != null) {
6774                sb.append(prefix);
6775            }
6776            if (intent.getAction() != null) {
6777                sb.append(intent.getAction());
6778            } else if (intent.getComponent() != null) {
6779                intent.getComponent().appendShortString(sb);
6780            } else {
6781                sb.append("?");
6782            }
6783            return res.lastTag = sb.toString();
6784        }
6785        return null;
6786    }
6787
6788    @Override
6789    public void setProcessLimit(int max) {
6790        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6791                "setProcessLimit()");
6792        synchronized (this) {
6793            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6794            mProcessLimitOverride = max;
6795        }
6796        trimApplications();
6797    }
6798
6799    @Override
6800    public int getProcessLimit() {
6801        synchronized (this) {
6802            return mProcessLimitOverride;
6803        }
6804    }
6805
6806    void foregroundTokenDied(ForegroundToken token) {
6807        synchronized (ActivityManagerService.this) {
6808            synchronized (mPidsSelfLocked) {
6809                ForegroundToken cur
6810                    = mForegroundProcesses.get(token.pid);
6811                if (cur != token) {
6812                    return;
6813                }
6814                mForegroundProcesses.remove(token.pid);
6815                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6816                if (pr == null) {
6817                    return;
6818                }
6819                pr.forcingToForeground = null;
6820                updateProcessForegroundLocked(pr, false, false);
6821            }
6822            updateOomAdjLocked();
6823        }
6824    }
6825
6826    @Override
6827    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6828        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6829                "setProcessForeground()");
6830        synchronized(this) {
6831            boolean changed = false;
6832
6833            synchronized (mPidsSelfLocked) {
6834                ProcessRecord pr = mPidsSelfLocked.get(pid);
6835                if (pr == null && isForeground) {
6836                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6837                    return;
6838                }
6839                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6840                if (oldToken != null) {
6841                    oldToken.token.unlinkToDeath(oldToken, 0);
6842                    mForegroundProcesses.remove(pid);
6843                    if (pr != null) {
6844                        pr.forcingToForeground = null;
6845                    }
6846                    changed = true;
6847                }
6848                if (isForeground && token != null) {
6849                    ForegroundToken newToken = new ForegroundToken() {
6850                        @Override
6851                        public void binderDied() {
6852                            foregroundTokenDied(this);
6853                        }
6854                    };
6855                    newToken.pid = pid;
6856                    newToken.token = token;
6857                    try {
6858                        token.linkToDeath(newToken, 0);
6859                        mForegroundProcesses.put(pid, newToken);
6860                        pr.forcingToForeground = token;
6861                        changed = true;
6862                    } catch (RemoteException e) {
6863                        // If the process died while doing this, we will later
6864                        // do the cleanup with the process death link.
6865                    }
6866                }
6867            }
6868
6869            if (changed) {
6870                updateOomAdjLocked();
6871            }
6872        }
6873    }
6874
6875    // =========================================================
6876    // PROCESS INFO
6877    // =========================================================
6878
6879    static class ProcessInfoService extends IProcessInfoService.Stub {
6880        final ActivityManagerService mActivityManagerService;
6881        ProcessInfoService(ActivityManagerService activityManagerService) {
6882            mActivityManagerService = activityManagerService;
6883        }
6884
6885        @Override
6886        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6887            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6888        }
6889    }
6890
6891    /**
6892     * For each PID in the given input array, write the current process state
6893     * for that process into the output array, or -1 to indicate that no
6894     * process with the given PID exists.
6895     */
6896    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6897        if (pids == null) {
6898            throw new NullPointerException("pids");
6899        } else if (states == null) {
6900            throw new NullPointerException("states");
6901        } else if (pids.length != states.length) {
6902            throw new IllegalArgumentException("input and output arrays have different lengths!");
6903        }
6904
6905        synchronized (mPidsSelfLocked) {
6906            for (int i = 0; i < pids.length; i++) {
6907                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6908                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6909                        pr.curProcState;
6910            }
6911        }
6912    }
6913
6914    // =========================================================
6915    // PERMISSIONS
6916    // =========================================================
6917
6918    static class PermissionController extends IPermissionController.Stub {
6919        ActivityManagerService mActivityManagerService;
6920        PermissionController(ActivityManagerService activityManagerService) {
6921            mActivityManagerService = activityManagerService;
6922        }
6923
6924        @Override
6925        public boolean checkPermission(String permission, int pid, int uid) {
6926            return mActivityManagerService.checkPermission(permission, pid,
6927                    uid) == PackageManager.PERMISSION_GRANTED;
6928        }
6929
6930        @Override
6931        public String[] getPackagesForUid(int uid) {
6932            return mActivityManagerService.mContext.getPackageManager()
6933                    .getPackagesForUid(uid);
6934        }
6935
6936        @Override
6937        public boolean isRuntimePermission(String permission) {
6938            try {
6939                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6940                        .getPermissionInfo(permission, 0);
6941                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6942            } catch (NameNotFoundException nnfe) {
6943                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6944            }
6945            return false;
6946        }
6947    }
6948
6949    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6950        @Override
6951        public int checkComponentPermission(String permission, int pid, int uid,
6952                int owningUid, boolean exported) {
6953            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6954                    owningUid, exported);
6955        }
6956
6957        @Override
6958        public Object getAMSLock() {
6959            return ActivityManagerService.this;
6960        }
6961    }
6962
6963    /**
6964     * This can be called with or without the global lock held.
6965     */
6966    int checkComponentPermission(String permission, int pid, int uid,
6967            int owningUid, boolean exported) {
6968        if (pid == MY_PID) {
6969            return PackageManager.PERMISSION_GRANTED;
6970        }
6971        return ActivityManager.checkComponentPermission(permission, uid,
6972                owningUid, exported);
6973    }
6974
6975    /**
6976     * As the only public entry point for permissions checking, this method
6977     * can enforce the semantic that requesting a check on a null global
6978     * permission is automatically denied.  (Internally a null permission
6979     * string is used when calling {@link #checkComponentPermission} in cases
6980     * when only uid-based security is needed.)
6981     *
6982     * This can be called with or without the global lock held.
6983     */
6984    @Override
6985    public int checkPermission(String permission, int pid, int uid) {
6986        if (permission == null) {
6987            return PackageManager.PERMISSION_DENIED;
6988        }
6989        return checkComponentPermission(permission, pid, uid, -1, true);
6990    }
6991
6992    @Override
6993    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6994        if (permission == null) {
6995            return PackageManager.PERMISSION_DENIED;
6996        }
6997
6998        // We might be performing an operation on behalf of an indirect binder
6999        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7000        // client identity accordingly before proceeding.
7001        Identity tlsIdentity = sCallerIdentity.get();
7002        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7003            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7004                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7005            uid = tlsIdentity.uid;
7006            pid = tlsIdentity.pid;
7007        }
7008
7009        return checkComponentPermission(permission, pid, uid, -1, true);
7010    }
7011
7012    /**
7013     * Binder IPC calls go through the public entry point.
7014     * This can be called with or without the global lock held.
7015     */
7016    int checkCallingPermission(String permission) {
7017        return checkPermission(permission,
7018                Binder.getCallingPid(),
7019                UserHandle.getAppId(Binder.getCallingUid()));
7020    }
7021
7022    /**
7023     * This can be called with or without the global lock held.
7024     */
7025    void enforceCallingPermission(String permission, String func) {
7026        if (checkCallingPermission(permission)
7027                == PackageManager.PERMISSION_GRANTED) {
7028            return;
7029        }
7030
7031        String msg = "Permission Denial: " + func + " from pid="
7032                + Binder.getCallingPid()
7033                + ", uid=" + Binder.getCallingUid()
7034                + " requires " + permission;
7035        Slog.w(TAG, msg);
7036        throw new SecurityException(msg);
7037    }
7038
7039    /**
7040     * Determine if UID is holding permissions required to access {@link Uri} in
7041     * the given {@link ProviderInfo}. Final permission checking is always done
7042     * in {@link ContentProvider}.
7043     */
7044    private final boolean checkHoldingPermissionsLocked(
7045            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7046        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7047                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7048        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7049            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7050                    != PERMISSION_GRANTED) {
7051                return false;
7052            }
7053        }
7054        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7055    }
7056
7057    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7058            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7059        if (pi.applicationInfo.uid == uid) {
7060            return true;
7061        } else if (!pi.exported) {
7062            return false;
7063        }
7064
7065        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7066        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7067        try {
7068            // check if target holds top-level <provider> permissions
7069            if (!readMet && pi.readPermission != null && considerUidPermissions
7070                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7071                readMet = true;
7072            }
7073            if (!writeMet && pi.writePermission != null && considerUidPermissions
7074                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7075                writeMet = true;
7076            }
7077
7078            // track if unprotected read/write is allowed; any denied
7079            // <path-permission> below removes this ability
7080            boolean allowDefaultRead = pi.readPermission == null;
7081            boolean allowDefaultWrite = pi.writePermission == null;
7082
7083            // check if target holds any <path-permission> that match uri
7084            final PathPermission[] pps = pi.pathPermissions;
7085            if (pps != null) {
7086                final String path = grantUri.uri.getPath();
7087                int i = pps.length;
7088                while (i > 0 && (!readMet || !writeMet)) {
7089                    i--;
7090                    PathPermission pp = pps[i];
7091                    if (pp.match(path)) {
7092                        if (!readMet) {
7093                            final String pprperm = pp.getReadPermission();
7094                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7095                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7096                                    + ": match=" + pp.match(path)
7097                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7098                            if (pprperm != null) {
7099                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7100                                        == PERMISSION_GRANTED) {
7101                                    readMet = true;
7102                                } else {
7103                                    allowDefaultRead = false;
7104                                }
7105                            }
7106                        }
7107                        if (!writeMet) {
7108                            final String ppwperm = pp.getWritePermission();
7109                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7110                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7111                                    + ": match=" + pp.match(path)
7112                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7113                            if (ppwperm != null) {
7114                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7115                                        == PERMISSION_GRANTED) {
7116                                    writeMet = true;
7117                                } else {
7118                                    allowDefaultWrite = false;
7119                                }
7120                            }
7121                        }
7122                    }
7123                }
7124            }
7125
7126            // grant unprotected <provider> read/write, if not blocked by
7127            // <path-permission> above
7128            if (allowDefaultRead) readMet = true;
7129            if (allowDefaultWrite) writeMet = true;
7130
7131        } catch (RemoteException e) {
7132            return false;
7133        }
7134
7135        return readMet && writeMet;
7136    }
7137
7138    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7139        ProviderInfo pi = null;
7140        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7141        if (cpr != null) {
7142            pi = cpr.info;
7143        } else {
7144            try {
7145                pi = AppGlobals.getPackageManager().resolveContentProvider(
7146                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7147            } catch (RemoteException ex) {
7148            }
7149        }
7150        return pi;
7151    }
7152
7153    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7154        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7155        if (targetUris != null) {
7156            return targetUris.get(grantUri);
7157        }
7158        return null;
7159    }
7160
7161    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7162            String targetPkg, int targetUid, GrantUri grantUri) {
7163        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7164        if (targetUris == null) {
7165            targetUris = Maps.newArrayMap();
7166            mGrantedUriPermissions.put(targetUid, targetUris);
7167        }
7168
7169        UriPermission perm = targetUris.get(grantUri);
7170        if (perm == null) {
7171            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7172            targetUris.put(grantUri, perm);
7173        }
7174
7175        return perm;
7176    }
7177
7178    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7179            final int modeFlags) {
7180        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7181        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7182                : UriPermission.STRENGTH_OWNED;
7183
7184        // Root gets to do everything.
7185        if (uid == 0) {
7186            return true;
7187        }
7188
7189        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7190        if (perms == null) return false;
7191
7192        // First look for exact match
7193        final UriPermission exactPerm = perms.get(grantUri);
7194        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7195            return true;
7196        }
7197
7198        // No exact match, look for prefixes
7199        final int N = perms.size();
7200        for (int i = 0; i < N; i++) {
7201            final UriPermission perm = perms.valueAt(i);
7202            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7203                    && perm.getStrength(modeFlags) >= minStrength) {
7204                return true;
7205            }
7206        }
7207
7208        return false;
7209    }
7210
7211    /**
7212     * @param uri This uri must NOT contain an embedded userId.
7213     * @param userId The userId in which the uri is to be resolved.
7214     */
7215    @Override
7216    public int checkUriPermission(Uri uri, int pid, int uid,
7217            final int modeFlags, int userId, IBinder callerToken) {
7218        enforceNotIsolatedCaller("checkUriPermission");
7219
7220        // Another redirected-binder-call permissions check as in
7221        // {@link checkPermissionWithToken}.
7222        Identity tlsIdentity = sCallerIdentity.get();
7223        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7224            uid = tlsIdentity.uid;
7225            pid = tlsIdentity.pid;
7226        }
7227
7228        // Our own process gets to do everything.
7229        if (pid == MY_PID) {
7230            return PackageManager.PERMISSION_GRANTED;
7231        }
7232        synchronized (this) {
7233            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7234                    ? PackageManager.PERMISSION_GRANTED
7235                    : PackageManager.PERMISSION_DENIED;
7236        }
7237    }
7238
7239    /**
7240     * Check if the targetPkg can be granted permission to access uri by
7241     * the callingUid using the given modeFlags.  Throws a security exception
7242     * if callingUid is not allowed to do this.  Returns the uid of the target
7243     * if the URI permission grant should be performed; returns -1 if it is not
7244     * needed (for example targetPkg already has permission to access the URI).
7245     * If you already know the uid of the target, you can supply it in
7246     * lastTargetUid else set that to -1.
7247     */
7248    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7249            final int modeFlags, int lastTargetUid) {
7250        if (!Intent.isAccessUriMode(modeFlags)) {
7251            return -1;
7252        }
7253
7254        if (targetPkg != null) {
7255            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7256                    "Checking grant " + targetPkg + " permission to " + grantUri);
7257        }
7258
7259        final IPackageManager pm = AppGlobals.getPackageManager();
7260
7261        // If this is not a content: uri, we can't do anything with it.
7262        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7263            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7264                    "Can't grant URI permission for non-content URI: " + grantUri);
7265            return -1;
7266        }
7267
7268        final String authority = grantUri.uri.getAuthority();
7269        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7270        if (pi == null) {
7271            Slog.w(TAG, "No content provider found for permission check: " +
7272                    grantUri.uri.toSafeString());
7273            return -1;
7274        }
7275
7276        int targetUid = lastTargetUid;
7277        if (targetUid < 0 && targetPkg != null) {
7278            try {
7279                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7280                if (targetUid < 0) {
7281                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7282                            "Can't grant URI permission no uid for: " + targetPkg);
7283                    return -1;
7284                }
7285            } catch (RemoteException ex) {
7286                return -1;
7287            }
7288        }
7289
7290        if (targetUid >= 0) {
7291            // First...  does the target actually need this permission?
7292            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7293                // No need to grant the target this permission.
7294                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7295                        "Target " + targetPkg + " already has full permission to " + grantUri);
7296                return -1;
7297            }
7298        } else {
7299            // First...  there is no target package, so can anyone access it?
7300            boolean allowed = pi.exported;
7301            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7302                if (pi.readPermission != null) {
7303                    allowed = false;
7304                }
7305            }
7306            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7307                if (pi.writePermission != null) {
7308                    allowed = false;
7309                }
7310            }
7311            if (allowed) {
7312                return -1;
7313            }
7314        }
7315
7316        /* There is a special cross user grant if:
7317         * - The target is on another user.
7318         * - Apps on the current user can access the uri without any uid permissions.
7319         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7320         * grant uri permissions.
7321         */
7322        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7323                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7324                modeFlags, false /*without considering the uid permissions*/);
7325
7326        // Second...  is the provider allowing granting of URI permissions?
7327        if (!specialCrossUserGrant) {
7328            if (!pi.grantUriPermissions) {
7329                throw new SecurityException("Provider " + pi.packageName
7330                        + "/" + pi.name
7331                        + " does not allow granting of Uri permissions (uri "
7332                        + grantUri + ")");
7333            }
7334            if (pi.uriPermissionPatterns != null) {
7335                final int N = pi.uriPermissionPatterns.length;
7336                boolean allowed = false;
7337                for (int i=0; i<N; i++) {
7338                    if (pi.uriPermissionPatterns[i] != null
7339                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7340                        allowed = true;
7341                        break;
7342                    }
7343                }
7344                if (!allowed) {
7345                    throw new SecurityException("Provider " + pi.packageName
7346                            + "/" + pi.name
7347                            + " does not allow granting of permission to path of Uri "
7348                            + grantUri);
7349                }
7350            }
7351        }
7352
7353        // Third...  does the caller itself have permission to access
7354        // this uri?
7355        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7356            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7357                // Require they hold a strong enough Uri permission
7358                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7359                    throw new SecurityException("Uid " + callingUid
7360                            + " does not have permission to uri " + grantUri);
7361                }
7362            }
7363        }
7364        return targetUid;
7365    }
7366
7367    /**
7368     * @param uri This uri must NOT contain an embedded userId.
7369     * @param userId The userId in which the uri is to be resolved.
7370     */
7371    @Override
7372    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7373            final int modeFlags, int userId) {
7374        enforceNotIsolatedCaller("checkGrantUriPermission");
7375        synchronized(this) {
7376            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7377                    new GrantUri(userId, uri, false), modeFlags, -1);
7378        }
7379    }
7380
7381    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7382            final int modeFlags, UriPermissionOwner owner) {
7383        if (!Intent.isAccessUriMode(modeFlags)) {
7384            return;
7385        }
7386
7387        // So here we are: the caller has the assumed permission
7388        // to the uri, and the target doesn't.  Let's now give this to
7389        // the target.
7390
7391        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7392                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7393
7394        final String authority = grantUri.uri.getAuthority();
7395        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7396        if (pi == null) {
7397            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7398            return;
7399        }
7400
7401        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7402            grantUri.prefix = true;
7403        }
7404        final UriPermission perm = findOrCreateUriPermissionLocked(
7405                pi.packageName, targetPkg, targetUid, grantUri);
7406        perm.grantModes(modeFlags, owner);
7407    }
7408
7409    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7410            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7411        if (targetPkg == null) {
7412            throw new NullPointerException("targetPkg");
7413        }
7414        int targetUid;
7415        final IPackageManager pm = AppGlobals.getPackageManager();
7416        try {
7417            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7418        } catch (RemoteException ex) {
7419            return;
7420        }
7421
7422        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7423                targetUid);
7424        if (targetUid < 0) {
7425            return;
7426        }
7427
7428        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7429                owner);
7430    }
7431
7432    static class NeededUriGrants extends ArrayList<GrantUri> {
7433        final String targetPkg;
7434        final int targetUid;
7435        final int flags;
7436
7437        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7438            this.targetPkg = targetPkg;
7439            this.targetUid = targetUid;
7440            this.flags = flags;
7441        }
7442    }
7443
7444    /**
7445     * Like checkGrantUriPermissionLocked, but takes an Intent.
7446     */
7447    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7448            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7449        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7450                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7451                + " clip=" + (intent != null ? intent.getClipData() : null)
7452                + " from " + intent + "; flags=0x"
7453                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7454
7455        if (targetPkg == null) {
7456            throw new NullPointerException("targetPkg");
7457        }
7458
7459        if (intent == null) {
7460            return null;
7461        }
7462        Uri data = intent.getData();
7463        ClipData clip = intent.getClipData();
7464        if (data == null && clip == null) {
7465            return null;
7466        }
7467        // Default userId for uris in the intent (if they don't specify it themselves)
7468        int contentUserHint = intent.getContentUserHint();
7469        if (contentUserHint == UserHandle.USER_CURRENT) {
7470            contentUserHint = UserHandle.getUserId(callingUid);
7471        }
7472        final IPackageManager pm = AppGlobals.getPackageManager();
7473        int targetUid;
7474        if (needed != null) {
7475            targetUid = needed.targetUid;
7476        } else {
7477            try {
7478                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7479            } catch (RemoteException ex) {
7480                return null;
7481            }
7482            if (targetUid < 0) {
7483                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7484                        "Can't grant URI permission no uid for: " + targetPkg
7485                        + " on user " + targetUserId);
7486                return null;
7487            }
7488        }
7489        if (data != null) {
7490            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7491            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7492                    targetUid);
7493            if (targetUid > 0) {
7494                if (needed == null) {
7495                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7496                }
7497                needed.add(grantUri);
7498            }
7499        }
7500        if (clip != null) {
7501            for (int i=0; i<clip.getItemCount(); i++) {
7502                Uri uri = clip.getItemAt(i).getUri();
7503                if (uri != null) {
7504                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7505                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7506                            targetUid);
7507                    if (targetUid > 0) {
7508                        if (needed == null) {
7509                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7510                        }
7511                        needed.add(grantUri);
7512                    }
7513                } else {
7514                    Intent clipIntent = clip.getItemAt(i).getIntent();
7515                    if (clipIntent != null) {
7516                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7517                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7518                        if (newNeeded != null) {
7519                            needed = newNeeded;
7520                        }
7521                    }
7522                }
7523            }
7524        }
7525
7526        return needed;
7527    }
7528
7529    /**
7530     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7531     */
7532    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7533            UriPermissionOwner owner) {
7534        if (needed != null) {
7535            for (int i=0; i<needed.size(); i++) {
7536                GrantUri grantUri = needed.get(i);
7537                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7538                        grantUri, needed.flags, owner);
7539            }
7540        }
7541    }
7542
7543    void grantUriPermissionFromIntentLocked(int callingUid,
7544            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7545        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7546                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7547        if (needed == null) {
7548            return;
7549        }
7550
7551        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7552    }
7553
7554    /**
7555     * @param uri This uri must NOT contain an embedded userId.
7556     * @param userId The userId in which the uri is to be resolved.
7557     */
7558    @Override
7559    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7560            final int modeFlags, int userId) {
7561        enforceNotIsolatedCaller("grantUriPermission");
7562        GrantUri grantUri = new GrantUri(userId, uri, false);
7563        synchronized(this) {
7564            final ProcessRecord r = getRecordForAppLocked(caller);
7565            if (r == null) {
7566                throw new SecurityException("Unable to find app for caller "
7567                        + caller
7568                        + " when granting permission to uri " + grantUri);
7569            }
7570            if (targetPkg == null) {
7571                throw new IllegalArgumentException("null target");
7572            }
7573            if (grantUri == null) {
7574                throw new IllegalArgumentException("null uri");
7575            }
7576
7577            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7578                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7579                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7580                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7581
7582            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7583                    UserHandle.getUserId(r.uid));
7584        }
7585    }
7586
7587    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7588        if (perm.modeFlags == 0) {
7589            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7590                    perm.targetUid);
7591            if (perms != null) {
7592                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7593                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7594
7595                perms.remove(perm.uri);
7596                if (perms.isEmpty()) {
7597                    mGrantedUriPermissions.remove(perm.targetUid);
7598                }
7599            }
7600        }
7601    }
7602
7603    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7604        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7605                "Revoking all granted permissions to " + grantUri);
7606
7607        final IPackageManager pm = AppGlobals.getPackageManager();
7608        final String authority = grantUri.uri.getAuthority();
7609        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7610        if (pi == null) {
7611            Slog.w(TAG, "No content provider found for permission revoke: "
7612                    + grantUri.toSafeString());
7613            return;
7614        }
7615
7616        // Does the caller have this permission on the URI?
7617        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7618            // If they don't have direct access to the URI, then revoke any
7619            // ownerless URI permissions that have been granted to them.
7620            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7621            if (perms != null) {
7622                boolean persistChanged = false;
7623                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7624                    final UriPermission perm = it.next();
7625                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7626                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7627                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7628                                "Revoking non-owned " + perm.targetUid
7629                                + " permission to " + perm.uri);
7630                        persistChanged |= perm.revokeModes(
7631                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7632                        if (perm.modeFlags == 0) {
7633                            it.remove();
7634                        }
7635                    }
7636                }
7637                if (perms.isEmpty()) {
7638                    mGrantedUriPermissions.remove(callingUid);
7639                }
7640                if (persistChanged) {
7641                    schedulePersistUriGrants();
7642                }
7643            }
7644            return;
7645        }
7646
7647        boolean persistChanged = false;
7648
7649        // Go through all of the permissions and remove any that match.
7650        int N = mGrantedUriPermissions.size();
7651        for (int i = 0; i < N; i++) {
7652            final int targetUid = mGrantedUriPermissions.keyAt(i);
7653            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7654
7655            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7656                final UriPermission perm = it.next();
7657                if (perm.uri.sourceUserId == grantUri.sourceUserId
7658                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7659                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7660                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7661                    persistChanged |= perm.revokeModes(
7662                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7663                    if (perm.modeFlags == 0) {
7664                        it.remove();
7665                    }
7666                }
7667            }
7668
7669            if (perms.isEmpty()) {
7670                mGrantedUriPermissions.remove(targetUid);
7671                N--;
7672                i--;
7673            }
7674        }
7675
7676        if (persistChanged) {
7677            schedulePersistUriGrants();
7678        }
7679    }
7680
7681    /**
7682     * @param uri This uri must NOT contain an embedded userId.
7683     * @param userId The userId in which the uri is to be resolved.
7684     */
7685    @Override
7686    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7687            int userId) {
7688        enforceNotIsolatedCaller("revokeUriPermission");
7689        synchronized(this) {
7690            final ProcessRecord r = getRecordForAppLocked(caller);
7691            if (r == null) {
7692                throw new SecurityException("Unable to find app for caller "
7693                        + caller
7694                        + " when revoking permission to uri " + uri);
7695            }
7696            if (uri == null) {
7697                Slog.w(TAG, "revokeUriPermission: null uri");
7698                return;
7699            }
7700
7701            if (!Intent.isAccessUriMode(modeFlags)) {
7702                return;
7703            }
7704
7705            final String authority = uri.getAuthority();
7706            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7707            if (pi == null) {
7708                Slog.w(TAG, "No content provider found for permission revoke: "
7709                        + uri.toSafeString());
7710                return;
7711            }
7712
7713            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7714        }
7715    }
7716
7717    /**
7718     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7719     * given package.
7720     *
7721     * @param packageName Package name to match, or {@code null} to apply to all
7722     *            packages.
7723     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7724     *            to all users.
7725     * @param persistable If persistable grants should be removed.
7726     */
7727    private void removeUriPermissionsForPackageLocked(
7728            String packageName, int userHandle, boolean persistable) {
7729        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7730            throw new IllegalArgumentException("Must narrow by either package or user");
7731        }
7732
7733        boolean persistChanged = false;
7734
7735        int N = mGrantedUriPermissions.size();
7736        for (int i = 0; i < N; i++) {
7737            final int targetUid = mGrantedUriPermissions.keyAt(i);
7738            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7739
7740            // Only inspect grants matching user
7741            if (userHandle == UserHandle.USER_ALL
7742                    || userHandle == UserHandle.getUserId(targetUid)) {
7743                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7744                    final UriPermission perm = it.next();
7745
7746                    // Only inspect grants matching package
7747                    if (packageName == null || perm.sourcePkg.equals(packageName)
7748                            || perm.targetPkg.equals(packageName)) {
7749                        persistChanged |= perm.revokeModes(persistable
7750                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7751
7752                        // Only remove when no modes remain; any persisted grants
7753                        // will keep this alive.
7754                        if (perm.modeFlags == 0) {
7755                            it.remove();
7756                        }
7757                    }
7758                }
7759
7760                if (perms.isEmpty()) {
7761                    mGrantedUriPermissions.remove(targetUid);
7762                    N--;
7763                    i--;
7764                }
7765            }
7766        }
7767
7768        if (persistChanged) {
7769            schedulePersistUriGrants();
7770        }
7771    }
7772
7773    @Override
7774    public IBinder newUriPermissionOwner(String name) {
7775        enforceNotIsolatedCaller("newUriPermissionOwner");
7776        synchronized(this) {
7777            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7778            return owner.getExternalTokenLocked();
7779        }
7780    }
7781
7782    /**
7783     * @param uri This uri must NOT contain an embedded userId.
7784     * @param sourceUserId The userId in which the uri is to be resolved.
7785     * @param targetUserId The userId of the app that receives the grant.
7786     */
7787    @Override
7788    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7789            final int modeFlags, int sourceUserId, int targetUserId) {
7790        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7791                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7792        synchronized(this) {
7793            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7794            if (owner == null) {
7795                throw new IllegalArgumentException("Unknown owner: " + token);
7796            }
7797            if (fromUid != Binder.getCallingUid()) {
7798                if (Binder.getCallingUid() != Process.myUid()) {
7799                    // Only system code can grant URI permissions on behalf
7800                    // of other users.
7801                    throw new SecurityException("nice try");
7802                }
7803            }
7804            if (targetPkg == null) {
7805                throw new IllegalArgumentException("null target");
7806            }
7807            if (uri == null) {
7808                throw new IllegalArgumentException("null uri");
7809            }
7810
7811            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7812                    modeFlags, owner, targetUserId);
7813        }
7814    }
7815
7816    /**
7817     * @param uri This uri must NOT contain an embedded userId.
7818     * @param userId The userId in which the uri is to be resolved.
7819     */
7820    @Override
7821    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7822        synchronized(this) {
7823            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7824            if (owner == null) {
7825                throw new IllegalArgumentException("Unknown owner: " + token);
7826            }
7827
7828            if (uri == null) {
7829                owner.removeUriPermissionsLocked(mode);
7830            } else {
7831                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7832            }
7833        }
7834    }
7835
7836    private void schedulePersistUriGrants() {
7837        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7838            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7839                    10 * DateUtils.SECOND_IN_MILLIS);
7840        }
7841    }
7842
7843    private void writeGrantedUriPermissions() {
7844        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7845
7846        // Snapshot permissions so we can persist without lock
7847        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7848        synchronized (this) {
7849            final int size = mGrantedUriPermissions.size();
7850            for (int i = 0; i < size; i++) {
7851                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7852                for (UriPermission perm : perms.values()) {
7853                    if (perm.persistedModeFlags != 0) {
7854                        persist.add(perm.snapshot());
7855                    }
7856                }
7857            }
7858        }
7859
7860        FileOutputStream fos = null;
7861        try {
7862            fos = mGrantFile.startWrite();
7863
7864            XmlSerializer out = new FastXmlSerializer();
7865            out.setOutput(fos, StandardCharsets.UTF_8.name());
7866            out.startDocument(null, true);
7867            out.startTag(null, TAG_URI_GRANTS);
7868            for (UriPermission.Snapshot perm : persist) {
7869                out.startTag(null, TAG_URI_GRANT);
7870                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7871                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7872                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7873                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7874                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7875                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7876                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7877                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7878                out.endTag(null, TAG_URI_GRANT);
7879            }
7880            out.endTag(null, TAG_URI_GRANTS);
7881            out.endDocument();
7882
7883            mGrantFile.finishWrite(fos);
7884        } catch (IOException e) {
7885            if (fos != null) {
7886                mGrantFile.failWrite(fos);
7887            }
7888        }
7889    }
7890
7891    private void readGrantedUriPermissionsLocked() {
7892        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7893
7894        final long now = System.currentTimeMillis();
7895
7896        FileInputStream fis = null;
7897        try {
7898            fis = mGrantFile.openRead();
7899            final XmlPullParser in = Xml.newPullParser();
7900            in.setInput(fis, StandardCharsets.UTF_8.name());
7901
7902            int type;
7903            while ((type = in.next()) != END_DOCUMENT) {
7904                final String tag = in.getName();
7905                if (type == START_TAG) {
7906                    if (TAG_URI_GRANT.equals(tag)) {
7907                        final int sourceUserId;
7908                        final int targetUserId;
7909                        final int userHandle = readIntAttribute(in,
7910                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7911                        if (userHandle != UserHandle.USER_NULL) {
7912                            // For backwards compatibility.
7913                            sourceUserId = userHandle;
7914                            targetUserId = userHandle;
7915                        } else {
7916                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7917                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7918                        }
7919                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7920                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7921                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7922                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7923                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7924                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7925
7926                        // Sanity check that provider still belongs to source package
7927                        final ProviderInfo pi = getProviderInfoLocked(
7928                                uri.getAuthority(), sourceUserId);
7929                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7930                            int targetUid = -1;
7931                            try {
7932                                targetUid = AppGlobals.getPackageManager()
7933                                        .getPackageUid(targetPkg, targetUserId);
7934                            } catch (RemoteException e) {
7935                            }
7936                            if (targetUid != -1) {
7937                                final UriPermission perm = findOrCreateUriPermissionLocked(
7938                                        sourcePkg, targetPkg, targetUid,
7939                                        new GrantUri(sourceUserId, uri, prefix));
7940                                perm.initPersistedModes(modeFlags, createdTime);
7941                            }
7942                        } else {
7943                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7944                                    + " but instead found " + pi);
7945                        }
7946                    }
7947                }
7948            }
7949        } catch (FileNotFoundException e) {
7950            // Missing grants is okay
7951        } catch (IOException e) {
7952            Slog.wtf(TAG, "Failed reading Uri grants", e);
7953        } catch (XmlPullParserException e) {
7954            Slog.wtf(TAG, "Failed reading Uri grants", e);
7955        } finally {
7956            IoUtils.closeQuietly(fis);
7957        }
7958    }
7959
7960    /**
7961     * @param uri This uri must NOT contain an embedded userId.
7962     * @param userId The userId in which the uri is to be resolved.
7963     */
7964    @Override
7965    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7966        enforceNotIsolatedCaller("takePersistableUriPermission");
7967
7968        Preconditions.checkFlagsArgument(modeFlags,
7969                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7970
7971        synchronized (this) {
7972            final int callingUid = Binder.getCallingUid();
7973            boolean persistChanged = false;
7974            GrantUri grantUri = new GrantUri(userId, uri, false);
7975
7976            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7977                    new GrantUri(userId, uri, false));
7978            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7979                    new GrantUri(userId, uri, true));
7980
7981            final boolean exactValid = (exactPerm != null)
7982                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7983            final boolean prefixValid = (prefixPerm != null)
7984                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7985
7986            if (!(exactValid || prefixValid)) {
7987                throw new SecurityException("No persistable permission grants found for UID "
7988                        + callingUid + " and Uri " + grantUri.toSafeString());
7989            }
7990
7991            if (exactValid) {
7992                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7993            }
7994            if (prefixValid) {
7995                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7996            }
7997
7998            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7999
8000            if (persistChanged) {
8001                schedulePersistUriGrants();
8002            }
8003        }
8004    }
8005
8006    /**
8007     * @param uri This uri must NOT contain an embedded userId.
8008     * @param userId The userId in which the uri is to be resolved.
8009     */
8010    @Override
8011    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8012        enforceNotIsolatedCaller("releasePersistableUriPermission");
8013
8014        Preconditions.checkFlagsArgument(modeFlags,
8015                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8016
8017        synchronized (this) {
8018            final int callingUid = Binder.getCallingUid();
8019            boolean persistChanged = false;
8020
8021            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8022                    new GrantUri(userId, uri, false));
8023            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8024                    new GrantUri(userId, uri, true));
8025            if (exactPerm == null && prefixPerm == null) {
8026                throw new SecurityException("No permission grants found for UID " + callingUid
8027                        + " and Uri " + uri.toSafeString());
8028            }
8029
8030            if (exactPerm != null) {
8031                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8032                removeUriPermissionIfNeededLocked(exactPerm);
8033            }
8034            if (prefixPerm != null) {
8035                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8036                removeUriPermissionIfNeededLocked(prefixPerm);
8037            }
8038
8039            if (persistChanged) {
8040                schedulePersistUriGrants();
8041            }
8042        }
8043    }
8044
8045    /**
8046     * Prune any older {@link UriPermission} for the given UID until outstanding
8047     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8048     *
8049     * @return if any mutations occured that require persisting.
8050     */
8051    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8052        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8053        if (perms == null) return false;
8054        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8055
8056        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8057        for (UriPermission perm : perms.values()) {
8058            if (perm.persistedModeFlags != 0) {
8059                persisted.add(perm);
8060            }
8061        }
8062
8063        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8064        if (trimCount <= 0) return false;
8065
8066        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8067        for (int i = 0; i < trimCount; i++) {
8068            final UriPermission perm = persisted.get(i);
8069
8070            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8071                    "Trimming grant created at " + perm.persistedCreateTime);
8072
8073            perm.releasePersistableModes(~0);
8074            removeUriPermissionIfNeededLocked(perm);
8075        }
8076
8077        return true;
8078    }
8079
8080    @Override
8081    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8082            String packageName, boolean incoming) {
8083        enforceNotIsolatedCaller("getPersistedUriPermissions");
8084        Preconditions.checkNotNull(packageName, "packageName");
8085
8086        final int callingUid = Binder.getCallingUid();
8087        final IPackageManager pm = AppGlobals.getPackageManager();
8088        try {
8089            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8090            if (packageUid != callingUid) {
8091                throw new SecurityException(
8092                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8093            }
8094        } catch (RemoteException e) {
8095            throw new SecurityException("Failed to verify package name ownership");
8096        }
8097
8098        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8099        synchronized (this) {
8100            if (incoming) {
8101                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8102                        callingUid);
8103                if (perms == null) {
8104                    Slog.w(TAG, "No permission grants found for " + packageName);
8105                } else {
8106                    for (UriPermission perm : perms.values()) {
8107                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8108                            result.add(perm.buildPersistedPublicApiObject());
8109                        }
8110                    }
8111                }
8112            } else {
8113                final int size = mGrantedUriPermissions.size();
8114                for (int i = 0; i < size; i++) {
8115                    final ArrayMap<GrantUri, UriPermission> perms =
8116                            mGrantedUriPermissions.valueAt(i);
8117                    for (UriPermission perm : perms.values()) {
8118                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8119                            result.add(perm.buildPersistedPublicApiObject());
8120                        }
8121                    }
8122                }
8123            }
8124        }
8125        return new ParceledListSlice<android.content.UriPermission>(result);
8126    }
8127
8128    @Override
8129    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8130        synchronized (this) {
8131            ProcessRecord app =
8132                who != null ? getRecordForAppLocked(who) : null;
8133            if (app == null) return;
8134
8135            Message msg = Message.obtain();
8136            msg.what = WAIT_FOR_DEBUGGER_MSG;
8137            msg.obj = app;
8138            msg.arg1 = waiting ? 1 : 0;
8139            mUiHandler.sendMessage(msg);
8140        }
8141    }
8142
8143    @Override
8144    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8145        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8146        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8147        outInfo.availMem = Process.getFreeMemory();
8148        outInfo.totalMem = Process.getTotalMemory();
8149        outInfo.threshold = homeAppMem;
8150        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8151        outInfo.hiddenAppThreshold = cachedAppMem;
8152        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8153                ProcessList.SERVICE_ADJ);
8154        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8155                ProcessList.VISIBLE_APP_ADJ);
8156        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8157                ProcessList.FOREGROUND_APP_ADJ);
8158    }
8159
8160    // =========================================================
8161    // TASK MANAGEMENT
8162    // =========================================================
8163
8164    @Override
8165    public List<IAppTask> getAppTasks(String callingPackage) {
8166        int callingUid = Binder.getCallingUid();
8167        long ident = Binder.clearCallingIdentity();
8168
8169        synchronized(this) {
8170            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8171            try {
8172                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8173
8174                final int N = mRecentTasks.size();
8175                for (int i = 0; i < N; i++) {
8176                    TaskRecord tr = mRecentTasks.get(i);
8177                    // Skip tasks that do not match the caller.  We don't need to verify
8178                    // callingPackage, because we are also limiting to callingUid and know
8179                    // that will limit to the correct security sandbox.
8180                    if (tr.effectiveUid != callingUid) {
8181                        continue;
8182                    }
8183                    Intent intent = tr.getBaseIntent();
8184                    if (intent == null ||
8185                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8186                        continue;
8187                    }
8188                    ActivityManager.RecentTaskInfo taskInfo =
8189                            createRecentTaskInfoFromTaskRecord(tr);
8190                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8191                    list.add(taskImpl);
8192                }
8193            } finally {
8194                Binder.restoreCallingIdentity(ident);
8195            }
8196            return list;
8197        }
8198    }
8199
8200    @Override
8201    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8202        final int callingUid = Binder.getCallingUid();
8203        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8204
8205        synchronized(this) {
8206            if (DEBUG_ALL) Slog.v(
8207                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8208
8209            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8210                    callingUid);
8211
8212            // TODO: Improve with MRU list from all ActivityStacks.
8213            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8214        }
8215
8216        return list;
8217    }
8218
8219    /**
8220     * Creates a new RecentTaskInfo from a TaskRecord.
8221     */
8222    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8223        // Update the task description to reflect any changes in the task stack
8224        tr.updateTaskDescription();
8225
8226        // Compose the recent task info
8227        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8228        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8229        rti.persistentId = tr.taskId;
8230        rti.baseIntent = new Intent(tr.getBaseIntent());
8231        rti.origActivity = tr.origActivity;
8232        rti.description = tr.lastDescription;
8233        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8234        rti.userId = tr.userId;
8235        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8236        rti.firstActiveTime = tr.firstActiveTime;
8237        rti.lastActiveTime = tr.lastActiveTime;
8238        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8239        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8240        rti.numActivities = 0;
8241
8242        ActivityRecord base = null;
8243        ActivityRecord top = null;
8244        ActivityRecord tmp;
8245
8246        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8247            tmp = tr.mActivities.get(i);
8248            if (tmp.finishing) {
8249                continue;
8250            }
8251            base = tmp;
8252            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8253                top = base;
8254            }
8255            rti.numActivities++;
8256        }
8257
8258        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8259        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8260
8261        return rti;
8262    }
8263
8264    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8265        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8266                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8267        if (!allowed) {
8268            if (checkPermission(android.Manifest.permission.GET_TASKS,
8269                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8270                // Temporary compatibility: some existing apps on the system image may
8271                // still be requesting the old permission and not switched to the new
8272                // one; if so, we'll still allow them full access.  This means we need
8273                // to see if they are holding the old permission and are a system app.
8274                try {
8275                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8276                        allowed = true;
8277                        Slog.w(TAG, caller + ": caller " + callingUid
8278                                + " is using old GET_TASKS but privileged; allowing");
8279                    }
8280                } catch (RemoteException e) {
8281                }
8282            }
8283        }
8284        if (!allowed) {
8285            Slog.w(TAG, caller + ": caller " + callingUid
8286                    + " does not hold REAL_GET_TASKS; limiting output");
8287        }
8288        return allowed;
8289    }
8290
8291    @Override
8292    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8293        final int callingUid = Binder.getCallingUid();
8294        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8295                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8296
8297        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8298        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8299        synchronized (this) {
8300            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8301                    callingUid);
8302            final boolean detailed = checkCallingPermission(
8303                    android.Manifest.permission.GET_DETAILED_TASKS)
8304                    == PackageManager.PERMISSION_GRANTED;
8305
8306            final int recentsCount = mRecentTasks.size();
8307            ArrayList<ActivityManager.RecentTaskInfo> res =
8308                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8309
8310            final Set<Integer> includedUsers;
8311            if (includeProfiles) {
8312                includedUsers = getProfileIdsLocked(userId);
8313            } else {
8314                includedUsers = new HashSet<>();
8315            }
8316            includedUsers.add(Integer.valueOf(userId));
8317
8318            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8319                TaskRecord tr = mRecentTasks.get(i);
8320                // Only add calling user or related users recent tasks
8321                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8322                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8323                    continue;
8324                }
8325
8326                // Return the entry if desired by the caller.  We always return
8327                // the first entry, because callers always expect this to be the
8328                // foreground app.  We may filter others if the caller has
8329                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8330                // we should exclude the entry.
8331
8332                if (i == 0
8333                        || withExcluded
8334                        || (tr.intent == null)
8335                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8336                                == 0)) {
8337                    if (!allowed) {
8338                        // If the caller doesn't have the GET_TASKS permission, then only
8339                        // allow them to see a small subset of tasks -- their own and home.
8340                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8341                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8342                            continue;
8343                        }
8344                    }
8345                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8346                        if (tr.stack != null && tr.stack.isHomeStack()) {
8347                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8348                                    "Skipping, home stack task: " + tr);
8349                            continue;
8350                        }
8351                    }
8352                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8353                        // Don't include auto remove tasks that are finished or finishing.
8354                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8355                                "Skipping, auto-remove without activity: " + tr);
8356                        continue;
8357                    }
8358                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8359                            && !tr.isAvailable) {
8360                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8361                                "Skipping, unavail real act: " + tr);
8362                        continue;
8363                    }
8364
8365                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8366                    if (!detailed) {
8367                        rti.baseIntent.replaceExtras((Bundle)null);
8368                    }
8369
8370                    res.add(rti);
8371                    maxNum--;
8372                }
8373            }
8374            return res;
8375        }
8376    }
8377
8378    @Override
8379    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8380        synchronized (this) {
8381            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8382                    "getTaskThumbnail()");
8383            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8384            if (tr != null) {
8385                return tr.getTaskThumbnailLocked();
8386            }
8387        }
8388        return null;
8389    }
8390
8391    @Override
8392    public int addAppTask(IBinder activityToken, Intent intent,
8393            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8394        final int callingUid = Binder.getCallingUid();
8395        final long callingIdent = Binder.clearCallingIdentity();
8396
8397        try {
8398            synchronized (this) {
8399                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8400                if (r == null) {
8401                    throw new IllegalArgumentException("Activity does not exist; token="
8402                            + activityToken);
8403                }
8404                ComponentName comp = intent.getComponent();
8405                if (comp == null) {
8406                    throw new IllegalArgumentException("Intent " + intent
8407                            + " must specify explicit component");
8408                }
8409                if (thumbnail.getWidth() != mThumbnailWidth
8410                        || thumbnail.getHeight() != mThumbnailHeight) {
8411                    throw new IllegalArgumentException("Bad thumbnail size: got "
8412                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8413                            + mThumbnailWidth + "x" + mThumbnailHeight);
8414                }
8415                if (intent.getSelector() != null) {
8416                    intent.setSelector(null);
8417                }
8418                if (intent.getSourceBounds() != null) {
8419                    intent.setSourceBounds(null);
8420                }
8421                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8422                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8423                        // The caller has added this as an auto-remove task...  that makes no
8424                        // sense, so turn off auto-remove.
8425                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8426                    }
8427                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8428                    // Must be a new task.
8429                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8430                }
8431                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8432                    mLastAddedTaskActivity = null;
8433                }
8434                ActivityInfo ainfo = mLastAddedTaskActivity;
8435                if (ainfo == null) {
8436                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8437                            comp, 0, UserHandle.getUserId(callingUid));
8438                    if (ainfo.applicationInfo.uid != callingUid) {
8439                        throw new SecurityException(
8440                                "Can't add task for another application: target uid="
8441                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8442                    }
8443                }
8444
8445                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8446                        intent, description);
8447
8448                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8449                if (trimIdx >= 0) {
8450                    // If this would have caused a trim, then we'll abort because that
8451                    // means it would be added at the end of the list but then just removed.
8452                    return INVALID_TASK_ID;
8453                }
8454
8455                final int N = mRecentTasks.size();
8456                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8457                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8458                    tr.removedFromRecents();
8459                }
8460
8461                task.inRecents = true;
8462                mRecentTasks.add(task);
8463                r.task.stack.addTask(task, false, false);
8464
8465                task.setLastThumbnail(thumbnail);
8466                task.freeLastThumbnail();
8467
8468                return task.taskId;
8469            }
8470        } finally {
8471            Binder.restoreCallingIdentity(callingIdent);
8472        }
8473    }
8474
8475    @Override
8476    public Point getAppTaskThumbnailSize() {
8477        synchronized (this) {
8478            return new Point(mThumbnailWidth,  mThumbnailHeight);
8479        }
8480    }
8481
8482    @Override
8483    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8484        synchronized (this) {
8485            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8486            if (r != null) {
8487                r.setTaskDescription(td);
8488                r.task.updateTaskDescription();
8489            }
8490        }
8491    }
8492
8493    @Override
8494    public void setTaskResizeable(int taskId, boolean resizeable) {
8495        synchronized (this) {
8496            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8497            if (task == null) {
8498                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8499                return;
8500            }
8501            if (task.mResizeable != resizeable) {
8502                task.mResizeable = resizeable;
8503                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8504                mStackSupervisor.resumeTopActivitiesLocked();
8505            }
8506        }
8507    }
8508
8509    @Override
8510    public void resizeTask(int taskId, Rect bounds) {
8511        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8512                "resizeTask()");
8513        long ident = Binder.clearCallingIdentity();
8514        try {
8515            synchronized (this) {
8516                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8517                if (task == null) {
8518                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8519                    return;
8520                }
8521                mStackSupervisor.resizeTaskLocked(task, bounds);
8522            }
8523        } finally {
8524            Binder.restoreCallingIdentity(ident);
8525        }
8526    }
8527
8528    @Override
8529    public Bitmap getTaskDescriptionIcon(String filename) {
8530        if (!FileUtils.isValidExtFilename(filename)
8531                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8532            throw new IllegalArgumentException("Bad filename: " + filename);
8533        }
8534        return mTaskPersister.getTaskDescriptionIcon(filename);
8535    }
8536
8537    @Override
8538    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8539            throws RemoteException {
8540        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8541                opts.getCustomInPlaceResId() == 0) {
8542            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8543                    "with valid animation");
8544        }
8545        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8546        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8547                opts.getCustomInPlaceResId());
8548        mWindowManager.executeAppTransition();
8549    }
8550
8551    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8552        mRecentTasks.remove(tr);
8553        tr.removedFromRecents();
8554        ComponentName component = tr.getBaseIntent().getComponent();
8555        if (component == null) {
8556            Slog.w(TAG, "No component for base intent of task: " + tr);
8557            return;
8558        }
8559
8560        // Find any running services associated with this app and stop if needed.
8561        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8562
8563        if (!killProcess) {
8564            return;
8565        }
8566
8567        // Determine if the process(es) for this task should be killed.
8568        final String pkg = component.getPackageName();
8569        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8570        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8571        for (int i = 0; i < pmap.size(); i++) {
8572
8573            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8574            for (int j = 0; j < uids.size(); j++) {
8575                ProcessRecord proc = uids.valueAt(j);
8576                if (proc.userId != tr.userId) {
8577                    // Don't kill process for a different user.
8578                    continue;
8579                }
8580                if (proc == mHomeProcess) {
8581                    // Don't kill the home process along with tasks from the same package.
8582                    continue;
8583                }
8584                if (!proc.pkgList.containsKey(pkg)) {
8585                    // Don't kill process that is not associated with this task.
8586                    continue;
8587                }
8588
8589                for (int k = 0; k < proc.activities.size(); k++) {
8590                    TaskRecord otherTask = proc.activities.get(k).task;
8591                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8592                        // Don't kill process(es) that has an activity in a different task that is
8593                        // also in recents.
8594                        return;
8595                    }
8596                }
8597
8598                if (proc.foregroundServices) {
8599                    // Don't kill process(es) with foreground service.
8600                    return;
8601                }
8602
8603                // Add process to kill list.
8604                procsToKill.add(proc);
8605            }
8606        }
8607
8608        // Kill the running processes.
8609        for (int i = 0; i < procsToKill.size(); i++) {
8610            ProcessRecord pr = procsToKill.get(i);
8611            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8612                    && pr.curReceiver == null) {
8613                pr.kill("remove task", true);
8614            } else {
8615                // We delay killing processes that are not in the background or running a receiver.
8616                pr.waitingToKill = "remove task";
8617            }
8618        }
8619    }
8620
8621    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8622        // Remove all tasks with activities in the specified package from the list of recent tasks
8623        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8624            TaskRecord tr = mRecentTasks.get(i);
8625            if (tr.userId != userId) continue;
8626
8627            ComponentName cn = tr.intent.getComponent();
8628            if (cn != null && cn.getPackageName().equals(packageName)) {
8629                // If the package name matches, remove the task.
8630                removeTaskByIdLocked(tr.taskId, true);
8631            }
8632        }
8633    }
8634
8635    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8636            int userId) {
8637
8638        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8639            TaskRecord tr = mRecentTasks.get(i);
8640            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8641                continue;
8642            }
8643
8644            ComponentName cn = tr.intent.getComponent();
8645            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8646                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8647            if (sameComponent) {
8648                removeTaskByIdLocked(tr.taskId, false);
8649            }
8650        }
8651    }
8652
8653    /**
8654     * Removes the task with the specified task id.
8655     *
8656     * @param taskId Identifier of the task to be removed.
8657     * @param killProcess Kill any process associated with the task if possible.
8658     * @return Returns true if the given task was found and removed.
8659     */
8660    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8661        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8662        if (tr != null) {
8663            tr.removeTaskActivitiesLocked();
8664            cleanUpRemovedTaskLocked(tr, killProcess);
8665            if (tr.isPersistable) {
8666                notifyTaskPersisterLocked(null, true);
8667            }
8668            return true;
8669        }
8670        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8671        return false;
8672    }
8673
8674    @Override
8675    public boolean removeTask(int taskId) {
8676        synchronized (this) {
8677            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8678                    "removeTask()");
8679            long ident = Binder.clearCallingIdentity();
8680            try {
8681                return removeTaskByIdLocked(taskId, true);
8682            } finally {
8683                Binder.restoreCallingIdentity(ident);
8684            }
8685        }
8686    }
8687
8688    /**
8689     * TODO: Add mController hook
8690     */
8691    @Override
8692    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8693        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8694
8695        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8696        synchronized(this) {
8697            moveTaskToFrontLocked(taskId, flags, options);
8698        }
8699    }
8700
8701    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8702        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8703                Binder.getCallingUid(), -1, -1, "Task to front")) {
8704            ActivityOptions.abort(options);
8705            return;
8706        }
8707        final long origId = Binder.clearCallingIdentity();
8708        try {
8709            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8710            if (task == null) {
8711                Slog.d(TAG, "Could not find task for id: "+ taskId);
8712                return;
8713            }
8714            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8715                mStackSupervisor.showLockTaskToast();
8716                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8717                return;
8718            }
8719            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8720            if (prev != null && prev.isRecentsActivity()) {
8721                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8722            }
8723            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8724        } finally {
8725            Binder.restoreCallingIdentity(origId);
8726        }
8727        ActivityOptions.abort(options);
8728    }
8729
8730    /**
8731     * Moves an activity, and all of the other activities within the same task, to the bottom
8732     * of the history stack.  The activity's order within the task is unchanged.
8733     *
8734     * @param token A reference to the activity we wish to move
8735     * @param nonRoot If false then this only works if the activity is the root
8736     *                of a task; if true it will work for any activity in a task.
8737     * @return Returns true if the move completed, false if not.
8738     */
8739    @Override
8740    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8741        enforceNotIsolatedCaller("moveActivityTaskToBack");
8742        synchronized(this) {
8743            final long origId = Binder.clearCallingIdentity();
8744            try {
8745                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8746                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8747                if (task != null) {
8748                    if (mStackSupervisor.isLockedTask(task)) {
8749                        mStackSupervisor.showLockTaskToast();
8750                        return false;
8751                    }
8752                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8753                }
8754            } finally {
8755                Binder.restoreCallingIdentity(origId);
8756            }
8757        }
8758        return false;
8759    }
8760
8761    @Override
8762    public void moveTaskBackwards(int task) {
8763        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8764                "moveTaskBackwards()");
8765
8766        synchronized(this) {
8767            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8768                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8769                return;
8770            }
8771            final long origId = Binder.clearCallingIdentity();
8772            moveTaskBackwardsLocked(task);
8773            Binder.restoreCallingIdentity(origId);
8774        }
8775    }
8776
8777    private final void moveTaskBackwardsLocked(int task) {
8778        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8779    }
8780
8781    @Override
8782    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8783            IActivityContainerCallback callback) throws RemoteException {
8784        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8785                "createActivityContainer()");
8786        synchronized (this) {
8787            if (parentActivityToken == null) {
8788                throw new IllegalArgumentException("parent token must not be null");
8789            }
8790            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8791            if (r == null) {
8792                return null;
8793            }
8794            if (callback == null) {
8795                throw new IllegalArgumentException("callback must not be null");
8796            }
8797            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8798        }
8799    }
8800
8801    @Override
8802    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8803        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8804                "deleteActivityContainer()");
8805        synchronized (this) {
8806            mStackSupervisor.deleteActivityContainer(container);
8807        }
8808    }
8809
8810    @Override
8811    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8812        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8813                "createStackOnDisplay()");
8814        synchronized (this) {
8815            final int stackId = mStackSupervisor.getNextStackId();
8816            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8817            if (stack == null) {
8818                return null;
8819            }
8820            return stack.mActivityContainer;
8821        }
8822    }
8823
8824    @Override
8825    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8826        synchronized (this) {
8827            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8828            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8829                return stack.mActivityContainer.getDisplayId();
8830            }
8831            return Display.DEFAULT_DISPLAY;
8832        }
8833    }
8834
8835    @Override
8836    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8837        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8838                "moveTaskToStack()");
8839        if (stackId == HOME_STACK_ID) {
8840            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8841                    new RuntimeException("here").fillInStackTrace());
8842        }
8843        synchronized (this) {
8844            long ident = Binder.clearCallingIdentity();
8845            try {
8846                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8847                        + " to stackId=" + stackId + " toTop=" + toTop);
8848                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8849            } finally {
8850                Binder.restoreCallingIdentity(ident);
8851            }
8852        }
8853    }
8854
8855    @Override
8856    public void resizeStack(int stackId, Rect bounds) {
8857        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8858                "resizeStack()");
8859        long ident = Binder.clearCallingIdentity();
8860        try {
8861            synchronized (this) {
8862                mStackSupervisor.resizeStackLocked(stackId, bounds);
8863            }
8864        } finally {
8865            Binder.restoreCallingIdentity(ident);
8866        }
8867    }
8868
8869    @Override
8870    public List<StackInfo> getAllStackInfos() {
8871        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8872                "getAllStackInfos()");
8873        long ident = Binder.clearCallingIdentity();
8874        try {
8875            synchronized (this) {
8876                return mStackSupervisor.getAllStackInfosLocked();
8877            }
8878        } finally {
8879            Binder.restoreCallingIdentity(ident);
8880        }
8881    }
8882
8883    @Override
8884    public StackInfo getStackInfo(int stackId) {
8885        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8886                "getStackInfo()");
8887        long ident = Binder.clearCallingIdentity();
8888        try {
8889            synchronized (this) {
8890                return mStackSupervisor.getStackInfoLocked(stackId);
8891            }
8892        } finally {
8893            Binder.restoreCallingIdentity(ident);
8894        }
8895    }
8896
8897    @Override
8898    public boolean isInHomeStack(int taskId) {
8899        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8900                "getStackInfo()");
8901        long ident = Binder.clearCallingIdentity();
8902        try {
8903            synchronized (this) {
8904                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8905                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8906            }
8907        } finally {
8908            Binder.restoreCallingIdentity(ident);
8909        }
8910    }
8911
8912    @Override
8913    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8914        synchronized(this) {
8915            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8916        }
8917    }
8918
8919    @Override
8920    public void updateDeviceOwner(String packageName) {
8921        final int callingUid = Binder.getCallingUid();
8922        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8923            throw new SecurityException("updateDeviceOwner called from non-system process");
8924        }
8925        synchronized (this) {
8926            mDeviceOwnerName = packageName;
8927        }
8928    }
8929
8930    @Override
8931    public void updateLockTaskPackages(int userId, String[] packages) {
8932        final int callingUid = Binder.getCallingUid();
8933        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8934            throw new SecurityException("updateLockTaskPackage called from non-system process");
8935        }
8936        synchronized (this) {
8937            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8938                    Arrays.toString(packages));
8939            mLockTaskPackages.put(userId, packages);
8940            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8941        }
8942    }
8943
8944
8945    void startLockTaskModeLocked(TaskRecord task) {
8946        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8947        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8948            return;
8949        }
8950
8951        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8952        // is initiated by system after the pinning request was shown and locked mode is initiated
8953        // by an authorized app directly
8954        final int callingUid = Binder.getCallingUid();
8955        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8956        long ident = Binder.clearCallingIdentity();
8957        try {
8958            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8959            if (!isSystemInitiated) {
8960                task.mLockTaskUid = callingUid;
8961                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8962                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8963                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8964                    StatusBarManagerInternal statusBarManager =
8965                            LocalServices.getService(StatusBarManagerInternal.class);
8966                    if (statusBarManager != null) {
8967                        statusBarManager.showScreenPinningRequest();
8968                    }
8969                    return;
8970                }
8971
8972                if (stack == null || task != stack.topTask()) {
8973                    throw new IllegalArgumentException("Invalid task, not in foreground");
8974                }
8975            }
8976            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8977                    "Locking fully");
8978            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8979                    ActivityManager.LOCK_TASK_MODE_PINNED :
8980                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8981                    "startLockTask", true);
8982        } finally {
8983            Binder.restoreCallingIdentity(ident);
8984        }
8985    }
8986
8987    @Override
8988    public void startLockTaskMode(int taskId) {
8989        synchronized (this) {
8990            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8991            if (task != null) {
8992                startLockTaskModeLocked(task);
8993            }
8994        }
8995    }
8996
8997    @Override
8998    public void startLockTaskMode(IBinder token) {
8999        synchronized (this) {
9000            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9001            if (r == null) {
9002                return;
9003            }
9004            final TaskRecord task = r.task;
9005            if (task != null) {
9006                startLockTaskModeLocked(task);
9007            }
9008        }
9009    }
9010
9011    @Override
9012    public void startLockTaskModeOnCurrent() throws RemoteException {
9013        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9014                "startLockTaskModeOnCurrent");
9015        long ident = Binder.clearCallingIdentity();
9016        try {
9017            synchronized (this) {
9018                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9019                if (r != null) {
9020                    startLockTaskModeLocked(r.task);
9021                }
9022            }
9023        } finally {
9024            Binder.restoreCallingIdentity(ident);
9025        }
9026    }
9027
9028    @Override
9029    public void stopLockTaskMode() {
9030        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9031        if (lockTask == null) {
9032            // Our work here is done.
9033            return;
9034        }
9035
9036        final int callingUid = Binder.getCallingUid();
9037        final int lockTaskUid = lockTask.mLockTaskUid;
9038        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9039        // It is possible lockTaskMode was started by the system process because
9040        // android:lockTaskMode is set to a locking value in the application manifest instead of
9041        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9042        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9043        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9044                callingUid != lockTaskUid
9045                && (lockTaskUid != 0
9046                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9047            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9048                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9049        }
9050
9051        long ident = Binder.clearCallingIdentity();
9052        try {
9053            Log.d(TAG, "stopLockTaskMode");
9054            // Stop lock task
9055            synchronized (this) {
9056                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9057                        "stopLockTask", true);
9058            }
9059        } finally {
9060            Binder.restoreCallingIdentity(ident);
9061        }
9062    }
9063
9064    @Override
9065    public void stopLockTaskModeOnCurrent() throws RemoteException {
9066        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9067                "stopLockTaskModeOnCurrent");
9068        long ident = Binder.clearCallingIdentity();
9069        try {
9070            stopLockTaskMode();
9071        } finally {
9072            Binder.restoreCallingIdentity(ident);
9073        }
9074    }
9075
9076    @Override
9077    public boolean isInLockTaskMode() {
9078        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9079    }
9080
9081    @Override
9082    public int getLockTaskModeState() {
9083        synchronized (this) {
9084            return mStackSupervisor.getLockTaskModeState();
9085        }
9086    }
9087
9088    @Override
9089    public void showLockTaskEscapeMessage(IBinder token) {
9090        synchronized (this) {
9091            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9092            if (r == null) {
9093                return;
9094            }
9095            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9096        }
9097    }
9098
9099    // =========================================================
9100    // CONTENT PROVIDERS
9101    // =========================================================
9102
9103    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9104        List<ProviderInfo> providers = null;
9105        try {
9106            providers = AppGlobals.getPackageManager().
9107                queryContentProviders(app.processName, app.uid,
9108                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9109        } catch (RemoteException ex) {
9110        }
9111        if (DEBUG_MU) Slog.v(TAG_MU,
9112                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9113        int userId = app.userId;
9114        if (providers != null) {
9115            int N = providers.size();
9116            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9117            for (int i=0; i<N; i++) {
9118                ProviderInfo cpi =
9119                    (ProviderInfo)providers.get(i);
9120                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9121                        cpi.name, cpi.flags);
9122                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9123                    // This is a singleton provider, but a user besides the
9124                    // default user is asking to initialize a process it runs
9125                    // in...  well, no, it doesn't actually run in this process,
9126                    // it runs in the process of the default user.  Get rid of it.
9127                    providers.remove(i);
9128                    N--;
9129                    i--;
9130                    continue;
9131                }
9132
9133                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9134                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9135                if (cpr == null) {
9136                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9137                    mProviderMap.putProviderByClass(comp, cpr);
9138                }
9139                if (DEBUG_MU) Slog.v(TAG_MU,
9140                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9141                app.pubProviders.put(cpi.name, cpr);
9142                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9143                    // Don't add this if it is a platform component that is marked
9144                    // to run in multiple processes, because this is actually
9145                    // part of the framework so doesn't make sense to track as a
9146                    // separate apk in the process.
9147                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9148                            mProcessStats);
9149                }
9150                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9151            }
9152        }
9153        return providers;
9154    }
9155
9156    /**
9157     * Check if {@link ProcessRecord} has a possible chance at accessing the
9158     * given {@link ProviderInfo}. Final permission checking is always done
9159     * in {@link ContentProvider}.
9160     */
9161    private final String checkContentProviderPermissionLocked(
9162            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9163        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9164        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9165        boolean checkedGrants = false;
9166        if (checkUser) {
9167            // Looking for cross-user grants before enforcing the typical cross-users permissions
9168            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9169            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9170                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9171                    return null;
9172                }
9173                checkedGrants = true;
9174            }
9175            userId = handleIncomingUser(callingPid, callingUid, userId,
9176                    false, ALLOW_NON_FULL,
9177                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9178            if (userId != tmpTargetUserId) {
9179                // When we actually went to determine the final targer user ID, this ended
9180                // up different than our initial check for the authority.  This is because
9181                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9182                // SELF.  So we need to re-check the grants again.
9183                checkedGrants = false;
9184            }
9185        }
9186        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9187                cpi.applicationInfo.uid, cpi.exported)
9188                == PackageManager.PERMISSION_GRANTED) {
9189            return null;
9190        }
9191        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9192                cpi.applicationInfo.uid, cpi.exported)
9193                == PackageManager.PERMISSION_GRANTED) {
9194            return null;
9195        }
9196
9197        PathPermission[] pps = cpi.pathPermissions;
9198        if (pps != null) {
9199            int i = pps.length;
9200            while (i > 0) {
9201                i--;
9202                PathPermission pp = pps[i];
9203                String pprperm = pp.getReadPermission();
9204                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9205                        cpi.applicationInfo.uid, cpi.exported)
9206                        == PackageManager.PERMISSION_GRANTED) {
9207                    return null;
9208                }
9209                String ppwperm = pp.getWritePermission();
9210                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9211                        cpi.applicationInfo.uid, cpi.exported)
9212                        == PackageManager.PERMISSION_GRANTED) {
9213                    return null;
9214                }
9215            }
9216        }
9217        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9218            return null;
9219        }
9220
9221        String msg;
9222        if (!cpi.exported) {
9223            msg = "Permission Denial: opening provider " + cpi.name
9224                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9225                    + ", uid=" + callingUid + ") that is not exported from uid "
9226                    + cpi.applicationInfo.uid;
9227        } else {
9228            msg = "Permission Denial: opening provider " + cpi.name
9229                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9230                    + ", uid=" + callingUid + ") requires "
9231                    + cpi.readPermission + " or " + cpi.writePermission;
9232        }
9233        Slog.w(TAG, msg);
9234        return msg;
9235    }
9236
9237    /**
9238     * Returns if the ContentProvider has granted a uri to callingUid
9239     */
9240    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9241        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9242        if (perms != null) {
9243            for (int i=perms.size()-1; i>=0; i--) {
9244                GrantUri grantUri = perms.keyAt(i);
9245                if (grantUri.sourceUserId == userId || !checkUser) {
9246                    if (matchesProvider(grantUri.uri, cpi)) {
9247                        return true;
9248                    }
9249                }
9250            }
9251        }
9252        return false;
9253    }
9254
9255    /**
9256     * Returns true if the uri authority is one of the authorities specified in the provider.
9257     */
9258    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9259        String uriAuth = uri.getAuthority();
9260        String cpiAuth = cpi.authority;
9261        if (cpiAuth.indexOf(';') == -1) {
9262            return cpiAuth.equals(uriAuth);
9263        }
9264        String[] cpiAuths = cpiAuth.split(";");
9265        int length = cpiAuths.length;
9266        for (int i = 0; i < length; i++) {
9267            if (cpiAuths[i].equals(uriAuth)) return true;
9268        }
9269        return false;
9270    }
9271
9272    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9273            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9274        if (r != null) {
9275            for (int i=0; i<r.conProviders.size(); i++) {
9276                ContentProviderConnection conn = r.conProviders.get(i);
9277                if (conn.provider == cpr) {
9278                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9279                            "Adding provider requested by "
9280                            + r.processName + " from process "
9281                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9282                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9283                    if (stable) {
9284                        conn.stableCount++;
9285                        conn.numStableIncs++;
9286                    } else {
9287                        conn.unstableCount++;
9288                        conn.numUnstableIncs++;
9289                    }
9290                    return conn;
9291                }
9292            }
9293            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9294            if (stable) {
9295                conn.stableCount = 1;
9296                conn.numStableIncs = 1;
9297            } else {
9298                conn.unstableCount = 1;
9299                conn.numUnstableIncs = 1;
9300            }
9301            cpr.connections.add(conn);
9302            r.conProviders.add(conn);
9303            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9304            return conn;
9305        }
9306        cpr.addExternalProcessHandleLocked(externalProcessToken);
9307        return null;
9308    }
9309
9310    boolean decProviderCountLocked(ContentProviderConnection conn,
9311            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9312        if (conn != null) {
9313            cpr = conn.provider;
9314            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9315                    "Removing provider requested by "
9316                    + conn.client.processName + " from process "
9317                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9318                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9319            if (stable) {
9320                conn.stableCount--;
9321            } else {
9322                conn.unstableCount--;
9323            }
9324            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9325                cpr.connections.remove(conn);
9326                conn.client.conProviders.remove(conn);
9327                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9328                return true;
9329            }
9330            return false;
9331        }
9332        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9333        return false;
9334    }
9335
9336    private void checkTime(long startTime, String where) {
9337        long now = SystemClock.elapsedRealtime();
9338        if ((now-startTime) > 1000) {
9339            // If we are taking more than a second, log about it.
9340            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9341        }
9342    }
9343
9344    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9345            String name, IBinder token, boolean stable, int userId) {
9346        ContentProviderRecord cpr;
9347        ContentProviderConnection conn = null;
9348        ProviderInfo cpi = null;
9349
9350        synchronized(this) {
9351            long startTime = SystemClock.elapsedRealtime();
9352
9353            ProcessRecord r = null;
9354            if (caller != null) {
9355                r = getRecordForAppLocked(caller);
9356                if (r == null) {
9357                    throw new SecurityException(
9358                            "Unable to find app for caller " + caller
9359                          + " (pid=" + Binder.getCallingPid()
9360                          + ") when getting content provider " + name);
9361                }
9362            }
9363
9364            boolean checkCrossUser = true;
9365
9366            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9367
9368            // First check if this content provider has been published...
9369            cpr = mProviderMap.getProviderByName(name, userId);
9370            // If that didn't work, check if it exists for user 0 and then
9371            // verify that it's a singleton provider before using it.
9372            if (cpr == null && userId != UserHandle.USER_OWNER) {
9373                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9374                if (cpr != null) {
9375                    cpi = cpr.info;
9376                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9377                            cpi.name, cpi.flags)
9378                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9379                        userId = UserHandle.USER_OWNER;
9380                        checkCrossUser = false;
9381                    } else {
9382                        cpr = null;
9383                        cpi = null;
9384                    }
9385                }
9386            }
9387
9388            boolean providerRunning = cpr != null;
9389            if (providerRunning) {
9390                cpi = cpr.info;
9391                String msg;
9392                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9393                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9394                        != null) {
9395                    throw new SecurityException(msg);
9396                }
9397                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9398
9399                if (r != null && cpr.canRunHere(r)) {
9400                    // This provider has been published or is in the process
9401                    // of being published...  but it is also allowed to run
9402                    // in the caller's process, so don't make a connection
9403                    // and just let the caller instantiate its own instance.
9404                    ContentProviderHolder holder = cpr.newHolder(null);
9405                    // don't give caller the provider object, it needs
9406                    // to make its own.
9407                    holder.provider = null;
9408                    return holder;
9409                }
9410
9411                final long origId = Binder.clearCallingIdentity();
9412
9413                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9414
9415                // In this case the provider instance already exists, so we can
9416                // return it right away.
9417                conn = incProviderCountLocked(r, cpr, token, stable);
9418                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9419                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9420                        // If this is a perceptible app accessing the provider,
9421                        // make sure to count it as being accessed and thus
9422                        // back up on the LRU list.  This is good because
9423                        // content providers are often expensive to start.
9424                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9425                        updateLruProcessLocked(cpr.proc, false, null);
9426                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9427                    }
9428                }
9429
9430                if (cpr.proc != null) {
9431                    if (false) {
9432                        if (cpr.name.flattenToShortString().equals(
9433                                "com.android.providers.calendar/.CalendarProvider2")) {
9434                            Slog.v(TAG, "****************** KILLING "
9435                                + cpr.name.flattenToShortString());
9436                            Process.killProcess(cpr.proc.pid);
9437                        }
9438                    }
9439                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9440                    boolean success = updateOomAdjLocked(cpr.proc);
9441                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9442                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9443                    // NOTE: there is still a race here where a signal could be
9444                    // pending on the process even though we managed to update its
9445                    // adj level.  Not sure what to do about this, but at least
9446                    // the race is now smaller.
9447                    if (!success) {
9448                        // Uh oh...  it looks like the provider's process
9449                        // has been killed on us.  We need to wait for a new
9450                        // process to be started, and make sure its death
9451                        // doesn't kill our process.
9452                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9453                                + " is crashing; detaching " + r);
9454                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9455                        checkTime(startTime, "getContentProviderImpl: before appDied");
9456                        appDiedLocked(cpr.proc);
9457                        checkTime(startTime, "getContentProviderImpl: after appDied");
9458                        if (!lastRef) {
9459                            // This wasn't the last ref our process had on
9460                            // the provider...  we have now been killed, bail.
9461                            return null;
9462                        }
9463                        providerRunning = false;
9464                        conn = null;
9465                    }
9466                }
9467
9468                Binder.restoreCallingIdentity(origId);
9469            }
9470
9471            boolean singleton;
9472            if (!providerRunning) {
9473                try {
9474                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9475                    cpi = AppGlobals.getPackageManager().
9476                        resolveContentProvider(name,
9477                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9478                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9479                } catch (RemoteException ex) {
9480                }
9481                if (cpi == null) {
9482                    return null;
9483                }
9484                // If the provider is a singleton AND
9485                // (it's a call within the same user || the provider is a
9486                // privileged app)
9487                // Then allow connecting to the singleton provider
9488                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9489                        cpi.name, cpi.flags)
9490                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9491                if (singleton) {
9492                    userId = UserHandle.USER_OWNER;
9493                }
9494                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9495                checkTime(startTime, "getContentProviderImpl: got app info for user");
9496
9497                String msg;
9498                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9499                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9500                        != null) {
9501                    throw new SecurityException(msg);
9502                }
9503                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9504
9505                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9506                        && !cpi.processName.equals("system")) {
9507                    // If this content provider does not run in the system
9508                    // process, and the system is not yet ready to run other
9509                    // processes, then fail fast instead of hanging.
9510                    throw new IllegalArgumentException(
9511                            "Attempt to launch content provider before system ready");
9512                }
9513
9514                // Make sure that the user who owns this provider is running.  If not,
9515                // we don't want to allow it to run.
9516                if (!isUserRunningLocked(userId, false)) {
9517                    Slog.w(TAG, "Unable to launch app "
9518                            + cpi.applicationInfo.packageName + "/"
9519                            + cpi.applicationInfo.uid + " for provider "
9520                            + name + ": user " + userId + " is stopped");
9521                    return null;
9522                }
9523
9524                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9525                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9526                cpr = mProviderMap.getProviderByClass(comp, userId);
9527                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9528                final boolean firstClass = cpr == null;
9529                if (firstClass) {
9530                    final long ident = Binder.clearCallingIdentity();
9531                    try {
9532                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9533                        ApplicationInfo ai =
9534                            AppGlobals.getPackageManager().
9535                                getApplicationInfo(
9536                                        cpi.applicationInfo.packageName,
9537                                        STOCK_PM_FLAGS, userId);
9538                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9539                        if (ai == null) {
9540                            Slog.w(TAG, "No package info for content provider "
9541                                    + cpi.name);
9542                            return null;
9543                        }
9544                        ai = getAppInfoForUser(ai, userId);
9545                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9546                    } catch (RemoteException ex) {
9547                        // pm is in same process, this will never happen.
9548                    } finally {
9549                        Binder.restoreCallingIdentity(ident);
9550                    }
9551                }
9552
9553                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9554
9555                if (r != null && cpr.canRunHere(r)) {
9556                    // If this is a multiprocess provider, then just return its
9557                    // info and allow the caller to instantiate it.  Only do
9558                    // this if the provider is the same user as the caller's
9559                    // process, or can run as root (so can be in any process).
9560                    return cpr.newHolder(null);
9561                }
9562
9563                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9564                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9565                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9566
9567                // This is single process, and our app is now connecting to it.
9568                // See if we are already in the process of launching this
9569                // provider.
9570                final int N = mLaunchingProviders.size();
9571                int i;
9572                for (i = 0; i < N; i++) {
9573                    if (mLaunchingProviders.get(i) == cpr) {
9574                        break;
9575                    }
9576                }
9577
9578                // If the provider is not already being launched, then get it
9579                // started.
9580                if (i >= N) {
9581                    final long origId = Binder.clearCallingIdentity();
9582
9583                    try {
9584                        // Content provider is now in use, its package can't be stopped.
9585                        try {
9586                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9587                            AppGlobals.getPackageManager().setPackageStoppedState(
9588                                    cpr.appInfo.packageName, false, userId);
9589                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9590                        } catch (RemoteException e) {
9591                        } catch (IllegalArgumentException e) {
9592                            Slog.w(TAG, "Failed trying to unstop package "
9593                                    + cpr.appInfo.packageName + ": " + e);
9594                        }
9595
9596                        // Use existing process if already started
9597                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9598                        ProcessRecord proc = getProcessRecordLocked(
9599                                cpi.processName, cpr.appInfo.uid, false);
9600                        if (proc != null && proc.thread != null) {
9601                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9602                                    "Installing in existing process " + proc);
9603                            if (!proc.pubProviders.containsKey(cpi.name)) {
9604                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9605                                proc.pubProviders.put(cpi.name, cpr);
9606                                try {
9607                                    proc.thread.scheduleInstallProvider(cpi);
9608                                } catch (RemoteException e) {
9609                                }
9610                            }
9611                        } else {
9612                            checkTime(startTime, "getContentProviderImpl: before start process");
9613                            proc = startProcessLocked(cpi.processName,
9614                                    cpr.appInfo, false, 0, "content provider",
9615                                    new ComponentName(cpi.applicationInfo.packageName,
9616                                            cpi.name), false, false, false);
9617                            checkTime(startTime, "getContentProviderImpl: after start process");
9618                            if (proc == null) {
9619                                Slog.w(TAG, "Unable to launch app "
9620                                        + cpi.applicationInfo.packageName + "/"
9621                                        + cpi.applicationInfo.uid + " for provider "
9622                                        + name + ": process is bad");
9623                                return null;
9624                            }
9625                        }
9626                        cpr.launchingApp = proc;
9627                        mLaunchingProviders.add(cpr);
9628                    } finally {
9629                        Binder.restoreCallingIdentity(origId);
9630                    }
9631                }
9632
9633                checkTime(startTime, "getContentProviderImpl: updating data structures");
9634
9635                // Make sure the provider is published (the same provider class
9636                // may be published under multiple names).
9637                if (firstClass) {
9638                    mProviderMap.putProviderByClass(comp, cpr);
9639                }
9640
9641                mProviderMap.putProviderByName(name, cpr);
9642                conn = incProviderCountLocked(r, cpr, token, stable);
9643                if (conn != null) {
9644                    conn.waiting = true;
9645                }
9646            }
9647            checkTime(startTime, "getContentProviderImpl: done!");
9648        }
9649
9650        // Wait for the provider to be published...
9651        synchronized (cpr) {
9652            while (cpr.provider == null) {
9653                if (cpr.launchingApp == null) {
9654                    Slog.w(TAG, "Unable to launch app "
9655                            + cpi.applicationInfo.packageName + "/"
9656                            + cpi.applicationInfo.uid + " for provider "
9657                            + name + ": launching app became null");
9658                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9659                            UserHandle.getUserId(cpi.applicationInfo.uid),
9660                            cpi.applicationInfo.packageName,
9661                            cpi.applicationInfo.uid, name);
9662                    return null;
9663                }
9664                try {
9665                    if (DEBUG_MU) Slog.v(TAG_MU,
9666                            "Waiting to start provider " + cpr
9667                            + " launchingApp=" + cpr.launchingApp);
9668                    if (conn != null) {
9669                        conn.waiting = true;
9670                    }
9671                    cpr.wait();
9672                } catch (InterruptedException ex) {
9673                } finally {
9674                    if (conn != null) {
9675                        conn.waiting = false;
9676                    }
9677                }
9678            }
9679        }
9680        return cpr != null ? cpr.newHolder(conn) : null;
9681    }
9682
9683    @Override
9684    public final ContentProviderHolder getContentProvider(
9685            IApplicationThread caller, String name, int userId, boolean stable) {
9686        enforceNotIsolatedCaller("getContentProvider");
9687        if (caller == null) {
9688            String msg = "null IApplicationThread when getting content provider "
9689                    + name;
9690            Slog.w(TAG, msg);
9691            throw new SecurityException(msg);
9692        }
9693        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9694        // with cross-user grant.
9695        return getContentProviderImpl(caller, name, null, stable, userId);
9696    }
9697
9698    public ContentProviderHolder getContentProviderExternal(
9699            String name, int userId, IBinder token) {
9700        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9701            "Do not have permission in call getContentProviderExternal()");
9702        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9703                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9704        return getContentProviderExternalUnchecked(name, token, userId);
9705    }
9706
9707    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9708            IBinder token, int userId) {
9709        return getContentProviderImpl(null, name, token, true, userId);
9710    }
9711
9712    /**
9713     * Drop a content provider from a ProcessRecord's bookkeeping
9714     */
9715    public void removeContentProvider(IBinder connection, boolean stable) {
9716        enforceNotIsolatedCaller("removeContentProvider");
9717        long ident = Binder.clearCallingIdentity();
9718        try {
9719            synchronized (this) {
9720                ContentProviderConnection conn;
9721                try {
9722                    conn = (ContentProviderConnection)connection;
9723                } catch (ClassCastException e) {
9724                    String msg ="removeContentProvider: " + connection
9725                            + " not a ContentProviderConnection";
9726                    Slog.w(TAG, msg);
9727                    throw new IllegalArgumentException(msg);
9728                }
9729                if (conn == null) {
9730                    throw new NullPointerException("connection is null");
9731                }
9732                if (decProviderCountLocked(conn, null, null, stable)) {
9733                    updateOomAdjLocked();
9734                }
9735            }
9736        } finally {
9737            Binder.restoreCallingIdentity(ident);
9738        }
9739    }
9740
9741    public void removeContentProviderExternal(String name, IBinder token) {
9742        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9743            "Do not have permission in call removeContentProviderExternal()");
9744        int userId = UserHandle.getCallingUserId();
9745        long ident = Binder.clearCallingIdentity();
9746        try {
9747            removeContentProviderExternalUnchecked(name, token, userId);
9748        } finally {
9749            Binder.restoreCallingIdentity(ident);
9750        }
9751    }
9752
9753    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9754        synchronized (this) {
9755            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9756            if(cpr == null) {
9757                //remove from mProvidersByClass
9758                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9759                return;
9760            }
9761
9762            //update content provider record entry info
9763            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9764            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9765            if (localCpr.hasExternalProcessHandles()) {
9766                if (localCpr.removeExternalProcessHandleLocked(token)) {
9767                    updateOomAdjLocked();
9768                } else {
9769                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9770                            + " with no external reference for token: "
9771                            + token + ".");
9772                }
9773            } else {
9774                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9775                        + " with no external references.");
9776            }
9777        }
9778    }
9779
9780    public final void publishContentProviders(IApplicationThread caller,
9781            List<ContentProviderHolder> providers) {
9782        if (providers == null) {
9783            return;
9784        }
9785
9786        enforceNotIsolatedCaller("publishContentProviders");
9787        synchronized (this) {
9788            final ProcessRecord r = getRecordForAppLocked(caller);
9789            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9790            if (r == null) {
9791                throw new SecurityException(
9792                        "Unable to find app for caller " + caller
9793                      + " (pid=" + Binder.getCallingPid()
9794                      + ") when publishing content providers");
9795            }
9796
9797            final long origId = Binder.clearCallingIdentity();
9798
9799            final int N = providers.size();
9800            for (int i=0; i<N; i++) {
9801                ContentProviderHolder src = providers.get(i);
9802                if (src == null || src.info == null || src.provider == null) {
9803                    continue;
9804                }
9805                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9806                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9807                if (dst != null) {
9808                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9809                    mProviderMap.putProviderByClass(comp, dst);
9810                    String names[] = dst.info.authority.split(";");
9811                    for (int j = 0; j < names.length; j++) {
9812                        mProviderMap.putProviderByName(names[j], dst);
9813                    }
9814
9815                    int NL = mLaunchingProviders.size();
9816                    int j;
9817                    for (j=0; j<NL; j++) {
9818                        if (mLaunchingProviders.get(j) == dst) {
9819                            mLaunchingProviders.remove(j);
9820                            j--;
9821                            NL--;
9822                        }
9823                    }
9824                    synchronized (dst) {
9825                        dst.provider = src.provider;
9826                        dst.proc = r;
9827                        dst.notifyAll();
9828                    }
9829                    updateOomAdjLocked(r);
9830                }
9831            }
9832
9833            Binder.restoreCallingIdentity(origId);
9834        }
9835    }
9836
9837    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9838        ContentProviderConnection conn;
9839        try {
9840            conn = (ContentProviderConnection)connection;
9841        } catch (ClassCastException e) {
9842            String msg ="refContentProvider: " + connection
9843                    + " not a ContentProviderConnection";
9844            Slog.w(TAG, msg);
9845            throw new IllegalArgumentException(msg);
9846        }
9847        if (conn == null) {
9848            throw new NullPointerException("connection is null");
9849        }
9850
9851        synchronized (this) {
9852            if (stable > 0) {
9853                conn.numStableIncs += stable;
9854            }
9855            stable = conn.stableCount + stable;
9856            if (stable < 0) {
9857                throw new IllegalStateException("stableCount < 0: " + stable);
9858            }
9859
9860            if (unstable > 0) {
9861                conn.numUnstableIncs += unstable;
9862            }
9863            unstable = conn.unstableCount + unstable;
9864            if (unstable < 0) {
9865                throw new IllegalStateException("unstableCount < 0: " + unstable);
9866            }
9867
9868            if ((stable+unstable) <= 0) {
9869                throw new IllegalStateException("ref counts can't go to zero here: stable="
9870                        + stable + " unstable=" + unstable);
9871            }
9872            conn.stableCount = stable;
9873            conn.unstableCount = unstable;
9874            return !conn.dead;
9875        }
9876    }
9877
9878    public void unstableProviderDied(IBinder connection) {
9879        ContentProviderConnection conn;
9880        try {
9881            conn = (ContentProviderConnection)connection;
9882        } catch (ClassCastException e) {
9883            String msg ="refContentProvider: " + connection
9884                    + " not a ContentProviderConnection";
9885            Slog.w(TAG, msg);
9886            throw new IllegalArgumentException(msg);
9887        }
9888        if (conn == null) {
9889            throw new NullPointerException("connection is null");
9890        }
9891
9892        // Safely retrieve the content provider associated with the connection.
9893        IContentProvider provider;
9894        synchronized (this) {
9895            provider = conn.provider.provider;
9896        }
9897
9898        if (provider == null) {
9899            // Um, yeah, we're way ahead of you.
9900            return;
9901        }
9902
9903        // Make sure the caller is being honest with us.
9904        if (provider.asBinder().pingBinder()) {
9905            // Er, no, still looks good to us.
9906            synchronized (this) {
9907                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9908                        + " says " + conn + " died, but we don't agree");
9909                return;
9910            }
9911        }
9912
9913        // Well look at that!  It's dead!
9914        synchronized (this) {
9915            if (conn.provider.provider != provider) {
9916                // But something changed...  good enough.
9917                return;
9918            }
9919
9920            ProcessRecord proc = conn.provider.proc;
9921            if (proc == null || proc.thread == null) {
9922                // Seems like the process is already cleaned up.
9923                return;
9924            }
9925
9926            // As far as we're concerned, this is just like receiving a
9927            // death notification...  just a bit prematurely.
9928            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9929                    + ") early provider death");
9930            final long ident = Binder.clearCallingIdentity();
9931            try {
9932                appDiedLocked(proc);
9933            } finally {
9934                Binder.restoreCallingIdentity(ident);
9935            }
9936        }
9937    }
9938
9939    @Override
9940    public void appNotRespondingViaProvider(IBinder connection) {
9941        enforceCallingPermission(
9942                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9943
9944        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9945        if (conn == null) {
9946            Slog.w(TAG, "ContentProviderConnection is null");
9947            return;
9948        }
9949
9950        final ProcessRecord host = conn.provider.proc;
9951        if (host == null) {
9952            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9953            return;
9954        }
9955
9956        final long token = Binder.clearCallingIdentity();
9957        try {
9958            appNotResponding(host, null, null, false, "ContentProvider not responding");
9959        } finally {
9960            Binder.restoreCallingIdentity(token);
9961        }
9962    }
9963
9964    public final void installSystemProviders() {
9965        List<ProviderInfo> providers;
9966        synchronized (this) {
9967            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9968            providers = generateApplicationProvidersLocked(app);
9969            if (providers != null) {
9970                for (int i=providers.size()-1; i>=0; i--) {
9971                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9972                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9973                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9974                                + ": not system .apk");
9975                        providers.remove(i);
9976                    }
9977                }
9978            }
9979        }
9980        if (providers != null) {
9981            mSystemThread.installSystemProviders(providers);
9982        }
9983
9984        mCoreSettingsObserver = new CoreSettingsObserver(this);
9985
9986        //mUsageStatsService.monitorPackages();
9987    }
9988
9989    /**
9990     * Allows apps to retrieve the MIME type of a URI.
9991     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9992     * users, then it does not need permission to access the ContentProvider.
9993     * Either, it needs cross-user uri grants.
9994     *
9995     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9996     *
9997     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9998     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9999     */
10000    public String getProviderMimeType(Uri uri, int userId) {
10001        enforceNotIsolatedCaller("getProviderMimeType");
10002        final String name = uri.getAuthority();
10003        int callingUid = Binder.getCallingUid();
10004        int callingPid = Binder.getCallingPid();
10005        long ident = 0;
10006        boolean clearedIdentity = false;
10007        userId = unsafeConvertIncomingUser(userId);
10008        if (canClearIdentity(callingPid, callingUid, userId)) {
10009            clearedIdentity = true;
10010            ident = Binder.clearCallingIdentity();
10011        }
10012        ContentProviderHolder holder = null;
10013        try {
10014            holder = getContentProviderExternalUnchecked(name, null, userId);
10015            if (holder != null) {
10016                return holder.provider.getType(uri);
10017            }
10018        } catch (RemoteException e) {
10019            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10020            return null;
10021        } finally {
10022            // We need to clear the identity to call removeContentProviderExternalUnchecked
10023            if (!clearedIdentity) {
10024                ident = Binder.clearCallingIdentity();
10025            }
10026            try {
10027                if (holder != null) {
10028                    removeContentProviderExternalUnchecked(name, null, userId);
10029                }
10030            } finally {
10031                Binder.restoreCallingIdentity(ident);
10032            }
10033        }
10034
10035        return null;
10036    }
10037
10038    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10039        if (UserHandle.getUserId(callingUid) == userId) {
10040            return true;
10041        }
10042        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10043                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10044                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10045                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10046                return true;
10047        }
10048        return false;
10049    }
10050
10051    // =========================================================
10052    // GLOBAL MANAGEMENT
10053    // =========================================================
10054
10055    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10056            boolean isolated, int isolatedUid) {
10057        String proc = customProcess != null ? customProcess : info.processName;
10058        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10059        final int userId = UserHandle.getUserId(info.uid);
10060        int uid = info.uid;
10061        if (isolated) {
10062            if (isolatedUid == 0) {
10063                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10064                while (true) {
10065                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10066                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10067                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10068                    }
10069                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10070                    mNextIsolatedProcessUid++;
10071                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10072                        // No process for this uid, use it.
10073                        break;
10074                    }
10075                    stepsLeft--;
10076                    if (stepsLeft <= 0) {
10077                        return null;
10078                    }
10079                }
10080            } else {
10081                // Special case for startIsolatedProcess (internal only), where
10082                // the uid of the isolated process is specified by the caller.
10083                uid = isolatedUid;
10084            }
10085        }
10086        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10087        if (!mBooted && !mBooting
10088                && userId == UserHandle.USER_OWNER
10089                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10090            r.persistent = true;
10091        }
10092        addProcessNameLocked(r);
10093        return r;
10094    }
10095
10096    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10097            String abiOverride) {
10098        ProcessRecord app;
10099        if (!isolated) {
10100            app = getProcessRecordLocked(info.processName, info.uid, true);
10101        } else {
10102            app = null;
10103        }
10104
10105        if (app == null) {
10106            app = newProcessRecordLocked(info, null, isolated, 0);
10107            updateLruProcessLocked(app, false, null);
10108            updateOomAdjLocked();
10109        }
10110
10111        // This package really, really can not be stopped.
10112        try {
10113            AppGlobals.getPackageManager().setPackageStoppedState(
10114                    info.packageName, false, UserHandle.getUserId(app.uid));
10115        } catch (RemoteException e) {
10116        } catch (IllegalArgumentException e) {
10117            Slog.w(TAG, "Failed trying to unstop package "
10118                    + info.packageName + ": " + e);
10119        }
10120
10121        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10122            app.persistent = true;
10123            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10124        }
10125        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10126            mPersistentStartingProcesses.add(app);
10127            startProcessLocked(app, "added application", app.processName, abiOverride,
10128                    null /* entryPoint */, null /* entryPointArgs */);
10129        }
10130
10131        return app;
10132    }
10133
10134    public void unhandledBack() {
10135        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10136                "unhandledBack()");
10137
10138        synchronized(this) {
10139            final long origId = Binder.clearCallingIdentity();
10140            try {
10141                getFocusedStack().unhandledBackLocked();
10142            } finally {
10143                Binder.restoreCallingIdentity(origId);
10144            }
10145        }
10146    }
10147
10148    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10149        enforceNotIsolatedCaller("openContentUri");
10150        final int userId = UserHandle.getCallingUserId();
10151        String name = uri.getAuthority();
10152        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10153        ParcelFileDescriptor pfd = null;
10154        if (cph != null) {
10155            // We record the binder invoker's uid in thread-local storage before
10156            // going to the content provider to open the file.  Later, in the code
10157            // that handles all permissions checks, we look for this uid and use
10158            // that rather than the Activity Manager's own uid.  The effect is that
10159            // we do the check against the caller's permissions even though it looks
10160            // to the content provider like the Activity Manager itself is making
10161            // the request.
10162            Binder token = new Binder();
10163            sCallerIdentity.set(new Identity(
10164                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10165            try {
10166                pfd = cph.provider.openFile(null, uri, "r", null, token);
10167            } catch (FileNotFoundException e) {
10168                // do nothing; pfd will be returned null
10169            } finally {
10170                // Ensure that whatever happens, we clean up the identity state
10171                sCallerIdentity.remove();
10172                // Ensure we're done with the provider.
10173                removeContentProviderExternalUnchecked(name, null, userId);
10174            }
10175        } else {
10176            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10177        }
10178        return pfd;
10179    }
10180
10181    // Actually is sleeping or shutting down or whatever else in the future
10182    // is an inactive state.
10183    public boolean isSleepingOrShuttingDown() {
10184        return isSleeping() || mShuttingDown;
10185    }
10186
10187    public boolean isSleeping() {
10188        return mSleeping;
10189    }
10190
10191    void onWakefulnessChanged(int wakefulness) {
10192        synchronized(this) {
10193            mWakefulness = wakefulness;
10194            updateSleepIfNeededLocked();
10195        }
10196    }
10197
10198    void finishRunningVoiceLocked() {
10199        if (mRunningVoice != null) {
10200            mRunningVoice = null;
10201            mVoiceWakeLock.release();
10202            updateSleepIfNeededLocked();
10203        }
10204    }
10205
10206    void startTimeTrackingFocusedActivityLocked() {
10207        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10208            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10209        }
10210    }
10211
10212    void updateSleepIfNeededLocked() {
10213        if (mSleeping && !shouldSleepLocked()) {
10214            mSleeping = false;
10215            startTimeTrackingFocusedActivityLocked();
10216            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10217            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10218            updateOomAdjLocked();
10219        } else if (!mSleeping && shouldSleepLocked()) {
10220            mSleeping = true;
10221            if (mCurAppTimeTracker != null) {
10222                mCurAppTimeTracker.stop();
10223            }
10224            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10225            mStackSupervisor.goingToSleepLocked();
10226            updateOomAdjLocked();
10227
10228            // Initialize the wake times of all processes.
10229            checkExcessivePowerUsageLocked(false);
10230            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10231            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10232            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10233        }
10234    }
10235
10236    private boolean shouldSleepLocked() {
10237        // Resume applications while running a voice interactor.
10238        if (mRunningVoice != null) {
10239            return false;
10240        }
10241
10242        // TODO: Transform the lock screen state into a sleep token instead.
10243        switch (mWakefulness) {
10244            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10245            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10246            case PowerManagerInternal.WAKEFULNESS_DOZING:
10247                // Pause applications whenever the lock screen is shown or any sleep
10248                // tokens have been acquired.
10249                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10250            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10251            default:
10252                // If we're asleep then pause applications unconditionally.
10253                return true;
10254        }
10255    }
10256
10257    /** Pokes the task persister. */
10258    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10259        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10260            // Never persist the home stack.
10261            return;
10262        }
10263        mTaskPersister.wakeup(task, flush);
10264    }
10265
10266    /** Notifies all listeners when the task stack has changed. */
10267    void notifyTaskStackChangedLocked() {
10268        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10269        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10270        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10271    }
10272
10273    @Override
10274    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10275        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10276    }
10277
10278    @Override
10279    public boolean shutdown(int timeout) {
10280        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10281                != PackageManager.PERMISSION_GRANTED) {
10282            throw new SecurityException("Requires permission "
10283                    + android.Manifest.permission.SHUTDOWN);
10284        }
10285
10286        boolean timedout = false;
10287
10288        synchronized(this) {
10289            mShuttingDown = true;
10290            updateEventDispatchingLocked();
10291            timedout = mStackSupervisor.shutdownLocked(timeout);
10292        }
10293
10294        mAppOpsService.shutdown();
10295        if (mUsageStatsService != null) {
10296            mUsageStatsService.prepareShutdown();
10297        }
10298        mBatteryStatsService.shutdown();
10299        synchronized (this) {
10300            mProcessStats.shutdownLocked();
10301            notifyTaskPersisterLocked(null, true);
10302        }
10303
10304        return timedout;
10305    }
10306
10307    public final void activitySlept(IBinder token) {
10308        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10309
10310        final long origId = Binder.clearCallingIdentity();
10311
10312        synchronized (this) {
10313            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10314            if (r != null) {
10315                mStackSupervisor.activitySleptLocked(r);
10316            }
10317        }
10318
10319        Binder.restoreCallingIdentity(origId);
10320    }
10321
10322    private String lockScreenShownToString() {
10323        switch (mLockScreenShown) {
10324            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10325            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10326            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10327            default: return "Unknown=" + mLockScreenShown;
10328        }
10329    }
10330
10331    void logLockScreen(String msg) {
10332        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10333                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10334                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10335                + " mSleeping=" + mSleeping);
10336    }
10337
10338    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10339        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10340        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10341            if (mRunningVoice == null) {
10342                mVoiceWakeLock.acquire();
10343                updateSleepIfNeededLocked();
10344            }
10345            mRunningVoice = session;
10346        }
10347    }
10348
10349    private void updateEventDispatchingLocked() {
10350        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10351    }
10352
10353    public void setLockScreenShown(boolean shown) {
10354        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10355                != PackageManager.PERMISSION_GRANTED) {
10356            throw new SecurityException("Requires permission "
10357                    + android.Manifest.permission.DEVICE_POWER);
10358        }
10359
10360        synchronized(this) {
10361            long ident = Binder.clearCallingIdentity();
10362            try {
10363                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10364                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10365                updateSleepIfNeededLocked();
10366            } finally {
10367                Binder.restoreCallingIdentity(ident);
10368            }
10369        }
10370    }
10371
10372    @Override
10373    public void stopAppSwitches() {
10374        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10375                != PackageManager.PERMISSION_GRANTED) {
10376            throw new SecurityException("Requires permission "
10377                    + android.Manifest.permission.STOP_APP_SWITCHES);
10378        }
10379
10380        synchronized(this) {
10381            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10382                    + APP_SWITCH_DELAY_TIME;
10383            mDidAppSwitch = false;
10384            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10385            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10386            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10387        }
10388    }
10389
10390    public void resumeAppSwitches() {
10391        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10392                != PackageManager.PERMISSION_GRANTED) {
10393            throw new SecurityException("Requires permission "
10394                    + android.Manifest.permission.STOP_APP_SWITCHES);
10395        }
10396
10397        synchronized(this) {
10398            // Note that we don't execute any pending app switches... we will
10399            // let those wait until either the timeout, or the next start
10400            // activity request.
10401            mAppSwitchesAllowedTime = 0;
10402        }
10403    }
10404
10405    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10406            int callingPid, int callingUid, String name) {
10407        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10408            return true;
10409        }
10410
10411        int perm = checkComponentPermission(
10412                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10413                sourceUid, -1, true);
10414        if (perm == PackageManager.PERMISSION_GRANTED) {
10415            return true;
10416        }
10417
10418        // If the actual IPC caller is different from the logical source, then
10419        // also see if they are allowed to control app switches.
10420        if (callingUid != -1 && callingUid != sourceUid) {
10421            perm = checkComponentPermission(
10422                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10423                    callingUid, -1, true);
10424            if (perm == PackageManager.PERMISSION_GRANTED) {
10425                return true;
10426            }
10427        }
10428
10429        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10430        return false;
10431    }
10432
10433    public void setDebugApp(String packageName, boolean waitForDebugger,
10434            boolean persistent) {
10435        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10436                "setDebugApp()");
10437
10438        long ident = Binder.clearCallingIdentity();
10439        try {
10440            // Note that this is not really thread safe if there are multiple
10441            // callers into it at the same time, but that's not a situation we
10442            // care about.
10443            if (persistent) {
10444                final ContentResolver resolver = mContext.getContentResolver();
10445                Settings.Global.putString(
10446                    resolver, Settings.Global.DEBUG_APP,
10447                    packageName);
10448                Settings.Global.putInt(
10449                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10450                    waitForDebugger ? 1 : 0);
10451            }
10452
10453            synchronized (this) {
10454                if (!persistent) {
10455                    mOrigDebugApp = mDebugApp;
10456                    mOrigWaitForDebugger = mWaitForDebugger;
10457                }
10458                mDebugApp = packageName;
10459                mWaitForDebugger = waitForDebugger;
10460                mDebugTransient = !persistent;
10461                if (packageName != null) {
10462                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10463                            false, UserHandle.USER_ALL, "set debug app");
10464                }
10465            }
10466        } finally {
10467            Binder.restoreCallingIdentity(ident);
10468        }
10469    }
10470
10471    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10472        synchronized (this) {
10473            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10474            if (!isDebuggable) {
10475                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10476                    throw new SecurityException("Process not debuggable: " + app.packageName);
10477                }
10478            }
10479
10480            mOpenGlTraceApp = processName;
10481        }
10482    }
10483
10484    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10485        synchronized (this) {
10486            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10487            if (!isDebuggable) {
10488                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10489                    throw new SecurityException("Process not debuggable: " + app.packageName);
10490                }
10491            }
10492            mProfileApp = processName;
10493            mProfileFile = profilerInfo.profileFile;
10494            if (mProfileFd != null) {
10495                try {
10496                    mProfileFd.close();
10497                } catch (IOException e) {
10498                }
10499                mProfileFd = null;
10500            }
10501            mProfileFd = profilerInfo.profileFd;
10502            mSamplingInterval = profilerInfo.samplingInterval;
10503            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10504            mProfileType = 0;
10505        }
10506    }
10507
10508    @Override
10509    public void setAlwaysFinish(boolean enabled) {
10510        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10511                "setAlwaysFinish()");
10512
10513        Settings.Global.putInt(
10514                mContext.getContentResolver(),
10515                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10516
10517        synchronized (this) {
10518            mAlwaysFinishActivities = enabled;
10519        }
10520    }
10521
10522    @Override
10523    public void setActivityController(IActivityController controller) {
10524        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10525                "setActivityController()");
10526        synchronized (this) {
10527            mController = controller;
10528            Watchdog.getInstance().setActivityController(controller);
10529        }
10530    }
10531
10532    @Override
10533    public void setUserIsMonkey(boolean userIsMonkey) {
10534        synchronized (this) {
10535            synchronized (mPidsSelfLocked) {
10536                final int callingPid = Binder.getCallingPid();
10537                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10538                if (precessRecord == null) {
10539                    throw new SecurityException("Unknown process: " + callingPid);
10540                }
10541                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10542                    throw new SecurityException("Only an instrumentation process "
10543                            + "with a UiAutomation can call setUserIsMonkey");
10544                }
10545            }
10546            mUserIsMonkey = userIsMonkey;
10547        }
10548    }
10549
10550    @Override
10551    public boolean isUserAMonkey() {
10552        synchronized (this) {
10553            // If there is a controller also implies the user is a monkey.
10554            return (mUserIsMonkey || mController != null);
10555        }
10556    }
10557
10558    public void requestBugReport() {
10559        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10560        SystemProperties.set("ctl.start", "bugreport");
10561    }
10562
10563    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10564        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10565    }
10566
10567    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10568        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10569            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10570        }
10571        return KEY_DISPATCHING_TIMEOUT;
10572    }
10573
10574    @Override
10575    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10576        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10577                != PackageManager.PERMISSION_GRANTED) {
10578            throw new SecurityException("Requires permission "
10579                    + android.Manifest.permission.FILTER_EVENTS);
10580        }
10581        ProcessRecord proc;
10582        long timeout;
10583        synchronized (this) {
10584            synchronized (mPidsSelfLocked) {
10585                proc = mPidsSelfLocked.get(pid);
10586            }
10587            timeout = getInputDispatchingTimeoutLocked(proc);
10588        }
10589
10590        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10591            return -1;
10592        }
10593
10594        return timeout;
10595    }
10596
10597    /**
10598     * Handle input dispatching timeouts.
10599     * Returns whether input dispatching should be aborted or not.
10600     */
10601    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10602            final ActivityRecord activity, final ActivityRecord parent,
10603            final boolean aboveSystem, String reason) {
10604        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10605                != PackageManager.PERMISSION_GRANTED) {
10606            throw new SecurityException("Requires permission "
10607                    + android.Manifest.permission.FILTER_EVENTS);
10608        }
10609
10610        final String annotation;
10611        if (reason == null) {
10612            annotation = "Input dispatching timed out";
10613        } else {
10614            annotation = "Input dispatching timed out (" + reason + ")";
10615        }
10616
10617        if (proc != null) {
10618            synchronized (this) {
10619                if (proc.debugging) {
10620                    return false;
10621                }
10622
10623                if (mDidDexOpt) {
10624                    // Give more time since we were dexopting.
10625                    mDidDexOpt = false;
10626                    return false;
10627                }
10628
10629                if (proc.instrumentationClass != null) {
10630                    Bundle info = new Bundle();
10631                    info.putString("shortMsg", "keyDispatchingTimedOut");
10632                    info.putString("longMsg", annotation);
10633                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10634                    return true;
10635                }
10636            }
10637            mHandler.post(new Runnable() {
10638                @Override
10639                public void run() {
10640                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10641                }
10642            });
10643        }
10644
10645        return true;
10646    }
10647
10648    @Override
10649    public Bundle getAssistContextExtras(int requestType) {
10650        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10651                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10652        if (pae == null) {
10653            return null;
10654        }
10655        synchronized (pae) {
10656            while (!pae.haveResult) {
10657                try {
10658                    pae.wait();
10659                } catch (InterruptedException e) {
10660                }
10661            }
10662        }
10663        synchronized (this) {
10664            buildAssistBundleLocked(pae, pae.result);
10665            mPendingAssistExtras.remove(pae);
10666            mHandler.removeCallbacks(pae);
10667        }
10668        return pae.extras;
10669    }
10670
10671    @Override
10672    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10673        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10674                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10675    }
10676
10677    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10678            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
10679        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10680                "enqueueAssistContext()");
10681        synchronized (this) {
10682            ActivityRecord activity = getFocusedStack().topActivity();
10683            if (activity == null) {
10684                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10685                return null;
10686            }
10687            if (activity.app == null || activity.app.thread == null) {
10688                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10689                return null;
10690            }
10691            if (activity.app.pid == Binder.getCallingPid()) {
10692                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10693                return null;
10694            }
10695            PendingAssistExtras pae;
10696            Bundle extras = new Bundle();
10697            if (args != null) {
10698                extras.putAll(args);
10699            }
10700            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10701            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10702            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10703            try {
10704                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10705                        requestType);
10706                mPendingAssistExtras.add(pae);
10707                mHandler.postDelayed(pae, timeout);
10708            } catch (RemoteException e) {
10709                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10710                return null;
10711            }
10712            return pae;
10713        }
10714    }
10715
10716    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10717        mPendingAssistExtras.remove(pae);
10718        if (pae.receiver != null) {
10719            // Caller wants result sent back to them.
10720            try {
10721                pae.receiver.send(0, null);
10722            } catch (RemoteException e) {
10723            }
10724        }
10725    }
10726
10727    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10728        if (result != null) {
10729            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10730        }
10731        if (pae.hint != null) {
10732            pae.extras.putBoolean(pae.hint, true);
10733        }
10734    }
10735
10736    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10737            AssistContent content, Uri referrer) {
10738        PendingAssistExtras pae = (PendingAssistExtras)token;
10739        synchronized (pae) {
10740            pae.result = extras;
10741            pae.structure = structure;
10742            pae.content = content;
10743            if (referrer != null) {
10744                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10745            }
10746            pae.haveResult = true;
10747            pae.notifyAll();
10748            if (pae.intent == null && pae.receiver == null) {
10749                // Caller is just waiting for the result.
10750                return;
10751            }
10752        }
10753
10754        // We are now ready to launch the assist activity.
10755        synchronized (this) {
10756            buildAssistBundleLocked(pae, extras);
10757            boolean exists = mPendingAssistExtras.remove(pae);
10758            mHandler.removeCallbacks(pae);
10759            if (!exists) {
10760                // Timed out.
10761                return;
10762            }
10763            if (pae.receiver != null) {
10764                // Caller wants result sent back to them.
10765                Bundle topBundle = new Bundle();
10766                topBundle.putBundle("data", pae.extras);
10767                topBundle.putParcelable("structure", pae.structure);
10768                topBundle.putParcelable("content", pae.content);
10769                try {
10770                    pae.receiver.send(0, topBundle);
10771                } catch (RemoteException e) {
10772                }
10773                return;
10774            }
10775        }
10776        pae.intent.replaceExtras(pae.extras);
10777        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10778                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10779                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10780        closeSystemDialogs("assist");
10781        try {
10782            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10783        } catch (ActivityNotFoundException e) {
10784            Slog.w(TAG, "No activity to handle assist action.", e);
10785        }
10786    }
10787
10788    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10789            Bundle args) {
10790        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
10791                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10792    }
10793
10794    public void registerProcessObserver(IProcessObserver observer) {
10795        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10796                "registerProcessObserver()");
10797        synchronized (this) {
10798            mProcessObservers.register(observer);
10799        }
10800    }
10801
10802    @Override
10803    public void unregisterProcessObserver(IProcessObserver observer) {
10804        synchronized (this) {
10805            mProcessObservers.unregister(observer);
10806        }
10807    }
10808
10809    public void registerUidObserver(IUidObserver observer) {
10810        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10811                "registerUidObserver()");
10812        synchronized (this) {
10813            mUidObservers.register(observer);
10814        }
10815    }
10816
10817    @Override
10818    public void unregisterUidObserver(IUidObserver observer) {
10819        synchronized (this) {
10820            mUidObservers.unregister(observer);
10821        }
10822    }
10823
10824    @Override
10825    public boolean convertFromTranslucent(IBinder token) {
10826        final long origId = Binder.clearCallingIdentity();
10827        try {
10828            synchronized (this) {
10829                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10830                if (r == null) {
10831                    return false;
10832                }
10833                final boolean translucentChanged = r.changeWindowTranslucency(true);
10834                if (translucentChanged) {
10835                    r.task.stack.releaseBackgroundResources(r);
10836                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10837                }
10838                mWindowManager.setAppFullscreen(token, true);
10839                return translucentChanged;
10840            }
10841        } finally {
10842            Binder.restoreCallingIdentity(origId);
10843        }
10844    }
10845
10846    @Override
10847    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10848        final long origId = Binder.clearCallingIdentity();
10849        try {
10850            synchronized (this) {
10851                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10852                if (r == null) {
10853                    return false;
10854                }
10855                int index = r.task.mActivities.lastIndexOf(r);
10856                if (index > 0) {
10857                    ActivityRecord under = r.task.mActivities.get(index - 1);
10858                    under.returningOptions = options;
10859                }
10860                final boolean translucentChanged = r.changeWindowTranslucency(false);
10861                if (translucentChanged) {
10862                    r.task.stack.convertActivityToTranslucent(r);
10863                }
10864                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10865                mWindowManager.setAppFullscreen(token, false);
10866                return translucentChanged;
10867            }
10868        } finally {
10869            Binder.restoreCallingIdentity(origId);
10870        }
10871    }
10872
10873    @Override
10874    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10875        final long origId = Binder.clearCallingIdentity();
10876        try {
10877            synchronized (this) {
10878                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10879                if (r != null) {
10880                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10881                }
10882            }
10883            return false;
10884        } finally {
10885            Binder.restoreCallingIdentity(origId);
10886        }
10887    }
10888
10889    @Override
10890    public boolean isBackgroundVisibleBehind(IBinder token) {
10891        final long origId = Binder.clearCallingIdentity();
10892        try {
10893            synchronized (this) {
10894                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10895                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10896                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
10897                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10898                return visible;
10899            }
10900        } finally {
10901            Binder.restoreCallingIdentity(origId);
10902        }
10903    }
10904
10905    @Override
10906    public ActivityOptions getActivityOptions(IBinder token) {
10907        final long origId = Binder.clearCallingIdentity();
10908        try {
10909            synchronized (this) {
10910                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10911                if (r != null) {
10912                    final ActivityOptions activityOptions = r.pendingOptions;
10913                    r.pendingOptions = null;
10914                    return activityOptions;
10915                }
10916                return null;
10917            }
10918        } finally {
10919            Binder.restoreCallingIdentity(origId);
10920        }
10921    }
10922
10923    @Override
10924    public void setImmersive(IBinder token, boolean immersive) {
10925        synchronized(this) {
10926            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10927            if (r == null) {
10928                throw new IllegalArgumentException();
10929            }
10930            r.immersive = immersive;
10931
10932            // update associated state if we're frontmost
10933            if (r == mFocusedActivity) {
10934                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10935                applyUpdateLockStateLocked(r);
10936            }
10937        }
10938    }
10939
10940    @Override
10941    public boolean isImmersive(IBinder token) {
10942        synchronized (this) {
10943            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10944            if (r == null) {
10945                throw new IllegalArgumentException();
10946            }
10947            return r.immersive;
10948        }
10949    }
10950
10951    public boolean isTopActivityImmersive() {
10952        enforceNotIsolatedCaller("startActivity");
10953        synchronized (this) {
10954            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10955            return (r != null) ? r.immersive : false;
10956        }
10957    }
10958
10959    @Override
10960    public boolean isTopOfTask(IBinder token) {
10961        synchronized (this) {
10962            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10963            if (r == null) {
10964                throw new IllegalArgumentException();
10965            }
10966            return r.task.getTopActivity() == r;
10967        }
10968    }
10969
10970    public final void enterSafeMode() {
10971        synchronized(this) {
10972            // It only makes sense to do this before the system is ready
10973            // and started launching other packages.
10974            if (!mSystemReady) {
10975                try {
10976                    AppGlobals.getPackageManager().enterSafeMode();
10977                } catch (RemoteException e) {
10978                }
10979            }
10980
10981            mSafeMode = true;
10982        }
10983    }
10984
10985    public final void showSafeModeOverlay() {
10986        View v = LayoutInflater.from(mContext).inflate(
10987                com.android.internal.R.layout.safe_mode, null);
10988        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10989        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10990        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10991        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10992        lp.gravity = Gravity.BOTTOM | Gravity.START;
10993        lp.format = v.getBackground().getOpacity();
10994        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10995                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10996        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10997        ((WindowManager)mContext.getSystemService(
10998                Context.WINDOW_SERVICE)).addView(v, lp);
10999    }
11000
11001    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11002        if (!(sender instanceof PendingIntentRecord)) {
11003            return;
11004        }
11005        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11006        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11007        synchronized (stats) {
11008            if (mBatteryStatsService.isOnBattery()) {
11009                mBatteryStatsService.enforceCallingPermission();
11010                int MY_UID = Binder.getCallingUid();
11011                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11012                BatteryStatsImpl.Uid.Pkg pkg =
11013                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11014                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11015                pkg.noteWakeupAlarmLocked(tag);
11016            }
11017        }
11018    }
11019
11020    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11021        if (!(sender instanceof PendingIntentRecord)) {
11022            return;
11023        }
11024        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11025        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11026        synchronized (stats) {
11027            mBatteryStatsService.enforceCallingPermission();
11028            int MY_UID = Binder.getCallingUid();
11029            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11030            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11031        }
11032    }
11033
11034    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11035        if (!(sender instanceof PendingIntentRecord)) {
11036            return;
11037        }
11038        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11039        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11040        synchronized (stats) {
11041            mBatteryStatsService.enforceCallingPermission();
11042            int MY_UID = Binder.getCallingUid();
11043            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11044            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11045        }
11046    }
11047
11048    public boolean killPids(int[] pids, String pReason, boolean secure) {
11049        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11050            throw new SecurityException("killPids only available to the system");
11051        }
11052        String reason = (pReason == null) ? "Unknown" : pReason;
11053        // XXX Note: don't acquire main activity lock here, because the window
11054        // manager calls in with its locks held.
11055
11056        boolean killed = false;
11057        synchronized (mPidsSelfLocked) {
11058            int[] types = new int[pids.length];
11059            int worstType = 0;
11060            for (int i=0; i<pids.length; i++) {
11061                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11062                if (proc != null) {
11063                    int type = proc.setAdj;
11064                    types[i] = type;
11065                    if (type > worstType) {
11066                        worstType = type;
11067                    }
11068                }
11069            }
11070
11071            // If the worst oom_adj is somewhere in the cached proc LRU range,
11072            // then constrain it so we will kill all cached procs.
11073            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11074                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11075                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11076            }
11077
11078            // If this is not a secure call, don't let it kill processes that
11079            // are important.
11080            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11081                worstType = ProcessList.SERVICE_ADJ;
11082            }
11083
11084            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11085            for (int i=0; i<pids.length; i++) {
11086                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11087                if (proc == null) {
11088                    continue;
11089                }
11090                int adj = proc.setAdj;
11091                if (adj >= worstType && !proc.killedByAm) {
11092                    proc.kill(reason, true);
11093                    killed = true;
11094                }
11095            }
11096        }
11097        return killed;
11098    }
11099
11100    @Override
11101    public void killUid(int uid, String reason) {
11102        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11103        synchronized (this) {
11104            final long identity = Binder.clearCallingIdentity();
11105            try {
11106                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11107                        UserHandle.getUserId(uid),
11108                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11109                        reason != null ? reason : "kill uid");
11110            } finally {
11111                Binder.restoreCallingIdentity(identity);
11112            }
11113        }
11114    }
11115
11116    @Override
11117    public boolean killProcessesBelowForeground(String reason) {
11118        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11119            throw new SecurityException("killProcessesBelowForeground() only available to system");
11120        }
11121
11122        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11123    }
11124
11125    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11126        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11127            throw new SecurityException("killProcessesBelowAdj() only available to system");
11128        }
11129
11130        boolean killed = false;
11131        synchronized (mPidsSelfLocked) {
11132            final int size = mPidsSelfLocked.size();
11133            for (int i = 0; i < size; i++) {
11134                final int pid = mPidsSelfLocked.keyAt(i);
11135                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11136                if (proc == null) continue;
11137
11138                final int adj = proc.setAdj;
11139                if (adj > belowAdj && !proc.killedByAm) {
11140                    proc.kill(reason, true);
11141                    killed = true;
11142                }
11143            }
11144        }
11145        return killed;
11146    }
11147
11148    @Override
11149    public void hang(final IBinder who, boolean allowRestart) {
11150        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11151                != PackageManager.PERMISSION_GRANTED) {
11152            throw new SecurityException("Requires permission "
11153                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11154        }
11155
11156        final IBinder.DeathRecipient death = new DeathRecipient() {
11157            @Override
11158            public void binderDied() {
11159                synchronized (this) {
11160                    notifyAll();
11161                }
11162            }
11163        };
11164
11165        try {
11166            who.linkToDeath(death, 0);
11167        } catch (RemoteException e) {
11168            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11169            return;
11170        }
11171
11172        synchronized (this) {
11173            Watchdog.getInstance().setAllowRestart(allowRestart);
11174            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11175            synchronized (death) {
11176                while (who.isBinderAlive()) {
11177                    try {
11178                        death.wait();
11179                    } catch (InterruptedException e) {
11180                    }
11181                }
11182            }
11183            Watchdog.getInstance().setAllowRestart(true);
11184        }
11185    }
11186
11187    @Override
11188    public void restart() {
11189        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11190                != PackageManager.PERMISSION_GRANTED) {
11191            throw new SecurityException("Requires permission "
11192                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11193        }
11194
11195        Log.i(TAG, "Sending shutdown broadcast...");
11196
11197        BroadcastReceiver br = new BroadcastReceiver() {
11198            @Override public void onReceive(Context context, Intent intent) {
11199                // Now the broadcast is done, finish up the low-level shutdown.
11200                Log.i(TAG, "Shutting down activity manager...");
11201                shutdown(10000);
11202                Log.i(TAG, "Shutdown complete, restarting!");
11203                Process.killProcess(Process.myPid());
11204                System.exit(10);
11205            }
11206        };
11207
11208        // First send the high-level shut down broadcast.
11209        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11210        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11211        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11212        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11213        mContext.sendOrderedBroadcastAsUser(intent,
11214                UserHandle.ALL, null, br, mHandler, 0, null, null);
11215        */
11216        br.onReceive(mContext, intent);
11217    }
11218
11219    private long getLowRamTimeSinceIdle(long now) {
11220        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11221    }
11222
11223    @Override
11224    public void performIdleMaintenance() {
11225        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11226                != PackageManager.PERMISSION_GRANTED) {
11227            throw new SecurityException("Requires permission "
11228                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11229        }
11230
11231        synchronized (this) {
11232            final long now = SystemClock.uptimeMillis();
11233            final long timeSinceLastIdle = now - mLastIdleTime;
11234            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11235            mLastIdleTime = now;
11236            mLowRamTimeSinceLastIdle = 0;
11237            if (mLowRamStartTime != 0) {
11238                mLowRamStartTime = now;
11239            }
11240
11241            StringBuilder sb = new StringBuilder(128);
11242            sb.append("Idle maintenance over ");
11243            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11244            sb.append(" low RAM for ");
11245            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11246            Slog.i(TAG, sb.toString());
11247
11248            // If at least 1/3 of our time since the last idle period has been spent
11249            // with RAM low, then we want to kill processes.
11250            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11251
11252            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11253                ProcessRecord proc = mLruProcesses.get(i);
11254                if (proc.notCachedSinceIdle) {
11255                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11256                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11257                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11258                        if (doKilling && proc.initialIdlePss != 0
11259                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11260                            sb = new StringBuilder(128);
11261                            sb.append("Kill");
11262                            sb.append(proc.processName);
11263                            sb.append(" in idle maint: pss=");
11264                            sb.append(proc.lastPss);
11265                            sb.append(", initialPss=");
11266                            sb.append(proc.initialIdlePss);
11267                            sb.append(", period=");
11268                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11269                            sb.append(", lowRamPeriod=");
11270                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11271                            Slog.wtfQuiet(TAG, sb.toString());
11272                            proc.kill("idle maint (pss " + proc.lastPss
11273                                    + " from " + proc.initialIdlePss + ")", true);
11274                        }
11275                    }
11276                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11277                    proc.notCachedSinceIdle = true;
11278                    proc.initialIdlePss = 0;
11279                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11280                            mTestPssMode, isSleeping(), now);
11281                }
11282            }
11283
11284            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11285            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11286        }
11287    }
11288
11289    private void retrieveSettings() {
11290        final ContentResolver resolver = mContext.getContentResolver();
11291        String debugApp = Settings.Global.getString(
11292            resolver, Settings.Global.DEBUG_APP);
11293        boolean waitForDebugger = Settings.Global.getInt(
11294            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11295        boolean alwaysFinishActivities = Settings.Global.getInt(
11296            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11297        boolean forceRtl = Settings.Global.getInt(
11298                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11299        // Transfer any global setting for forcing RTL layout, into a System Property
11300        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11301
11302        Configuration configuration = new Configuration();
11303        Settings.System.getConfiguration(resolver, configuration);
11304        if (forceRtl) {
11305            // This will take care of setting the correct layout direction flags
11306            configuration.setLayoutDirection(configuration.locale);
11307        }
11308
11309        synchronized (this) {
11310            mDebugApp = mOrigDebugApp = debugApp;
11311            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11312            mAlwaysFinishActivities = alwaysFinishActivities;
11313            // This happens before any activities are started, so we can
11314            // change mConfiguration in-place.
11315            updateConfigurationLocked(configuration, null, false, true);
11316            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11317                    "Initial config: " + mConfiguration);
11318        }
11319    }
11320
11321    /** Loads resources after the current configuration has been set. */
11322    private void loadResourcesOnSystemReady() {
11323        final Resources res = mContext.getResources();
11324        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11325        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11326        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11327    }
11328
11329    public boolean testIsSystemReady() {
11330        // no need to synchronize(this) just to read & return the value
11331        return mSystemReady;
11332    }
11333
11334    private static File getCalledPreBootReceiversFile() {
11335        File dataDir = Environment.getDataDirectory();
11336        File systemDir = new File(dataDir, "system");
11337        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11338        return fname;
11339    }
11340
11341    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11342        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11343        File file = getCalledPreBootReceiversFile();
11344        FileInputStream fis = null;
11345        try {
11346            fis = new FileInputStream(file);
11347            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11348            int fvers = dis.readInt();
11349            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11350                String vers = dis.readUTF();
11351                String codename = dis.readUTF();
11352                String build = dis.readUTF();
11353                if (android.os.Build.VERSION.RELEASE.equals(vers)
11354                        && android.os.Build.VERSION.CODENAME.equals(codename)
11355                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11356                    int num = dis.readInt();
11357                    while (num > 0) {
11358                        num--;
11359                        String pkg = dis.readUTF();
11360                        String cls = dis.readUTF();
11361                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11362                    }
11363                }
11364            }
11365        } catch (FileNotFoundException e) {
11366        } catch (IOException e) {
11367            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11368        } finally {
11369            if (fis != null) {
11370                try {
11371                    fis.close();
11372                } catch (IOException e) {
11373                }
11374            }
11375        }
11376        return lastDoneReceivers;
11377    }
11378
11379    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11380        File file = getCalledPreBootReceiversFile();
11381        FileOutputStream fos = null;
11382        DataOutputStream dos = null;
11383        try {
11384            fos = new FileOutputStream(file);
11385            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11386            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11387            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11388            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11389            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11390            dos.writeInt(list.size());
11391            for (int i=0; i<list.size(); i++) {
11392                dos.writeUTF(list.get(i).getPackageName());
11393                dos.writeUTF(list.get(i).getClassName());
11394            }
11395        } catch (IOException e) {
11396            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11397            file.delete();
11398        } finally {
11399            FileUtils.sync(fos);
11400            if (dos != null) {
11401                try {
11402                    dos.close();
11403                } catch (IOException e) {
11404                    // TODO Auto-generated catch block
11405                    e.printStackTrace();
11406                }
11407            }
11408        }
11409    }
11410
11411    final class PreBootContinuation extends IIntentReceiver.Stub {
11412        final Intent intent;
11413        final Runnable onFinishCallback;
11414        final ArrayList<ComponentName> doneReceivers;
11415        final List<ResolveInfo> ris;
11416        final int[] users;
11417        int lastRi = -1;
11418        int curRi = 0;
11419        int curUser = 0;
11420
11421        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11422                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11423            intent = _intent;
11424            onFinishCallback = _onFinishCallback;
11425            doneReceivers = _doneReceivers;
11426            ris = _ris;
11427            users = _users;
11428        }
11429
11430        void go() {
11431            if (lastRi != curRi) {
11432                ActivityInfo ai = ris.get(curRi).activityInfo;
11433                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11434                intent.setComponent(comp);
11435                doneReceivers.add(comp);
11436                lastRi = curRi;
11437                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11438                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11439            }
11440            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11441                    + " for user " + users[curUser]);
11442            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11443            broadcastIntentLocked(null, null, intent, null, this,
11444                    0, null, null, null, AppOpsManager.OP_NONE,
11445                    true, false, MY_PID, Process.SYSTEM_UID,
11446                    users[curUser]);
11447        }
11448
11449        public void performReceive(Intent intent, int resultCode,
11450                String data, Bundle extras, boolean ordered,
11451                boolean sticky, int sendingUser) {
11452            curUser++;
11453            if (curUser >= users.length) {
11454                curUser = 0;
11455                curRi++;
11456                if (curRi >= ris.size()) {
11457                    // All done sending broadcasts!
11458                    if (onFinishCallback != null) {
11459                        // The raw IIntentReceiver interface is called
11460                        // with the AM lock held, so redispatch to
11461                        // execute our code without the lock.
11462                        mHandler.post(onFinishCallback);
11463                    }
11464                    return;
11465                }
11466            }
11467            go();
11468        }
11469    }
11470
11471    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11472            ArrayList<ComponentName> doneReceivers, int userId) {
11473        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11474        List<ResolveInfo> ris = null;
11475        try {
11476            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11477                    intent, null, 0, userId);
11478        } catch (RemoteException e) {
11479        }
11480        if (ris == null) {
11481            return false;
11482        }
11483        for (int i=ris.size()-1; i>=0; i--) {
11484            if ((ris.get(i).activityInfo.applicationInfo.flags
11485                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11486                ris.remove(i);
11487            }
11488        }
11489        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11490
11491        // For User 0, load the version number. When delivering to a new user, deliver
11492        // to all receivers.
11493        if (userId == UserHandle.USER_OWNER) {
11494            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11495            for (int i=0; i<ris.size(); i++) {
11496                ActivityInfo ai = ris.get(i).activityInfo;
11497                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11498                if (false && lastDoneReceivers.contains(comp)) {
11499                    // We already did the pre boot receiver for this app with the current
11500                    // platform version, so don't do it again...
11501                    ris.remove(i);
11502                    i--;
11503                    // ...however, do keep it as one that has been done, so we don't
11504                    // forget about it when rewriting the file of last done receivers.
11505                    doneReceivers.add(comp);
11506                }
11507            }
11508        }
11509
11510        if (ris.size() <= 0) {
11511            return false;
11512        }
11513
11514        // If primary user, send broadcast to all available users, else just to userId
11515        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11516                : new int[] { userId };
11517        if (users.length <= 0) {
11518            return false;
11519        }
11520
11521        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11522                ris, users);
11523        cont.go();
11524        return true;
11525    }
11526
11527    public void systemReady(final Runnable goingCallback) {
11528        synchronized(this) {
11529            if (mSystemReady) {
11530                // If we're done calling all the receivers, run the next "boot phase" passed in
11531                // by the SystemServer
11532                if (goingCallback != null) {
11533                    goingCallback.run();
11534                }
11535                return;
11536            }
11537
11538            // Make sure we have the current profile info, since it is needed for
11539            // security checks.
11540            updateCurrentProfileIdsLocked();
11541
11542            mRecentTasks.clear();
11543            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11544            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11545            mTaskPersister.startPersisting();
11546
11547            // Check to see if there are any update receivers to run.
11548            if (!mDidUpdate) {
11549                if (mWaitingUpdate) {
11550                    return;
11551                }
11552                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11553                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11554                    public void run() {
11555                        synchronized (ActivityManagerService.this) {
11556                            mDidUpdate = true;
11557                        }
11558                        showBootMessage(mContext.getText(
11559                                R.string.android_upgrading_complete),
11560                                false);
11561                        writeLastDonePreBootReceivers(doneReceivers);
11562                        systemReady(goingCallback);
11563                    }
11564                }, doneReceivers, UserHandle.USER_OWNER);
11565
11566                if (mWaitingUpdate) {
11567                    return;
11568                }
11569                mDidUpdate = true;
11570            }
11571
11572            mAppOpsService.systemReady();
11573            mSystemReady = true;
11574        }
11575
11576        ArrayList<ProcessRecord> procsToKill = null;
11577        synchronized(mPidsSelfLocked) {
11578            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11579                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11580                if (!isAllowedWhileBooting(proc.info)){
11581                    if (procsToKill == null) {
11582                        procsToKill = new ArrayList<ProcessRecord>();
11583                    }
11584                    procsToKill.add(proc);
11585                }
11586            }
11587        }
11588
11589        synchronized(this) {
11590            if (procsToKill != null) {
11591                for (int i=procsToKill.size()-1; i>=0; i--) {
11592                    ProcessRecord proc = procsToKill.get(i);
11593                    Slog.i(TAG, "Removing system update proc: " + proc);
11594                    removeProcessLocked(proc, true, false, "system update done");
11595                }
11596            }
11597
11598            // Now that we have cleaned up any update processes, we
11599            // are ready to start launching real processes and know that
11600            // we won't trample on them any more.
11601            mProcessesReady = true;
11602        }
11603
11604        Slog.i(TAG, "System now ready");
11605        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11606            SystemClock.uptimeMillis());
11607
11608        synchronized(this) {
11609            // Make sure we have no pre-ready processes sitting around.
11610
11611            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11612                ResolveInfo ri = mContext.getPackageManager()
11613                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11614                                STOCK_PM_FLAGS);
11615                CharSequence errorMsg = null;
11616                if (ri != null) {
11617                    ActivityInfo ai = ri.activityInfo;
11618                    ApplicationInfo app = ai.applicationInfo;
11619                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11620                        mTopAction = Intent.ACTION_FACTORY_TEST;
11621                        mTopData = null;
11622                        mTopComponent = new ComponentName(app.packageName,
11623                                ai.name);
11624                    } else {
11625                        errorMsg = mContext.getResources().getText(
11626                                com.android.internal.R.string.factorytest_not_system);
11627                    }
11628                } else {
11629                    errorMsg = mContext.getResources().getText(
11630                            com.android.internal.R.string.factorytest_no_action);
11631                }
11632                if (errorMsg != null) {
11633                    mTopAction = null;
11634                    mTopData = null;
11635                    mTopComponent = null;
11636                    Message msg = Message.obtain();
11637                    msg.what = SHOW_FACTORY_ERROR_MSG;
11638                    msg.getData().putCharSequence("msg", errorMsg);
11639                    mUiHandler.sendMessage(msg);
11640                }
11641            }
11642        }
11643
11644        retrieveSettings();
11645        loadResourcesOnSystemReady();
11646
11647        synchronized (this) {
11648            readGrantedUriPermissionsLocked();
11649        }
11650
11651        if (goingCallback != null) goingCallback.run();
11652
11653        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11654                Integer.toString(mCurrentUserId), mCurrentUserId);
11655        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11656                Integer.toString(mCurrentUserId), mCurrentUserId);
11657        mSystemServiceManager.startUser(mCurrentUserId);
11658
11659        synchronized (this) {
11660            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11661                try {
11662                    List apps = AppGlobals.getPackageManager().
11663                        getPersistentApplications(STOCK_PM_FLAGS);
11664                    if (apps != null) {
11665                        int N = apps.size();
11666                        int i;
11667                        for (i=0; i<N; i++) {
11668                            ApplicationInfo info
11669                                = (ApplicationInfo)apps.get(i);
11670                            if (info != null &&
11671                                    !info.packageName.equals("android")) {
11672                                addAppLocked(info, false, null /* ABI override */);
11673                            }
11674                        }
11675                    }
11676                } catch (RemoteException ex) {
11677                    // pm is in same process, this will never happen.
11678                }
11679            }
11680
11681            // Start up initial activity.
11682            mBooting = true;
11683            startHomeActivityLocked(mCurrentUserId, "systemReady");
11684
11685            try {
11686                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11687                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11688                            + " data partition or your device will be unstable.");
11689                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11690                }
11691            } catch (RemoteException e) {
11692            }
11693
11694            if (!Build.isBuildConsistent()) {
11695                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11696                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11697            }
11698
11699            long ident = Binder.clearCallingIdentity();
11700            try {
11701                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11702                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11703                        | Intent.FLAG_RECEIVER_FOREGROUND);
11704                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11705                broadcastIntentLocked(null, null, intent,
11706                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11707                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11708                intent = new Intent(Intent.ACTION_USER_STARTING);
11709                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11710                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11711                broadcastIntentLocked(null, null, intent,
11712                        null, new IIntentReceiver.Stub() {
11713                            @Override
11714                            public void performReceive(Intent intent, int resultCode, String data,
11715                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11716                                    throws RemoteException {
11717                            }
11718                        }, 0, null, null,
11719                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11720                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11721            } catch (Throwable t) {
11722                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11723            } finally {
11724                Binder.restoreCallingIdentity(ident);
11725            }
11726            mStackSupervisor.resumeTopActivitiesLocked();
11727            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11728        }
11729    }
11730
11731    private boolean makeAppCrashingLocked(ProcessRecord app,
11732            String shortMsg, String longMsg, String stackTrace) {
11733        app.crashing = true;
11734        app.crashingReport = generateProcessError(app,
11735                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11736        startAppProblemLocked(app);
11737        app.stopFreezingAllLocked();
11738        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11739    }
11740
11741    private void makeAppNotRespondingLocked(ProcessRecord app,
11742            String activity, String shortMsg, String longMsg) {
11743        app.notResponding = true;
11744        app.notRespondingReport = generateProcessError(app,
11745                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11746                activity, shortMsg, longMsg, null);
11747        startAppProblemLocked(app);
11748        app.stopFreezingAllLocked();
11749    }
11750
11751    /**
11752     * Generate a process error record, suitable for attachment to a ProcessRecord.
11753     *
11754     * @param app The ProcessRecord in which the error occurred.
11755     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11756     *                      ActivityManager.AppErrorStateInfo
11757     * @param activity The activity associated with the crash, if known.
11758     * @param shortMsg Short message describing the crash.
11759     * @param longMsg Long message describing the crash.
11760     * @param stackTrace Full crash stack trace, may be null.
11761     *
11762     * @return Returns a fully-formed AppErrorStateInfo record.
11763     */
11764    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11765            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11766        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11767
11768        report.condition = condition;
11769        report.processName = app.processName;
11770        report.pid = app.pid;
11771        report.uid = app.info.uid;
11772        report.tag = activity;
11773        report.shortMsg = shortMsg;
11774        report.longMsg = longMsg;
11775        report.stackTrace = stackTrace;
11776
11777        return report;
11778    }
11779
11780    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11781        synchronized (this) {
11782            app.crashing = false;
11783            app.crashingReport = null;
11784            app.notResponding = false;
11785            app.notRespondingReport = null;
11786            if (app.anrDialog == fromDialog) {
11787                app.anrDialog = null;
11788            }
11789            if (app.waitDialog == fromDialog) {
11790                app.waitDialog = null;
11791            }
11792            if (app.pid > 0 && app.pid != MY_PID) {
11793                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11794                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11795                app.kill("user request after error", true);
11796            }
11797        }
11798    }
11799
11800    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11801            String shortMsg, String longMsg, String stackTrace) {
11802        long now = SystemClock.uptimeMillis();
11803
11804        Long crashTime;
11805        if (!app.isolated) {
11806            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11807        } else {
11808            crashTime = null;
11809        }
11810        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11811            // This process loses!
11812            Slog.w(TAG, "Process " + app.info.processName
11813                    + " has crashed too many times: killing!");
11814            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11815                    app.userId, app.info.processName, app.uid);
11816            mStackSupervisor.handleAppCrashLocked(app);
11817            if (!app.persistent) {
11818                // We don't want to start this process again until the user
11819                // explicitly does so...  but for persistent process, we really
11820                // need to keep it running.  If a persistent process is actually
11821                // repeatedly crashing, then badness for everyone.
11822                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11823                        app.info.processName);
11824                if (!app.isolated) {
11825                    // XXX We don't have a way to mark isolated processes
11826                    // as bad, since they don't have a peristent identity.
11827                    mBadProcesses.put(app.info.processName, app.uid,
11828                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11829                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11830                }
11831                app.bad = true;
11832                app.removed = true;
11833                // Don't let services in this process be restarted and potentially
11834                // annoy the user repeatedly.  Unless it is persistent, since those
11835                // processes run critical code.
11836                removeProcessLocked(app, false, false, "crash");
11837                mStackSupervisor.resumeTopActivitiesLocked();
11838                return false;
11839            }
11840            mStackSupervisor.resumeTopActivitiesLocked();
11841        } else {
11842            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11843        }
11844
11845        // Bump up the crash count of any services currently running in the proc.
11846        for (int i=app.services.size()-1; i>=0; i--) {
11847            // Any services running in the application need to be placed
11848            // back in the pending list.
11849            ServiceRecord sr = app.services.valueAt(i);
11850            sr.crashCount++;
11851        }
11852
11853        // If the crashing process is what we consider to be the "home process" and it has been
11854        // replaced by a third-party app, clear the package preferred activities from packages
11855        // with a home activity running in the process to prevent a repeatedly crashing app
11856        // from blocking the user to manually clear the list.
11857        final ArrayList<ActivityRecord> activities = app.activities;
11858        if (app == mHomeProcess && activities.size() > 0
11859                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11860            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11861                final ActivityRecord r = activities.get(activityNdx);
11862                if (r.isHomeActivity()) {
11863                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11864                    try {
11865                        ActivityThread.getPackageManager()
11866                                .clearPackagePreferredActivities(r.packageName);
11867                    } catch (RemoteException c) {
11868                        // pm is in same process, this will never happen.
11869                    }
11870                }
11871            }
11872        }
11873
11874        if (!app.isolated) {
11875            // XXX Can't keep track of crash times for isolated processes,
11876            // because they don't have a perisistent identity.
11877            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11878        }
11879
11880        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11881        return true;
11882    }
11883
11884    void startAppProblemLocked(ProcessRecord app) {
11885        // If this app is not running under the current user, then we
11886        // can't give it a report button because that would require
11887        // launching the report UI under a different user.
11888        app.errorReportReceiver = null;
11889
11890        for (int userId : mCurrentProfileIds) {
11891            if (app.userId == userId) {
11892                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11893                        mContext, app.info.packageName, app.info.flags);
11894            }
11895        }
11896        skipCurrentReceiverLocked(app);
11897    }
11898
11899    void skipCurrentReceiverLocked(ProcessRecord app) {
11900        for (BroadcastQueue queue : mBroadcastQueues) {
11901            queue.skipCurrentReceiverLocked(app);
11902        }
11903    }
11904
11905    /**
11906     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11907     * The application process will exit immediately after this call returns.
11908     * @param app object of the crashing app, null for the system server
11909     * @param crashInfo describing the exception
11910     */
11911    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11912        ProcessRecord r = findAppProcess(app, "Crash");
11913        final String processName = app == null ? "system_server"
11914                : (r == null ? "unknown" : r.processName);
11915
11916        handleApplicationCrashInner("crash", r, processName, crashInfo);
11917    }
11918
11919    /* Native crash reporting uses this inner version because it needs to be somewhat
11920     * decoupled from the AM-managed cleanup lifecycle
11921     */
11922    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11923            ApplicationErrorReport.CrashInfo crashInfo) {
11924        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11925                UserHandle.getUserId(Binder.getCallingUid()), processName,
11926                r == null ? -1 : r.info.flags,
11927                crashInfo.exceptionClassName,
11928                crashInfo.exceptionMessage,
11929                crashInfo.throwFileName,
11930                crashInfo.throwLineNumber);
11931
11932        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11933
11934        crashApplication(r, crashInfo);
11935    }
11936
11937    public void handleApplicationStrictModeViolation(
11938            IBinder app,
11939            int violationMask,
11940            StrictMode.ViolationInfo info) {
11941        ProcessRecord r = findAppProcess(app, "StrictMode");
11942        if (r == null) {
11943            return;
11944        }
11945
11946        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11947            Integer stackFingerprint = info.hashCode();
11948            boolean logIt = true;
11949            synchronized (mAlreadyLoggedViolatedStacks) {
11950                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11951                    logIt = false;
11952                    // TODO: sub-sample into EventLog for these, with
11953                    // the info.durationMillis?  Then we'd get
11954                    // the relative pain numbers, without logging all
11955                    // the stack traces repeatedly.  We'd want to do
11956                    // likewise in the client code, which also does
11957                    // dup suppression, before the Binder call.
11958                } else {
11959                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11960                        mAlreadyLoggedViolatedStacks.clear();
11961                    }
11962                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11963                }
11964            }
11965            if (logIt) {
11966                logStrictModeViolationToDropBox(r, info);
11967            }
11968        }
11969
11970        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11971            AppErrorResult result = new AppErrorResult();
11972            synchronized (this) {
11973                final long origId = Binder.clearCallingIdentity();
11974
11975                Message msg = Message.obtain();
11976                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11977                HashMap<String, Object> data = new HashMap<String, Object>();
11978                data.put("result", result);
11979                data.put("app", r);
11980                data.put("violationMask", violationMask);
11981                data.put("info", info);
11982                msg.obj = data;
11983                mUiHandler.sendMessage(msg);
11984
11985                Binder.restoreCallingIdentity(origId);
11986            }
11987            int res = result.get();
11988            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11989        }
11990    }
11991
11992    // Depending on the policy in effect, there could be a bunch of
11993    // these in quick succession so we try to batch these together to
11994    // minimize disk writes, number of dropbox entries, and maximize
11995    // compression, by having more fewer, larger records.
11996    private void logStrictModeViolationToDropBox(
11997            ProcessRecord process,
11998            StrictMode.ViolationInfo info) {
11999        if (info == null) {
12000            return;
12001        }
12002        final boolean isSystemApp = process == null ||
12003                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12004                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12005        final String processName = process == null ? "unknown" : process.processName;
12006        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12007        final DropBoxManager dbox = (DropBoxManager)
12008                mContext.getSystemService(Context.DROPBOX_SERVICE);
12009
12010        // Exit early if the dropbox isn't configured to accept this report type.
12011        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12012
12013        boolean bufferWasEmpty;
12014        boolean needsFlush;
12015        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12016        synchronized (sb) {
12017            bufferWasEmpty = sb.length() == 0;
12018            appendDropBoxProcessHeaders(process, processName, sb);
12019            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12020            sb.append("System-App: ").append(isSystemApp).append("\n");
12021            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12022            if (info.violationNumThisLoop != 0) {
12023                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12024            }
12025            if (info.numAnimationsRunning != 0) {
12026                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12027            }
12028            if (info.broadcastIntentAction != null) {
12029                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12030            }
12031            if (info.durationMillis != -1) {
12032                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12033            }
12034            if (info.numInstances != -1) {
12035                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12036            }
12037            if (info.tags != null) {
12038                for (String tag : info.tags) {
12039                    sb.append("Span-Tag: ").append(tag).append("\n");
12040                }
12041            }
12042            sb.append("\n");
12043            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12044                sb.append(info.crashInfo.stackTrace);
12045                sb.append("\n");
12046            }
12047            if (info.message != null) {
12048                sb.append(info.message);
12049                sb.append("\n");
12050            }
12051
12052            // Only buffer up to ~64k.  Various logging bits truncate
12053            // things at 128k.
12054            needsFlush = (sb.length() > 64 * 1024);
12055        }
12056
12057        // Flush immediately if the buffer's grown too large, or this
12058        // is a non-system app.  Non-system apps are isolated with a
12059        // different tag & policy and not batched.
12060        //
12061        // Batching is useful during internal testing with
12062        // StrictMode settings turned up high.  Without batching,
12063        // thousands of separate files could be created on boot.
12064        if (!isSystemApp || needsFlush) {
12065            new Thread("Error dump: " + dropboxTag) {
12066                @Override
12067                public void run() {
12068                    String report;
12069                    synchronized (sb) {
12070                        report = sb.toString();
12071                        sb.delete(0, sb.length());
12072                        sb.trimToSize();
12073                    }
12074                    if (report.length() != 0) {
12075                        dbox.addText(dropboxTag, report);
12076                    }
12077                }
12078            }.start();
12079            return;
12080        }
12081
12082        // System app batching:
12083        if (!bufferWasEmpty) {
12084            // An existing dropbox-writing thread is outstanding, so
12085            // we don't need to start it up.  The existing thread will
12086            // catch the buffer appends we just did.
12087            return;
12088        }
12089
12090        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12091        // (After this point, we shouldn't access AMS internal data structures.)
12092        new Thread("Error dump: " + dropboxTag) {
12093            @Override
12094            public void run() {
12095                // 5 second sleep to let stacks arrive and be batched together
12096                try {
12097                    Thread.sleep(5000);  // 5 seconds
12098                } catch (InterruptedException e) {}
12099
12100                String errorReport;
12101                synchronized (mStrictModeBuffer) {
12102                    errorReport = mStrictModeBuffer.toString();
12103                    if (errorReport.length() == 0) {
12104                        return;
12105                    }
12106                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12107                    mStrictModeBuffer.trimToSize();
12108                }
12109                dbox.addText(dropboxTag, errorReport);
12110            }
12111        }.start();
12112    }
12113
12114    /**
12115     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12116     * @param app object of the crashing app, null for the system server
12117     * @param tag reported by the caller
12118     * @param system whether this wtf is coming from the system
12119     * @param crashInfo describing the context of the error
12120     * @return true if the process should exit immediately (WTF is fatal)
12121     */
12122    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12123            final ApplicationErrorReport.CrashInfo crashInfo) {
12124        final int callingUid = Binder.getCallingUid();
12125        final int callingPid = Binder.getCallingPid();
12126
12127        if (system) {
12128            // If this is coming from the system, we could very well have low-level
12129            // system locks held, so we want to do this all asynchronously.  And we
12130            // never want this to become fatal, so there is that too.
12131            mHandler.post(new Runnable() {
12132                @Override public void run() {
12133                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12134                }
12135            });
12136            return false;
12137        }
12138
12139        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12140                crashInfo);
12141
12142        if (r != null && r.pid != Process.myPid() &&
12143                Settings.Global.getInt(mContext.getContentResolver(),
12144                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12145            crashApplication(r, crashInfo);
12146            return true;
12147        } else {
12148            return false;
12149        }
12150    }
12151
12152    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12153            final ApplicationErrorReport.CrashInfo crashInfo) {
12154        final ProcessRecord r = findAppProcess(app, "WTF");
12155        final String processName = app == null ? "system_server"
12156                : (r == null ? "unknown" : r.processName);
12157
12158        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12159                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12160
12161        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12162
12163        return r;
12164    }
12165
12166    /**
12167     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12168     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12169     */
12170    private ProcessRecord findAppProcess(IBinder app, String reason) {
12171        if (app == null) {
12172            return null;
12173        }
12174
12175        synchronized (this) {
12176            final int NP = mProcessNames.getMap().size();
12177            for (int ip=0; ip<NP; ip++) {
12178                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12179                final int NA = apps.size();
12180                for (int ia=0; ia<NA; ia++) {
12181                    ProcessRecord p = apps.valueAt(ia);
12182                    if (p.thread != null && p.thread.asBinder() == app) {
12183                        return p;
12184                    }
12185                }
12186            }
12187
12188            Slog.w(TAG, "Can't find mystery application for " + reason
12189                    + " from pid=" + Binder.getCallingPid()
12190                    + " uid=" + Binder.getCallingUid() + ": " + app);
12191            return null;
12192        }
12193    }
12194
12195    /**
12196     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12197     * to append various headers to the dropbox log text.
12198     */
12199    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12200            StringBuilder sb) {
12201        // Watchdog thread ends up invoking this function (with
12202        // a null ProcessRecord) to add the stack file to dropbox.
12203        // Do not acquire a lock on this (am) in such cases, as it
12204        // could cause a potential deadlock, if and when watchdog
12205        // is invoked due to unavailability of lock on am and it
12206        // would prevent watchdog from killing system_server.
12207        if (process == null) {
12208            sb.append("Process: ").append(processName).append("\n");
12209            return;
12210        }
12211        // Note: ProcessRecord 'process' is guarded by the service
12212        // instance.  (notably process.pkgList, which could otherwise change
12213        // concurrently during execution of this method)
12214        synchronized (this) {
12215            sb.append("Process: ").append(processName).append("\n");
12216            int flags = process.info.flags;
12217            IPackageManager pm = AppGlobals.getPackageManager();
12218            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12219            for (int ip=0; ip<process.pkgList.size(); ip++) {
12220                String pkg = process.pkgList.keyAt(ip);
12221                sb.append("Package: ").append(pkg);
12222                try {
12223                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12224                    if (pi != null) {
12225                        sb.append(" v").append(pi.versionCode);
12226                        if (pi.versionName != null) {
12227                            sb.append(" (").append(pi.versionName).append(")");
12228                        }
12229                    }
12230                } catch (RemoteException e) {
12231                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12232                }
12233                sb.append("\n");
12234            }
12235        }
12236    }
12237
12238    private static String processClass(ProcessRecord process) {
12239        if (process == null || process.pid == MY_PID) {
12240            return "system_server";
12241        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12242            return "system_app";
12243        } else {
12244            return "data_app";
12245        }
12246    }
12247
12248    /**
12249     * Write a description of an error (crash, WTF, ANR) to the drop box.
12250     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12251     * @param process which caused the error, null means the system server
12252     * @param activity which triggered the error, null if unknown
12253     * @param parent activity related to the error, null if unknown
12254     * @param subject line related to the error, null if absent
12255     * @param report in long form describing the error, null if absent
12256     * @param logFile to include in the report, null if none
12257     * @param crashInfo giving an application stack trace, null if absent
12258     */
12259    public void addErrorToDropBox(String eventType,
12260            ProcessRecord process, String processName, ActivityRecord activity,
12261            ActivityRecord parent, String subject,
12262            final String report, final File logFile,
12263            final ApplicationErrorReport.CrashInfo crashInfo) {
12264        // NOTE -- this must never acquire the ActivityManagerService lock,
12265        // otherwise the watchdog may be prevented from resetting the system.
12266
12267        final String dropboxTag = processClass(process) + "_" + eventType;
12268        final DropBoxManager dbox = (DropBoxManager)
12269                mContext.getSystemService(Context.DROPBOX_SERVICE);
12270
12271        // Exit early if the dropbox isn't configured to accept this report type.
12272        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12273
12274        final StringBuilder sb = new StringBuilder(1024);
12275        appendDropBoxProcessHeaders(process, processName, sb);
12276        if (activity != null) {
12277            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12278        }
12279        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12280            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12281        }
12282        if (parent != null && parent != activity) {
12283            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12284        }
12285        if (subject != null) {
12286            sb.append("Subject: ").append(subject).append("\n");
12287        }
12288        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12289        if (Debug.isDebuggerConnected()) {
12290            sb.append("Debugger: Connected\n");
12291        }
12292        sb.append("\n");
12293
12294        // Do the rest in a worker thread to avoid blocking the caller on I/O
12295        // (After this point, we shouldn't access AMS internal data structures.)
12296        Thread worker = new Thread("Error dump: " + dropboxTag) {
12297            @Override
12298            public void run() {
12299                if (report != null) {
12300                    sb.append(report);
12301                }
12302                if (logFile != null) {
12303                    try {
12304                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12305                                    "\n\n[[TRUNCATED]]"));
12306                    } catch (IOException e) {
12307                        Slog.e(TAG, "Error reading " + logFile, e);
12308                    }
12309                }
12310                if (crashInfo != null && crashInfo.stackTrace != null) {
12311                    sb.append(crashInfo.stackTrace);
12312                }
12313
12314                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12315                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12316                if (lines > 0) {
12317                    sb.append("\n");
12318
12319                    // Merge several logcat streams, and take the last N lines
12320                    InputStreamReader input = null;
12321                    try {
12322                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12323                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12324                                "-b", "crash",
12325                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12326
12327                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12328                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12329                        input = new InputStreamReader(logcat.getInputStream());
12330
12331                        int num;
12332                        char[] buf = new char[8192];
12333                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12334                    } catch (IOException e) {
12335                        Slog.e(TAG, "Error running logcat", e);
12336                    } finally {
12337                        if (input != null) try { input.close(); } catch (IOException e) {}
12338                    }
12339                }
12340
12341                dbox.addText(dropboxTag, sb.toString());
12342            }
12343        };
12344
12345        if (process == null) {
12346            // If process is null, we are being called from some internal code
12347            // and may be about to die -- run this synchronously.
12348            worker.run();
12349        } else {
12350            worker.start();
12351        }
12352    }
12353
12354    /**
12355     * Bring up the "unexpected error" dialog box for a crashing app.
12356     * Deal with edge cases (intercepts from instrumented applications,
12357     * ActivityController, error intent receivers, that sort of thing).
12358     * @param r the application crashing
12359     * @param crashInfo describing the failure
12360     */
12361    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12362        long timeMillis = System.currentTimeMillis();
12363        String shortMsg = crashInfo.exceptionClassName;
12364        String longMsg = crashInfo.exceptionMessage;
12365        String stackTrace = crashInfo.stackTrace;
12366        if (shortMsg != null && longMsg != null) {
12367            longMsg = shortMsg + ": " + longMsg;
12368        } else if (shortMsg != null) {
12369            longMsg = shortMsg;
12370        }
12371
12372        AppErrorResult result = new AppErrorResult();
12373        synchronized (this) {
12374            if (mController != null) {
12375                try {
12376                    String name = r != null ? r.processName : null;
12377                    int pid = r != null ? r.pid : Binder.getCallingPid();
12378                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12379                    if (!mController.appCrashed(name, pid,
12380                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12381                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12382                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12383                            Slog.w(TAG, "Skip killing native crashed app " + name
12384                                    + "(" + pid + ") during testing");
12385                        } else {
12386                            Slog.w(TAG, "Force-killing crashed app " + name
12387                                    + " at watcher's request");
12388                            if (r != null) {
12389                                r.kill("crash", true);
12390                            } else {
12391                                // Huh.
12392                                Process.killProcess(pid);
12393                                Process.killProcessGroup(uid, pid);
12394                            }
12395                        }
12396                        return;
12397                    }
12398                } catch (RemoteException e) {
12399                    mController = null;
12400                    Watchdog.getInstance().setActivityController(null);
12401                }
12402            }
12403
12404            final long origId = Binder.clearCallingIdentity();
12405
12406            // If this process is running instrumentation, finish it.
12407            if (r != null && r.instrumentationClass != null) {
12408                Slog.w(TAG, "Error in app " + r.processName
12409                      + " running instrumentation " + r.instrumentationClass + ":");
12410                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12411                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12412                Bundle info = new Bundle();
12413                info.putString("shortMsg", shortMsg);
12414                info.putString("longMsg", longMsg);
12415                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12416                Binder.restoreCallingIdentity(origId);
12417                return;
12418            }
12419
12420            // Log crash in battery stats.
12421            if (r != null) {
12422                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12423            }
12424
12425            // If we can't identify the process or it's already exceeded its crash quota,
12426            // quit right away without showing a crash dialog.
12427            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12428                Binder.restoreCallingIdentity(origId);
12429                return;
12430            }
12431
12432            Message msg = Message.obtain();
12433            msg.what = SHOW_ERROR_MSG;
12434            HashMap data = new HashMap();
12435            data.put("result", result);
12436            data.put("app", r);
12437            msg.obj = data;
12438            mUiHandler.sendMessage(msg);
12439
12440            Binder.restoreCallingIdentity(origId);
12441        }
12442
12443        int res = result.get();
12444
12445        Intent appErrorIntent = null;
12446        synchronized (this) {
12447            if (r != null && !r.isolated) {
12448                // XXX Can't keep track of crash time for isolated processes,
12449                // since they don't have a persistent identity.
12450                mProcessCrashTimes.put(r.info.processName, r.uid,
12451                        SystemClock.uptimeMillis());
12452            }
12453            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12454                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12455            }
12456        }
12457
12458        if (appErrorIntent != null) {
12459            try {
12460                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12461            } catch (ActivityNotFoundException e) {
12462                Slog.w(TAG, "bug report receiver dissappeared", e);
12463            }
12464        }
12465    }
12466
12467    Intent createAppErrorIntentLocked(ProcessRecord r,
12468            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12469        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12470        if (report == null) {
12471            return null;
12472        }
12473        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12474        result.setComponent(r.errorReportReceiver);
12475        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12476        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12477        return result;
12478    }
12479
12480    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12481            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12482        if (r.errorReportReceiver == null) {
12483            return null;
12484        }
12485
12486        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12487            return null;
12488        }
12489
12490        ApplicationErrorReport report = new ApplicationErrorReport();
12491        report.packageName = r.info.packageName;
12492        report.installerPackageName = r.errorReportReceiver.getPackageName();
12493        report.processName = r.processName;
12494        report.time = timeMillis;
12495        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12496
12497        if (r.crashing || r.forceCrashReport) {
12498            report.type = ApplicationErrorReport.TYPE_CRASH;
12499            report.crashInfo = crashInfo;
12500        } else if (r.notResponding) {
12501            report.type = ApplicationErrorReport.TYPE_ANR;
12502            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12503
12504            report.anrInfo.activity = r.notRespondingReport.tag;
12505            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12506            report.anrInfo.info = r.notRespondingReport.longMsg;
12507        }
12508
12509        return report;
12510    }
12511
12512    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12513        enforceNotIsolatedCaller("getProcessesInErrorState");
12514        // assume our apps are happy - lazy create the list
12515        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12516
12517        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12518                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12519        int userId = UserHandle.getUserId(Binder.getCallingUid());
12520
12521        synchronized (this) {
12522
12523            // iterate across all processes
12524            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12525                ProcessRecord app = mLruProcesses.get(i);
12526                if (!allUsers && app.userId != userId) {
12527                    continue;
12528                }
12529                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12530                    // This one's in trouble, so we'll generate a report for it
12531                    // crashes are higher priority (in case there's a crash *and* an anr)
12532                    ActivityManager.ProcessErrorStateInfo report = null;
12533                    if (app.crashing) {
12534                        report = app.crashingReport;
12535                    } else if (app.notResponding) {
12536                        report = app.notRespondingReport;
12537                    }
12538
12539                    if (report != null) {
12540                        if (errList == null) {
12541                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12542                        }
12543                        errList.add(report);
12544                    } else {
12545                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12546                                " crashing = " + app.crashing +
12547                                " notResponding = " + app.notResponding);
12548                    }
12549                }
12550            }
12551        }
12552
12553        return errList;
12554    }
12555
12556    static int procStateToImportance(int procState, int memAdj,
12557            ActivityManager.RunningAppProcessInfo currApp) {
12558        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12559        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12560            currApp.lru = memAdj;
12561        } else {
12562            currApp.lru = 0;
12563        }
12564        return imp;
12565    }
12566
12567    private void fillInProcMemInfo(ProcessRecord app,
12568            ActivityManager.RunningAppProcessInfo outInfo) {
12569        outInfo.pid = app.pid;
12570        outInfo.uid = app.info.uid;
12571        if (mHeavyWeightProcess == app) {
12572            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12573        }
12574        if (app.persistent) {
12575            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12576        }
12577        if (app.activities.size() > 0) {
12578            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12579        }
12580        outInfo.lastTrimLevel = app.trimMemoryLevel;
12581        int adj = app.curAdj;
12582        int procState = app.curProcState;
12583        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12584        outInfo.importanceReasonCode = app.adjTypeCode;
12585        outInfo.processState = app.curProcState;
12586    }
12587
12588    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12589        enforceNotIsolatedCaller("getRunningAppProcesses");
12590
12591        final int callingUid = Binder.getCallingUid();
12592
12593        // Lazy instantiation of list
12594        List<ActivityManager.RunningAppProcessInfo> runList = null;
12595        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12596                callingUid) == PackageManager.PERMISSION_GRANTED;
12597        final int userId = UserHandle.getUserId(callingUid);
12598        final boolean allUids = isGetTasksAllowed(
12599                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12600
12601        synchronized (this) {
12602            // Iterate across all processes
12603            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12604                ProcessRecord app = mLruProcesses.get(i);
12605                if ((!allUsers && app.userId != userId)
12606                        || (!allUids && app.uid != callingUid)) {
12607                    continue;
12608                }
12609                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12610                    // Generate process state info for running application
12611                    ActivityManager.RunningAppProcessInfo currApp =
12612                        new ActivityManager.RunningAppProcessInfo(app.processName,
12613                                app.pid, app.getPackageList());
12614                    fillInProcMemInfo(app, currApp);
12615                    if (app.adjSource instanceof ProcessRecord) {
12616                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12617                        currApp.importanceReasonImportance =
12618                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12619                                        app.adjSourceProcState);
12620                    } else if (app.adjSource instanceof ActivityRecord) {
12621                        ActivityRecord r = (ActivityRecord)app.adjSource;
12622                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12623                    }
12624                    if (app.adjTarget instanceof ComponentName) {
12625                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12626                    }
12627                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12628                    //        + " lru=" + currApp.lru);
12629                    if (runList == null) {
12630                        runList = new ArrayList<>();
12631                    }
12632                    runList.add(currApp);
12633                }
12634            }
12635        }
12636        return runList;
12637    }
12638
12639    public List<ApplicationInfo> getRunningExternalApplications() {
12640        enforceNotIsolatedCaller("getRunningExternalApplications");
12641        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12642        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12643        if (runningApps != null && runningApps.size() > 0) {
12644            Set<String> extList = new HashSet<String>();
12645            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12646                if (app.pkgList != null) {
12647                    for (String pkg : app.pkgList) {
12648                        extList.add(pkg);
12649                    }
12650                }
12651            }
12652            IPackageManager pm = AppGlobals.getPackageManager();
12653            for (String pkg : extList) {
12654                try {
12655                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12656                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12657                        retList.add(info);
12658                    }
12659                } catch (RemoteException e) {
12660                }
12661            }
12662        }
12663        return retList;
12664    }
12665
12666    @Override
12667    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12668        enforceNotIsolatedCaller("getMyMemoryState");
12669        synchronized (this) {
12670            ProcessRecord proc;
12671            synchronized (mPidsSelfLocked) {
12672                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12673            }
12674            fillInProcMemInfo(proc, outInfo);
12675        }
12676    }
12677
12678    @Override
12679    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12680        if (checkCallingPermission(android.Manifest.permission.DUMP)
12681                != PackageManager.PERMISSION_GRANTED) {
12682            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12683                    + Binder.getCallingPid()
12684                    + ", uid=" + Binder.getCallingUid()
12685                    + " without permission "
12686                    + android.Manifest.permission.DUMP);
12687            return;
12688        }
12689
12690        boolean dumpAll = false;
12691        boolean dumpClient = false;
12692        String dumpPackage = null;
12693
12694        int opti = 0;
12695        while (opti < args.length) {
12696            String opt = args[opti];
12697            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12698                break;
12699            }
12700            opti++;
12701            if ("-a".equals(opt)) {
12702                dumpAll = true;
12703            } else if ("-c".equals(opt)) {
12704                dumpClient = true;
12705            } else if ("-p".equals(opt)) {
12706                if (opti < args.length) {
12707                    dumpPackage = args[opti];
12708                    opti++;
12709                } else {
12710                    pw.println("Error: -p option requires package argument");
12711                    return;
12712                }
12713                dumpClient = true;
12714            } else if ("-h".equals(opt)) {
12715                pw.println("Activity manager dump options:");
12716                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12717                pw.println("  cmd may be one of:");
12718                pw.println("    a[ctivities]: activity stack state");
12719                pw.println("    r[recents]: recent activities state");
12720                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12721                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12722                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12723                pw.println("    o[om]: out of memory management");
12724                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12725                pw.println("    provider [COMP_SPEC]: provider client-side state");
12726                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12727                pw.println("    as[sociations]: tracked app associations");
12728                pw.println("    service [COMP_SPEC]: service client-side state");
12729                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12730                pw.println("    all: dump all activities");
12731                pw.println("    top: dump the top activity");
12732                pw.println("    write: write all pending state to storage");
12733                pw.println("    track-associations: enable association tracking");
12734                pw.println("    untrack-associations: disable and clear association tracking");
12735                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12736                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12737                pw.println("    a partial substring in a component name, a");
12738                pw.println("    hex object identifier.");
12739                pw.println("  -a: include all available server state.");
12740                pw.println("  -c: include client state.");
12741                pw.println("  -p: limit output to given package.");
12742                return;
12743            } else {
12744                pw.println("Unknown argument: " + opt + "; use -h for help");
12745            }
12746        }
12747
12748        long origId = Binder.clearCallingIdentity();
12749        boolean more = false;
12750        // Is the caller requesting to dump a particular piece of data?
12751        if (opti < args.length) {
12752            String cmd = args[opti];
12753            opti++;
12754            if ("activities".equals(cmd) || "a".equals(cmd)) {
12755                synchronized (this) {
12756                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12757                }
12758            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12759                synchronized (this) {
12760                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12761                }
12762            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12763                String[] newArgs;
12764                String name;
12765                if (opti >= args.length) {
12766                    name = null;
12767                    newArgs = EMPTY_STRING_ARRAY;
12768                } else {
12769                    dumpPackage = args[opti];
12770                    opti++;
12771                    newArgs = new String[args.length - opti];
12772                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12773                            args.length - opti);
12774                }
12775                synchronized (this) {
12776                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12777                }
12778            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12779                String[] newArgs;
12780                String name;
12781                if (opti >= args.length) {
12782                    name = null;
12783                    newArgs = EMPTY_STRING_ARRAY;
12784                } else {
12785                    dumpPackage = args[opti];
12786                    opti++;
12787                    newArgs = new String[args.length - opti];
12788                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12789                            args.length - opti);
12790                }
12791                synchronized (this) {
12792                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12793                }
12794            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12795                String[] newArgs;
12796                String name;
12797                if (opti >= args.length) {
12798                    name = null;
12799                    newArgs = EMPTY_STRING_ARRAY;
12800                } else {
12801                    dumpPackage = args[opti];
12802                    opti++;
12803                    newArgs = new String[args.length - opti];
12804                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12805                            args.length - opti);
12806                }
12807                synchronized (this) {
12808                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12809                }
12810            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12811                synchronized (this) {
12812                    dumpOomLocked(fd, pw, args, opti, true);
12813                }
12814            } else if ("provider".equals(cmd)) {
12815                String[] newArgs;
12816                String name;
12817                if (opti >= args.length) {
12818                    name = null;
12819                    newArgs = EMPTY_STRING_ARRAY;
12820                } else {
12821                    name = args[opti];
12822                    opti++;
12823                    newArgs = new String[args.length - opti];
12824                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12825                }
12826                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12827                    pw.println("No providers match: " + name);
12828                    pw.println("Use -h for help.");
12829                }
12830            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12831                synchronized (this) {
12832                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12833                }
12834            } else if ("service".equals(cmd)) {
12835                String[] newArgs;
12836                String name;
12837                if (opti >= args.length) {
12838                    name = null;
12839                    newArgs = EMPTY_STRING_ARRAY;
12840                } else {
12841                    name = args[opti];
12842                    opti++;
12843                    newArgs = new String[args.length - opti];
12844                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12845                            args.length - opti);
12846                }
12847                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12848                    pw.println("No services match: " + name);
12849                    pw.println("Use -h for help.");
12850                }
12851            } else if ("package".equals(cmd)) {
12852                String[] newArgs;
12853                if (opti >= args.length) {
12854                    pw.println("package: no package name specified");
12855                    pw.println("Use -h for help.");
12856                } else {
12857                    dumpPackage = args[opti];
12858                    opti++;
12859                    newArgs = new String[args.length - opti];
12860                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12861                            args.length - opti);
12862                    args = newArgs;
12863                    opti = 0;
12864                    more = true;
12865                }
12866            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12867                synchronized (this) {
12868                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12869                }
12870            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12871                synchronized (this) {
12872                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12873                }
12874            } else if ("write".equals(cmd)) {
12875                mTaskPersister.flush();
12876                pw.println("All tasks persisted.");
12877                return;
12878            } else if ("track-associations".equals(cmd)) {
12879                synchronized (this) {
12880                    if (!mTrackingAssociations) {
12881                        mTrackingAssociations = true;
12882                        pw.println("Association tracking started.");
12883                    } else {
12884                        pw.println("Association tracking already enabled.");
12885                    }
12886                }
12887                return;
12888            } else if ("untrack-associations".equals(cmd)) {
12889                synchronized (this) {
12890                    if (mTrackingAssociations) {
12891                        mTrackingAssociations = false;
12892                        mAssociations.clear();
12893                        pw.println("Association tracking stopped.");
12894                    } else {
12895                        pw.println("Association tracking not running.");
12896                    }
12897                }
12898                return;
12899            } else {
12900                // Dumping a single activity?
12901                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12902                    pw.println("Bad activity command, or no activities match: " + cmd);
12903                    pw.println("Use -h for help.");
12904                }
12905            }
12906            if (!more) {
12907                Binder.restoreCallingIdentity(origId);
12908                return;
12909            }
12910        }
12911
12912        // No piece of data specified, dump everything.
12913        synchronized (this) {
12914            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12915            pw.println();
12916            if (dumpAll) {
12917                pw.println("-------------------------------------------------------------------------------");
12918            }
12919            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12920            pw.println();
12921            if (dumpAll) {
12922                pw.println("-------------------------------------------------------------------------------");
12923            }
12924            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12925            pw.println();
12926            if (dumpAll) {
12927                pw.println("-------------------------------------------------------------------------------");
12928            }
12929            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12930            pw.println();
12931            if (dumpAll) {
12932                pw.println("-------------------------------------------------------------------------------");
12933            }
12934            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12935            pw.println();
12936            if (dumpAll) {
12937                pw.println("-------------------------------------------------------------------------------");
12938            }
12939            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12940            if (mAssociations.size() > 0) {
12941                pw.println();
12942                if (dumpAll) {
12943                    pw.println("-------------------------------------------------------------------------------");
12944                }
12945                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12946            }
12947            pw.println();
12948            if (dumpAll) {
12949                pw.println("-------------------------------------------------------------------------------");
12950            }
12951            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12952        }
12953        Binder.restoreCallingIdentity(origId);
12954    }
12955
12956    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12957            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12958        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12959
12960        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12961                dumpPackage);
12962        boolean needSep = printedAnything;
12963
12964        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12965                dumpPackage, needSep, "  mFocusedActivity: ");
12966        if (printed) {
12967            printedAnything = true;
12968            needSep = false;
12969        }
12970
12971        if (dumpPackage == null) {
12972            if (needSep) {
12973                pw.println();
12974            }
12975            needSep = true;
12976            printedAnything = true;
12977            mStackSupervisor.dump(pw, "  ");
12978        }
12979
12980        if (!printedAnything) {
12981            pw.println("  (nothing)");
12982        }
12983    }
12984
12985    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12986            int opti, boolean dumpAll, String dumpPackage) {
12987        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12988
12989        boolean printedAnything = false;
12990
12991        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12992            boolean printedHeader = false;
12993
12994            final int N = mRecentTasks.size();
12995            for (int i=0; i<N; i++) {
12996                TaskRecord tr = mRecentTasks.get(i);
12997                if (dumpPackage != null) {
12998                    if (tr.realActivity == null ||
12999                            !dumpPackage.equals(tr.realActivity)) {
13000                        continue;
13001                    }
13002                }
13003                if (!printedHeader) {
13004                    pw.println("  Recent tasks:");
13005                    printedHeader = true;
13006                    printedAnything = true;
13007                }
13008                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13009                        pw.println(tr);
13010                if (dumpAll) {
13011                    mRecentTasks.get(i).dump(pw, "    ");
13012                }
13013            }
13014        }
13015
13016        if (!printedAnything) {
13017            pw.println("  (nothing)");
13018        }
13019    }
13020
13021    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13022            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13023        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13024
13025        int dumpUid = 0;
13026        if (dumpPackage != null) {
13027            IPackageManager pm = AppGlobals.getPackageManager();
13028            try {
13029                dumpUid = pm.getPackageUid(dumpPackage, 0);
13030            } catch (RemoteException e) {
13031            }
13032        }
13033
13034        boolean printedAnything = false;
13035
13036        final long now = SystemClock.uptimeMillis();
13037
13038        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13039            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13040                    = mAssociations.valueAt(i1);
13041            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13042                SparseArray<ArrayMap<String, Association>> sourceUids
13043                        = targetComponents.valueAt(i2);
13044                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13045                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13046                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13047                        Association ass = sourceProcesses.valueAt(i4);
13048                        if (dumpPackage != null) {
13049                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13050                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13051                                continue;
13052                            }
13053                        }
13054                        printedAnything = true;
13055                        pw.print("  ");
13056                        pw.print(ass.mTargetProcess);
13057                        pw.print("/");
13058                        UserHandle.formatUid(pw, ass.mTargetUid);
13059                        pw.print(" <- ");
13060                        pw.print(ass.mSourceProcess);
13061                        pw.print("/");
13062                        UserHandle.formatUid(pw, ass.mSourceUid);
13063                        pw.println();
13064                        pw.print("    via ");
13065                        pw.print(ass.mTargetComponent.flattenToShortString());
13066                        pw.println();
13067                        pw.print("    ");
13068                        long dur = ass.mTime;
13069                        if (ass.mNesting > 0) {
13070                            dur += now - ass.mStartTime;
13071                        }
13072                        TimeUtils.formatDuration(dur, pw);
13073                        pw.print(" (");
13074                        pw.print(ass.mCount);
13075                        pw.println(" times)");
13076                        if (ass.mNesting > 0) {
13077                            pw.print("    ");
13078                            pw.print(" Currently active: ");
13079                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13080                            pw.println();
13081                        }
13082                    }
13083                }
13084            }
13085
13086        }
13087
13088        if (!printedAnything) {
13089            pw.println("  (nothing)");
13090        }
13091    }
13092
13093    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13094            int opti, boolean dumpAll, String dumpPackage) {
13095        boolean needSep = false;
13096        boolean printedAnything = false;
13097        int numPers = 0;
13098
13099        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13100
13101        if (dumpAll) {
13102            final int NP = mProcessNames.getMap().size();
13103            for (int ip=0; ip<NP; ip++) {
13104                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13105                final int NA = procs.size();
13106                for (int ia=0; ia<NA; ia++) {
13107                    ProcessRecord r = procs.valueAt(ia);
13108                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13109                        continue;
13110                    }
13111                    if (!needSep) {
13112                        pw.println("  All known processes:");
13113                        needSep = true;
13114                        printedAnything = true;
13115                    }
13116                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13117                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13118                        pw.print(" "); pw.println(r);
13119                    r.dump(pw, "    ");
13120                    if (r.persistent) {
13121                        numPers++;
13122                    }
13123                }
13124            }
13125        }
13126
13127        if (mIsolatedProcesses.size() > 0) {
13128            boolean printed = false;
13129            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13130                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13131                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13132                    continue;
13133                }
13134                if (!printed) {
13135                    if (needSep) {
13136                        pw.println();
13137                    }
13138                    pw.println("  Isolated process list (sorted by uid):");
13139                    printedAnything = true;
13140                    printed = true;
13141                    needSep = true;
13142                }
13143                pw.println(String.format("%sIsolated #%2d: %s",
13144                        "    ", i, r.toString()));
13145            }
13146        }
13147
13148        if (mActiveUids.size() > 0) {
13149            if (needSep) {
13150                pw.println();
13151            }
13152            pw.println("  UID states:");
13153            for (int i=0; i<mActiveUids.size(); i++) {
13154                UidRecord uidRec = mActiveUids.valueAt(i);
13155                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13156                pw.print(": "); pw.println(uidRec);
13157            }
13158            needSep = true;
13159            printedAnything = true;
13160        }
13161
13162        if (mLruProcesses.size() > 0) {
13163            if (needSep) {
13164                pw.println();
13165            }
13166            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13167                    pw.print(" total, non-act at ");
13168                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13169                    pw.print(", non-svc at ");
13170                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13171                    pw.println("):");
13172            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13173            needSep = true;
13174            printedAnything = true;
13175        }
13176
13177        if (dumpAll || dumpPackage != null) {
13178            synchronized (mPidsSelfLocked) {
13179                boolean printed = false;
13180                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13181                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13182                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13183                        continue;
13184                    }
13185                    if (!printed) {
13186                        if (needSep) pw.println();
13187                        needSep = true;
13188                        pw.println("  PID mappings:");
13189                        printed = true;
13190                        printedAnything = true;
13191                    }
13192                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13193                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13194                }
13195            }
13196        }
13197
13198        if (mForegroundProcesses.size() > 0) {
13199            synchronized (mPidsSelfLocked) {
13200                boolean printed = false;
13201                for (int i=0; i<mForegroundProcesses.size(); i++) {
13202                    ProcessRecord r = mPidsSelfLocked.get(
13203                            mForegroundProcesses.valueAt(i).pid);
13204                    if (dumpPackage != null && (r == null
13205                            || !r.pkgList.containsKey(dumpPackage))) {
13206                        continue;
13207                    }
13208                    if (!printed) {
13209                        if (needSep) pw.println();
13210                        needSep = true;
13211                        pw.println("  Foreground Processes:");
13212                        printed = true;
13213                        printedAnything = true;
13214                    }
13215                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13216                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13217                }
13218            }
13219        }
13220
13221        if (mPersistentStartingProcesses.size() > 0) {
13222            if (needSep) pw.println();
13223            needSep = true;
13224            printedAnything = true;
13225            pw.println("  Persisent processes that are starting:");
13226            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13227                    "Starting Norm", "Restarting PERS", dumpPackage);
13228        }
13229
13230        if (mRemovedProcesses.size() > 0) {
13231            if (needSep) pw.println();
13232            needSep = true;
13233            printedAnything = true;
13234            pw.println("  Processes that are being removed:");
13235            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13236                    "Removed Norm", "Removed PERS", dumpPackage);
13237        }
13238
13239        if (mProcessesOnHold.size() > 0) {
13240            if (needSep) pw.println();
13241            needSep = true;
13242            printedAnything = true;
13243            pw.println("  Processes that are on old until the system is ready:");
13244            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13245                    "OnHold Norm", "OnHold PERS", dumpPackage);
13246        }
13247
13248        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13249
13250        if (mProcessCrashTimes.getMap().size() > 0) {
13251            boolean printed = false;
13252            long now = SystemClock.uptimeMillis();
13253            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13254            final int NP = pmap.size();
13255            for (int ip=0; ip<NP; ip++) {
13256                String pname = pmap.keyAt(ip);
13257                SparseArray<Long> uids = pmap.valueAt(ip);
13258                final int N = uids.size();
13259                for (int i=0; i<N; i++) {
13260                    int puid = uids.keyAt(i);
13261                    ProcessRecord r = mProcessNames.get(pname, puid);
13262                    if (dumpPackage != null && (r == null
13263                            || !r.pkgList.containsKey(dumpPackage))) {
13264                        continue;
13265                    }
13266                    if (!printed) {
13267                        if (needSep) pw.println();
13268                        needSep = true;
13269                        pw.println("  Time since processes crashed:");
13270                        printed = true;
13271                        printedAnything = true;
13272                    }
13273                    pw.print("    Process "); pw.print(pname);
13274                            pw.print(" uid "); pw.print(puid);
13275                            pw.print(": last crashed ");
13276                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13277                            pw.println(" ago");
13278                }
13279            }
13280        }
13281
13282        if (mBadProcesses.getMap().size() > 0) {
13283            boolean printed = false;
13284            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13285            final int NP = pmap.size();
13286            for (int ip=0; ip<NP; ip++) {
13287                String pname = pmap.keyAt(ip);
13288                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13289                final int N = uids.size();
13290                for (int i=0; i<N; i++) {
13291                    int puid = uids.keyAt(i);
13292                    ProcessRecord r = mProcessNames.get(pname, puid);
13293                    if (dumpPackage != null && (r == null
13294                            || !r.pkgList.containsKey(dumpPackage))) {
13295                        continue;
13296                    }
13297                    if (!printed) {
13298                        if (needSep) pw.println();
13299                        needSep = true;
13300                        pw.println("  Bad processes:");
13301                        printedAnything = true;
13302                    }
13303                    BadProcessInfo info = uids.valueAt(i);
13304                    pw.print("    Bad process "); pw.print(pname);
13305                            pw.print(" uid "); pw.print(puid);
13306                            pw.print(": crashed at time "); pw.println(info.time);
13307                    if (info.shortMsg != null) {
13308                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13309                    }
13310                    if (info.longMsg != null) {
13311                        pw.print("      Long msg: "); pw.println(info.longMsg);
13312                    }
13313                    if (info.stack != null) {
13314                        pw.println("      Stack:");
13315                        int lastPos = 0;
13316                        for (int pos=0; pos<info.stack.length(); pos++) {
13317                            if (info.stack.charAt(pos) == '\n') {
13318                                pw.print("        ");
13319                                pw.write(info.stack, lastPos, pos-lastPos);
13320                                pw.println();
13321                                lastPos = pos+1;
13322                            }
13323                        }
13324                        if (lastPos < info.stack.length()) {
13325                            pw.print("        ");
13326                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13327                            pw.println();
13328                        }
13329                    }
13330                }
13331            }
13332        }
13333
13334        if (dumpPackage == null) {
13335            pw.println();
13336            needSep = false;
13337            pw.println("  mStartedUsers:");
13338            for (int i=0; i<mStartedUsers.size(); i++) {
13339                UserStartedState uss = mStartedUsers.valueAt(i);
13340                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13341                        pw.print(": "); uss.dump("", pw);
13342            }
13343            pw.print("  mStartedUserArray: [");
13344            for (int i=0; i<mStartedUserArray.length; i++) {
13345                if (i > 0) pw.print(", ");
13346                pw.print(mStartedUserArray[i]);
13347            }
13348            pw.println("]");
13349            pw.print("  mUserLru: [");
13350            for (int i=0; i<mUserLru.size(); i++) {
13351                if (i > 0) pw.print(", ");
13352                pw.print(mUserLru.get(i));
13353            }
13354            pw.println("]");
13355            if (dumpAll) {
13356                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13357            }
13358            synchronized (mUserProfileGroupIdsSelfLocked) {
13359                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13360                    pw.println("  mUserProfileGroupIds:");
13361                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13362                        pw.print("    User #");
13363                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13364                        pw.print(" -> profile #");
13365                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13366                    }
13367                }
13368            }
13369        }
13370        if (mHomeProcess != null && (dumpPackage == null
13371                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13372            if (needSep) {
13373                pw.println();
13374                needSep = false;
13375            }
13376            pw.println("  mHomeProcess: " + mHomeProcess);
13377        }
13378        if (mPreviousProcess != null && (dumpPackage == null
13379                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13380            if (needSep) {
13381                pw.println();
13382                needSep = false;
13383            }
13384            pw.println("  mPreviousProcess: " + mPreviousProcess);
13385        }
13386        if (dumpAll) {
13387            StringBuilder sb = new StringBuilder(128);
13388            sb.append("  mPreviousProcessVisibleTime: ");
13389            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13390            pw.println(sb);
13391        }
13392        if (mHeavyWeightProcess != null && (dumpPackage == null
13393                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13394            if (needSep) {
13395                pw.println();
13396                needSep = false;
13397            }
13398            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13399        }
13400        if (dumpPackage == null) {
13401            pw.println("  mConfiguration: " + mConfiguration);
13402        }
13403        if (dumpAll) {
13404            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13405            if (mCompatModePackages.getPackages().size() > 0) {
13406                boolean printed = false;
13407                for (Map.Entry<String, Integer> entry
13408                        : mCompatModePackages.getPackages().entrySet()) {
13409                    String pkg = entry.getKey();
13410                    int mode = entry.getValue();
13411                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13412                        continue;
13413                    }
13414                    if (!printed) {
13415                        pw.println("  mScreenCompatPackages:");
13416                        printed = true;
13417                    }
13418                    pw.print("    "); pw.print(pkg); pw.print(": ");
13419                            pw.print(mode); pw.println();
13420                }
13421            }
13422        }
13423        if (dumpPackage == null) {
13424            pw.println("  mWakefulness="
13425                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13426            pw.println("  mSleepTokens=" + mSleepTokens);
13427            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13428                    + lockScreenShownToString());
13429            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13430            if (mRunningVoice != null) {
13431                pw.println("  mRunningVoice=" + mRunningVoice);
13432                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13433            }
13434        }
13435        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13436                || mOrigWaitForDebugger) {
13437            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13438                    || dumpPackage.equals(mOrigDebugApp)) {
13439                if (needSep) {
13440                    pw.println();
13441                    needSep = false;
13442                }
13443                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13444                        + " mDebugTransient=" + mDebugTransient
13445                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13446            }
13447        }
13448        if (mCurAppTimeTracker != null) {
13449            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13450        }
13451        if (mMemWatchProcesses.getMap().size() > 0) {
13452            pw.println("  Mem watch processes:");
13453            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13454                    = mMemWatchProcesses.getMap();
13455            for (int i=0; i<procs.size(); i++) {
13456                final String proc = procs.keyAt(i);
13457                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13458                for (int j=0; j<uids.size(); j++) {
13459                    if (needSep) {
13460                        pw.println();
13461                        needSep = false;
13462                    }
13463                    StringBuilder sb = new StringBuilder();
13464                    sb.append("    ").append(proc).append('/');
13465                    UserHandle.formatUid(sb, uids.keyAt(j));
13466                    Pair<Long, String> val = uids.valueAt(j);
13467                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13468                    if (val.second != null) {
13469                        sb.append(", report to ").append(val.second);
13470                    }
13471                    pw.println(sb.toString());
13472                }
13473            }
13474            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13475            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13476            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13477                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13478        }
13479        if (mOpenGlTraceApp != null) {
13480            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13481                if (needSep) {
13482                    pw.println();
13483                    needSep = false;
13484                }
13485                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13486            }
13487        }
13488        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13489                || mProfileFd != null) {
13490            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13491                if (needSep) {
13492                    pw.println();
13493                    needSep = false;
13494                }
13495                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13496                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13497                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13498                        + mAutoStopProfiler);
13499                pw.println("  mProfileType=" + mProfileType);
13500            }
13501        }
13502        if (dumpPackage == null) {
13503            if (mAlwaysFinishActivities || mController != null) {
13504                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13505                        + " mController=" + mController);
13506            }
13507            if (dumpAll) {
13508                pw.println("  Total persistent processes: " + numPers);
13509                pw.println("  mProcessesReady=" + mProcessesReady
13510                        + " mSystemReady=" + mSystemReady
13511                        + " mBooted=" + mBooted
13512                        + " mFactoryTest=" + mFactoryTest);
13513                pw.println("  mBooting=" + mBooting
13514                        + " mCallFinishBooting=" + mCallFinishBooting
13515                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13516                pw.print("  mLastPowerCheckRealtime=");
13517                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13518                        pw.println("");
13519                pw.print("  mLastPowerCheckUptime=");
13520                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13521                        pw.println("");
13522                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13523                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13524                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13525                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13526                        + " (" + mLruProcesses.size() + " total)"
13527                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13528                        + " mNumServiceProcs=" + mNumServiceProcs
13529                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13530                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13531                        + " mLastMemoryLevel" + mLastMemoryLevel
13532                        + " mLastNumProcesses" + mLastNumProcesses);
13533                long now = SystemClock.uptimeMillis();
13534                pw.print("  mLastIdleTime=");
13535                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13536                        pw.print(" mLowRamSinceLastIdle=");
13537                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13538                        pw.println();
13539            }
13540        }
13541
13542        if (!printedAnything) {
13543            pw.println("  (nothing)");
13544        }
13545    }
13546
13547    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13548            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13549        if (mProcessesToGc.size() > 0) {
13550            boolean printed = false;
13551            long now = SystemClock.uptimeMillis();
13552            for (int i=0; i<mProcessesToGc.size(); i++) {
13553                ProcessRecord proc = mProcessesToGc.get(i);
13554                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13555                    continue;
13556                }
13557                if (!printed) {
13558                    if (needSep) pw.println();
13559                    needSep = true;
13560                    pw.println("  Processes that are waiting to GC:");
13561                    printed = true;
13562                }
13563                pw.print("    Process "); pw.println(proc);
13564                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13565                        pw.print(", last gced=");
13566                        pw.print(now-proc.lastRequestedGc);
13567                        pw.print(" ms ago, last lowMem=");
13568                        pw.print(now-proc.lastLowMemory);
13569                        pw.println(" ms ago");
13570
13571            }
13572        }
13573        return needSep;
13574    }
13575
13576    void printOomLevel(PrintWriter pw, String name, int adj) {
13577        pw.print("    ");
13578        if (adj >= 0) {
13579            pw.print(' ');
13580            if (adj < 10) pw.print(' ');
13581        } else {
13582            if (adj > -10) pw.print(' ');
13583        }
13584        pw.print(adj);
13585        pw.print(": ");
13586        pw.print(name);
13587        pw.print(" (");
13588        pw.print(mProcessList.getMemLevel(adj)/1024);
13589        pw.println(" kB)");
13590    }
13591
13592    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13593            int opti, boolean dumpAll) {
13594        boolean needSep = false;
13595
13596        if (mLruProcesses.size() > 0) {
13597            if (needSep) pw.println();
13598            needSep = true;
13599            pw.println("  OOM levels:");
13600            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13601            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13602            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13603            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13604            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13605            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13606            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13607            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13608            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13609            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13610            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13611            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13612            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13613            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13614
13615            if (needSep) pw.println();
13616            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13617                    pw.print(" total, non-act at ");
13618                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13619                    pw.print(", non-svc at ");
13620                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13621                    pw.println("):");
13622            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13623            needSep = true;
13624        }
13625
13626        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13627
13628        pw.println();
13629        pw.println("  mHomeProcess: " + mHomeProcess);
13630        pw.println("  mPreviousProcess: " + mPreviousProcess);
13631        if (mHeavyWeightProcess != null) {
13632            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13633        }
13634
13635        return true;
13636    }
13637
13638    /**
13639     * There are three ways to call this:
13640     *  - no provider specified: dump all the providers
13641     *  - a flattened component name that matched an existing provider was specified as the
13642     *    first arg: dump that one provider
13643     *  - the first arg isn't the flattened component name of an existing provider:
13644     *    dump all providers whose component contains the first arg as a substring
13645     */
13646    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13647            int opti, boolean dumpAll) {
13648        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13649    }
13650
13651    static class ItemMatcher {
13652        ArrayList<ComponentName> components;
13653        ArrayList<String> strings;
13654        ArrayList<Integer> objects;
13655        boolean all;
13656
13657        ItemMatcher() {
13658            all = true;
13659        }
13660
13661        void build(String name) {
13662            ComponentName componentName = ComponentName.unflattenFromString(name);
13663            if (componentName != null) {
13664                if (components == null) {
13665                    components = new ArrayList<ComponentName>();
13666                }
13667                components.add(componentName);
13668                all = false;
13669            } else {
13670                int objectId = 0;
13671                // Not a '/' separated full component name; maybe an object ID?
13672                try {
13673                    objectId = Integer.parseInt(name, 16);
13674                    if (objects == null) {
13675                        objects = new ArrayList<Integer>();
13676                    }
13677                    objects.add(objectId);
13678                    all = false;
13679                } catch (RuntimeException e) {
13680                    // Not an integer; just do string match.
13681                    if (strings == null) {
13682                        strings = new ArrayList<String>();
13683                    }
13684                    strings.add(name);
13685                    all = false;
13686                }
13687            }
13688        }
13689
13690        int build(String[] args, int opti) {
13691            for (; opti<args.length; opti++) {
13692                String name = args[opti];
13693                if ("--".equals(name)) {
13694                    return opti+1;
13695                }
13696                build(name);
13697            }
13698            return opti;
13699        }
13700
13701        boolean match(Object object, ComponentName comp) {
13702            if (all) {
13703                return true;
13704            }
13705            if (components != null) {
13706                for (int i=0; i<components.size(); i++) {
13707                    if (components.get(i).equals(comp)) {
13708                        return true;
13709                    }
13710                }
13711            }
13712            if (objects != null) {
13713                for (int i=0; i<objects.size(); i++) {
13714                    if (System.identityHashCode(object) == objects.get(i)) {
13715                        return true;
13716                    }
13717                }
13718            }
13719            if (strings != null) {
13720                String flat = comp.flattenToString();
13721                for (int i=0; i<strings.size(); i++) {
13722                    if (flat.contains(strings.get(i))) {
13723                        return true;
13724                    }
13725                }
13726            }
13727            return false;
13728        }
13729    }
13730
13731    /**
13732     * There are three things that cmd can be:
13733     *  - a flattened component name that matches an existing activity
13734     *  - the cmd arg isn't the flattened component name of an existing activity:
13735     *    dump all activity whose component contains the cmd as a substring
13736     *  - A hex number of the ActivityRecord object instance.
13737     */
13738    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13739            int opti, boolean dumpAll) {
13740        ArrayList<ActivityRecord> activities;
13741
13742        synchronized (this) {
13743            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13744        }
13745
13746        if (activities.size() <= 0) {
13747            return false;
13748        }
13749
13750        String[] newArgs = new String[args.length - opti];
13751        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13752
13753        TaskRecord lastTask = null;
13754        boolean needSep = false;
13755        for (int i=activities.size()-1; i>=0; i--) {
13756            ActivityRecord r = activities.get(i);
13757            if (needSep) {
13758                pw.println();
13759            }
13760            needSep = true;
13761            synchronized (this) {
13762                if (lastTask != r.task) {
13763                    lastTask = r.task;
13764                    pw.print("TASK "); pw.print(lastTask.affinity);
13765                            pw.print(" id="); pw.println(lastTask.taskId);
13766                    if (dumpAll) {
13767                        lastTask.dump(pw, "  ");
13768                    }
13769                }
13770            }
13771            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13772        }
13773        return true;
13774    }
13775
13776    /**
13777     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13778     * there is a thread associated with the activity.
13779     */
13780    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13781            final ActivityRecord r, String[] args, boolean dumpAll) {
13782        String innerPrefix = prefix + "  ";
13783        synchronized (this) {
13784            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13785                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13786                    pw.print(" pid=");
13787                    if (r.app != null) pw.println(r.app.pid);
13788                    else pw.println("(not running)");
13789            if (dumpAll) {
13790                r.dump(pw, innerPrefix);
13791            }
13792        }
13793        if (r.app != null && r.app.thread != null) {
13794            // flush anything that is already in the PrintWriter since the thread is going
13795            // to write to the file descriptor directly
13796            pw.flush();
13797            try {
13798                TransferPipe tp = new TransferPipe();
13799                try {
13800                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13801                            r.appToken, innerPrefix, args);
13802                    tp.go(fd);
13803                } finally {
13804                    tp.kill();
13805                }
13806            } catch (IOException e) {
13807                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13808            } catch (RemoteException e) {
13809                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13810            }
13811        }
13812    }
13813
13814    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13815            int opti, boolean dumpAll, String dumpPackage) {
13816        boolean needSep = false;
13817        boolean onlyHistory = false;
13818        boolean printedAnything = false;
13819
13820        if ("history".equals(dumpPackage)) {
13821            if (opti < args.length && "-s".equals(args[opti])) {
13822                dumpAll = false;
13823            }
13824            onlyHistory = true;
13825            dumpPackage = null;
13826        }
13827
13828        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13829        if (!onlyHistory && dumpAll) {
13830            if (mRegisteredReceivers.size() > 0) {
13831                boolean printed = false;
13832                Iterator it = mRegisteredReceivers.values().iterator();
13833                while (it.hasNext()) {
13834                    ReceiverList r = (ReceiverList)it.next();
13835                    if (dumpPackage != null && (r.app == null ||
13836                            !dumpPackage.equals(r.app.info.packageName))) {
13837                        continue;
13838                    }
13839                    if (!printed) {
13840                        pw.println("  Registered Receivers:");
13841                        needSep = true;
13842                        printed = true;
13843                        printedAnything = true;
13844                    }
13845                    pw.print("  * "); pw.println(r);
13846                    r.dump(pw, "    ");
13847                }
13848            }
13849
13850            if (mReceiverResolver.dump(pw, needSep ?
13851                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13852                    "    ", dumpPackage, false, false)) {
13853                needSep = true;
13854                printedAnything = true;
13855            }
13856        }
13857
13858        for (BroadcastQueue q : mBroadcastQueues) {
13859            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13860            printedAnything |= needSep;
13861        }
13862
13863        needSep = true;
13864
13865        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13866            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13867                if (needSep) {
13868                    pw.println();
13869                }
13870                needSep = true;
13871                printedAnything = true;
13872                pw.print("  Sticky broadcasts for user ");
13873                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13874                StringBuilder sb = new StringBuilder(128);
13875                for (Map.Entry<String, ArrayList<Intent>> ent
13876                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13877                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13878                    if (dumpAll) {
13879                        pw.println(":");
13880                        ArrayList<Intent> intents = ent.getValue();
13881                        final int N = intents.size();
13882                        for (int i=0; i<N; i++) {
13883                            sb.setLength(0);
13884                            sb.append("    Intent: ");
13885                            intents.get(i).toShortString(sb, false, true, false, false);
13886                            pw.println(sb.toString());
13887                            Bundle bundle = intents.get(i).getExtras();
13888                            if (bundle != null) {
13889                                pw.print("      ");
13890                                pw.println(bundle.toString());
13891                            }
13892                        }
13893                    } else {
13894                        pw.println("");
13895                    }
13896                }
13897            }
13898        }
13899
13900        if (!onlyHistory && dumpAll) {
13901            pw.println();
13902            for (BroadcastQueue queue : mBroadcastQueues) {
13903                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13904                        + queue.mBroadcastsScheduled);
13905            }
13906            pw.println("  mHandler:");
13907            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13908            needSep = true;
13909            printedAnything = true;
13910        }
13911
13912        if (!printedAnything) {
13913            pw.println("  (nothing)");
13914        }
13915    }
13916
13917    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13918            int opti, boolean dumpAll, String dumpPackage) {
13919        boolean needSep;
13920        boolean printedAnything = false;
13921
13922        ItemMatcher matcher = new ItemMatcher();
13923        matcher.build(args, opti);
13924
13925        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13926
13927        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13928        printedAnything |= needSep;
13929
13930        if (mLaunchingProviders.size() > 0) {
13931            boolean printed = false;
13932            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13933                ContentProviderRecord r = mLaunchingProviders.get(i);
13934                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13935                    continue;
13936                }
13937                if (!printed) {
13938                    if (needSep) pw.println();
13939                    needSep = true;
13940                    pw.println("  Launching content providers:");
13941                    printed = true;
13942                    printedAnything = true;
13943                }
13944                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13945                        pw.println(r);
13946            }
13947        }
13948
13949        if (mGrantedUriPermissions.size() > 0) {
13950            boolean printed = false;
13951            int dumpUid = -2;
13952            if (dumpPackage != null) {
13953                try {
13954                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13955                } catch (NameNotFoundException e) {
13956                    dumpUid = -1;
13957                }
13958            }
13959            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13960                int uid = mGrantedUriPermissions.keyAt(i);
13961                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13962                    continue;
13963                }
13964                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13965                if (!printed) {
13966                    if (needSep) pw.println();
13967                    needSep = true;
13968                    pw.println("  Granted Uri Permissions:");
13969                    printed = true;
13970                    printedAnything = true;
13971                }
13972                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13973                for (UriPermission perm : perms.values()) {
13974                    pw.print("    "); pw.println(perm);
13975                    if (dumpAll) {
13976                        perm.dump(pw, "      ");
13977                    }
13978                }
13979            }
13980        }
13981
13982        if (!printedAnything) {
13983            pw.println("  (nothing)");
13984        }
13985    }
13986
13987    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13988            int opti, boolean dumpAll, String dumpPackage) {
13989        boolean printed = false;
13990
13991        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13992
13993        if (mIntentSenderRecords.size() > 0) {
13994            Iterator<WeakReference<PendingIntentRecord>> it
13995                    = mIntentSenderRecords.values().iterator();
13996            while (it.hasNext()) {
13997                WeakReference<PendingIntentRecord> ref = it.next();
13998                PendingIntentRecord rec = ref != null ? ref.get(): null;
13999                if (dumpPackage != null && (rec == null
14000                        || !dumpPackage.equals(rec.key.packageName))) {
14001                    continue;
14002                }
14003                printed = true;
14004                if (rec != null) {
14005                    pw.print("  * "); pw.println(rec);
14006                    if (dumpAll) {
14007                        rec.dump(pw, "    ");
14008                    }
14009                } else {
14010                    pw.print("  * "); pw.println(ref);
14011                }
14012            }
14013        }
14014
14015        if (!printed) {
14016            pw.println("  (nothing)");
14017        }
14018    }
14019
14020    private static final int dumpProcessList(PrintWriter pw,
14021            ActivityManagerService service, List list,
14022            String prefix, String normalLabel, String persistentLabel,
14023            String dumpPackage) {
14024        int numPers = 0;
14025        final int N = list.size()-1;
14026        for (int i=N; i>=0; i--) {
14027            ProcessRecord r = (ProcessRecord)list.get(i);
14028            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14029                continue;
14030            }
14031            pw.println(String.format("%s%s #%2d: %s",
14032                    prefix, (r.persistent ? persistentLabel : normalLabel),
14033                    i, r.toString()));
14034            if (r.persistent) {
14035                numPers++;
14036            }
14037        }
14038        return numPers;
14039    }
14040
14041    private static final boolean dumpProcessOomList(PrintWriter pw,
14042            ActivityManagerService service, List<ProcessRecord> origList,
14043            String prefix, String normalLabel, String persistentLabel,
14044            boolean inclDetails, String dumpPackage) {
14045
14046        ArrayList<Pair<ProcessRecord, Integer>> list
14047                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14048        for (int i=0; i<origList.size(); i++) {
14049            ProcessRecord r = origList.get(i);
14050            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14051                continue;
14052            }
14053            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14054        }
14055
14056        if (list.size() <= 0) {
14057            return false;
14058        }
14059
14060        Comparator<Pair<ProcessRecord, Integer>> comparator
14061                = new Comparator<Pair<ProcessRecord, Integer>>() {
14062            @Override
14063            public int compare(Pair<ProcessRecord, Integer> object1,
14064                    Pair<ProcessRecord, Integer> object2) {
14065                if (object1.first.setAdj != object2.first.setAdj) {
14066                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14067                }
14068                if (object1.second.intValue() != object2.second.intValue()) {
14069                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14070                }
14071                return 0;
14072            }
14073        };
14074
14075        Collections.sort(list, comparator);
14076
14077        final long curRealtime = SystemClock.elapsedRealtime();
14078        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14079        final long curUptime = SystemClock.uptimeMillis();
14080        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14081
14082        for (int i=list.size()-1; i>=0; i--) {
14083            ProcessRecord r = list.get(i).first;
14084            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14085            char schedGroup;
14086            switch (r.setSchedGroup) {
14087                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14088                    schedGroup = 'B';
14089                    break;
14090                case Process.THREAD_GROUP_DEFAULT:
14091                    schedGroup = 'F';
14092                    break;
14093                default:
14094                    schedGroup = '?';
14095                    break;
14096            }
14097            char foreground;
14098            if (r.foregroundActivities) {
14099                foreground = 'A';
14100            } else if (r.foregroundServices) {
14101                foreground = 'S';
14102            } else {
14103                foreground = ' ';
14104            }
14105            String procState = ProcessList.makeProcStateString(r.curProcState);
14106            pw.print(prefix);
14107            pw.print(r.persistent ? persistentLabel : normalLabel);
14108            pw.print(" #");
14109            int num = (origList.size()-1)-list.get(i).second;
14110            if (num < 10) pw.print(' ');
14111            pw.print(num);
14112            pw.print(": ");
14113            pw.print(oomAdj);
14114            pw.print(' ');
14115            pw.print(schedGroup);
14116            pw.print('/');
14117            pw.print(foreground);
14118            pw.print('/');
14119            pw.print(procState);
14120            pw.print(" trm:");
14121            if (r.trimMemoryLevel < 10) pw.print(' ');
14122            pw.print(r.trimMemoryLevel);
14123            pw.print(' ');
14124            pw.print(r.toShortString());
14125            pw.print(" (");
14126            pw.print(r.adjType);
14127            pw.println(')');
14128            if (r.adjSource != null || r.adjTarget != null) {
14129                pw.print(prefix);
14130                pw.print("    ");
14131                if (r.adjTarget instanceof ComponentName) {
14132                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14133                } else if (r.adjTarget != null) {
14134                    pw.print(r.adjTarget.toString());
14135                } else {
14136                    pw.print("{null}");
14137                }
14138                pw.print("<=");
14139                if (r.adjSource instanceof ProcessRecord) {
14140                    pw.print("Proc{");
14141                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14142                    pw.println("}");
14143                } else if (r.adjSource != null) {
14144                    pw.println(r.adjSource.toString());
14145                } else {
14146                    pw.println("{null}");
14147                }
14148            }
14149            if (inclDetails) {
14150                pw.print(prefix);
14151                pw.print("    ");
14152                pw.print("oom: max="); pw.print(r.maxAdj);
14153                pw.print(" curRaw="); pw.print(r.curRawAdj);
14154                pw.print(" setRaw="); pw.print(r.setRawAdj);
14155                pw.print(" cur="); pw.print(r.curAdj);
14156                pw.print(" set="); pw.println(r.setAdj);
14157                pw.print(prefix);
14158                pw.print("    ");
14159                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14160                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14161                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14162                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14163                pw.println();
14164                pw.print(prefix);
14165                pw.print("    ");
14166                pw.print("cached="); pw.print(r.cached);
14167                pw.print(" empty="); pw.print(r.empty);
14168                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14169
14170                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14171                    if (r.lastWakeTime != 0) {
14172                        long wtime;
14173                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14174                        synchronized (stats) {
14175                            wtime = stats.getProcessWakeTime(r.info.uid,
14176                                    r.pid, curRealtime);
14177                        }
14178                        long timeUsed = wtime - r.lastWakeTime;
14179                        pw.print(prefix);
14180                        pw.print("    ");
14181                        pw.print("keep awake over ");
14182                        TimeUtils.formatDuration(realtimeSince, pw);
14183                        pw.print(" used ");
14184                        TimeUtils.formatDuration(timeUsed, pw);
14185                        pw.print(" (");
14186                        pw.print((timeUsed*100)/realtimeSince);
14187                        pw.println("%)");
14188                    }
14189                    if (r.lastCpuTime != 0) {
14190                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14191                        pw.print(prefix);
14192                        pw.print("    ");
14193                        pw.print("run cpu over ");
14194                        TimeUtils.formatDuration(uptimeSince, pw);
14195                        pw.print(" used ");
14196                        TimeUtils.formatDuration(timeUsed, pw);
14197                        pw.print(" (");
14198                        pw.print((timeUsed*100)/uptimeSince);
14199                        pw.println("%)");
14200                    }
14201                }
14202            }
14203        }
14204        return true;
14205    }
14206
14207    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14208            String[] args) {
14209        ArrayList<ProcessRecord> procs;
14210        synchronized (this) {
14211            if (args != null && args.length > start
14212                    && args[start].charAt(0) != '-') {
14213                procs = new ArrayList<ProcessRecord>();
14214                int pid = -1;
14215                try {
14216                    pid = Integer.parseInt(args[start]);
14217                } catch (NumberFormatException e) {
14218                }
14219                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14220                    ProcessRecord proc = mLruProcesses.get(i);
14221                    if (proc.pid == pid) {
14222                        procs.add(proc);
14223                    } else if (allPkgs && proc.pkgList != null
14224                            && proc.pkgList.containsKey(args[start])) {
14225                        procs.add(proc);
14226                    } else if (proc.processName.equals(args[start])) {
14227                        procs.add(proc);
14228                    }
14229                }
14230                if (procs.size() <= 0) {
14231                    return null;
14232                }
14233            } else {
14234                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14235            }
14236        }
14237        return procs;
14238    }
14239
14240    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14241            PrintWriter pw, String[] args) {
14242        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14243        if (procs == null) {
14244            pw.println("No process found for: " + args[0]);
14245            return;
14246        }
14247
14248        long uptime = SystemClock.uptimeMillis();
14249        long realtime = SystemClock.elapsedRealtime();
14250        pw.println("Applications Graphics Acceleration Info:");
14251        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14252
14253        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14254            ProcessRecord r = procs.get(i);
14255            if (r.thread != null) {
14256                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14257                pw.flush();
14258                try {
14259                    TransferPipe tp = new TransferPipe();
14260                    try {
14261                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14262                        tp.go(fd);
14263                    } finally {
14264                        tp.kill();
14265                    }
14266                } catch (IOException e) {
14267                    pw.println("Failure while dumping the app: " + r);
14268                    pw.flush();
14269                } catch (RemoteException e) {
14270                    pw.println("Got a RemoteException while dumping the app " + r);
14271                    pw.flush();
14272                }
14273            }
14274        }
14275    }
14276
14277    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14278        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14279        if (procs == null) {
14280            pw.println("No process found for: " + args[0]);
14281            return;
14282        }
14283
14284        pw.println("Applications Database Info:");
14285
14286        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14287            ProcessRecord r = procs.get(i);
14288            if (r.thread != null) {
14289                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14290                pw.flush();
14291                try {
14292                    TransferPipe tp = new TransferPipe();
14293                    try {
14294                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14295                        tp.go(fd);
14296                    } finally {
14297                        tp.kill();
14298                    }
14299                } catch (IOException e) {
14300                    pw.println("Failure while dumping the app: " + r);
14301                    pw.flush();
14302                } catch (RemoteException e) {
14303                    pw.println("Got a RemoteException while dumping the app " + r);
14304                    pw.flush();
14305                }
14306            }
14307        }
14308    }
14309
14310    final static class MemItem {
14311        final boolean isProc;
14312        final String label;
14313        final String shortLabel;
14314        final long pss;
14315        final int id;
14316        final boolean hasActivities;
14317        ArrayList<MemItem> subitems;
14318
14319        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14320                boolean _hasActivities) {
14321            isProc = true;
14322            label = _label;
14323            shortLabel = _shortLabel;
14324            pss = _pss;
14325            id = _id;
14326            hasActivities = _hasActivities;
14327        }
14328
14329        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14330            isProc = false;
14331            label = _label;
14332            shortLabel = _shortLabel;
14333            pss = _pss;
14334            id = _id;
14335            hasActivities = false;
14336        }
14337    }
14338
14339    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14340            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14341        if (sort && !isCompact) {
14342            Collections.sort(items, new Comparator<MemItem>() {
14343                @Override
14344                public int compare(MemItem lhs, MemItem rhs) {
14345                    if (lhs.pss < rhs.pss) {
14346                        return 1;
14347                    } else if (lhs.pss > rhs.pss) {
14348                        return -1;
14349                    }
14350                    return 0;
14351                }
14352            });
14353        }
14354
14355        for (int i=0; i<items.size(); i++) {
14356            MemItem mi = items.get(i);
14357            if (!isCompact) {
14358                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14359            } else if (mi.isProc) {
14360                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14361                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14362                pw.println(mi.hasActivities ? ",a" : ",e");
14363            } else {
14364                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14365                pw.println(mi.pss);
14366            }
14367            if (mi.subitems != null) {
14368                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14369                        true, isCompact);
14370            }
14371        }
14372    }
14373
14374    // These are in KB.
14375    static final long[] DUMP_MEM_BUCKETS = new long[] {
14376        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14377        120*1024, 160*1024, 200*1024,
14378        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14379        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14380    };
14381
14382    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14383            boolean stackLike) {
14384        int start = label.lastIndexOf('.');
14385        if (start >= 0) start++;
14386        else start = 0;
14387        int end = label.length();
14388        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14389            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14390                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14391                out.append(bucket);
14392                out.append(stackLike ? "MB." : "MB ");
14393                out.append(label, start, end);
14394                return;
14395            }
14396        }
14397        out.append(memKB/1024);
14398        out.append(stackLike ? "MB." : "MB ");
14399        out.append(label, start, end);
14400    }
14401
14402    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14403            ProcessList.NATIVE_ADJ,
14404            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14405            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14406            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14407            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14408            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14409            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14410    };
14411    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14412            "Native",
14413            "System", "Persistent", "Persistent Service", "Foreground",
14414            "Visible", "Perceptible",
14415            "Heavy Weight", "Backup",
14416            "A Services", "Home",
14417            "Previous", "B Services", "Cached"
14418    };
14419    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14420            "native",
14421            "sys", "pers", "persvc", "fore",
14422            "vis", "percept",
14423            "heavy", "backup",
14424            "servicea", "home",
14425            "prev", "serviceb", "cached"
14426    };
14427
14428    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14429            long realtime, boolean isCheckinRequest, boolean isCompact) {
14430        if (isCheckinRequest || isCompact) {
14431            // short checkin version
14432            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14433        } else {
14434            pw.println("Applications Memory Usage (kB):");
14435            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14436        }
14437    }
14438
14439    private static final int KSM_SHARED = 0;
14440    private static final int KSM_SHARING = 1;
14441    private static final int KSM_UNSHARED = 2;
14442    private static final int KSM_VOLATILE = 3;
14443
14444    private final long[] getKsmInfo() {
14445        long[] longOut = new long[4];
14446        final int[] SINGLE_LONG_FORMAT = new int[] {
14447            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14448        };
14449        long[] longTmp = new long[1];
14450        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14451                SINGLE_LONG_FORMAT, null, longTmp, null);
14452        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14453        longTmp[0] = 0;
14454        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14455                SINGLE_LONG_FORMAT, null, longTmp, null);
14456        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14457        longTmp[0] = 0;
14458        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14459                SINGLE_LONG_FORMAT, null, longTmp, null);
14460        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14461        longTmp[0] = 0;
14462        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14463                SINGLE_LONG_FORMAT, null, longTmp, null);
14464        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14465        return longOut;
14466    }
14467
14468    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14469            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14470        boolean dumpDetails = false;
14471        boolean dumpFullDetails = false;
14472        boolean dumpDalvik = false;
14473        boolean dumpSummaryOnly = false;
14474        boolean oomOnly = false;
14475        boolean isCompact = false;
14476        boolean localOnly = false;
14477        boolean packages = false;
14478
14479        int opti = 0;
14480        while (opti < args.length) {
14481            String opt = args[opti];
14482            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14483                break;
14484            }
14485            opti++;
14486            if ("-a".equals(opt)) {
14487                dumpDetails = true;
14488                dumpFullDetails = true;
14489                dumpDalvik = true;
14490            } else if ("-d".equals(opt)) {
14491                dumpDalvik = true;
14492            } else if ("-c".equals(opt)) {
14493                isCompact = true;
14494            } else if ("-s".equals(opt)) {
14495                dumpDetails = true;
14496                dumpSummaryOnly = true;
14497            } else if ("--oom".equals(opt)) {
14498                oomOnly = true;
14499            } else if ("--local".equals(opt)) {
14500                localOnly = true;
14501            } else if ("--package".equals(opt)) {
14502                packages = true;
14503            } else if ("-h".equals(opt)) {
14504                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14505                pw.println("  -a: include all available information for each process.");
14506                pw.println("  -d: include dalvik details.");
14507                pw.println("  -c: dump in a compact machine-parseable representation.");
14508                pw.println("  -s: dump only summary of application memory usage.");
14509                pw.println("  --oom: only show processes organized by oom adj.");
14510                pw.println("  --local: only collect details locally, don't call process.");
14511                pw.println("  --package: interpret process arg as package, dumping all");
14512                pw.println("             processes that have loaded that package.");
14513                pw.println("If [process] is specified it can be the name or ");
14514                pw.println("pid of a specific process to dump.");
14515                return;
14516            } else {
14517                pw.println("Unknown argument: " + opt + "; use -h for help");
14518            }
14519        }
14520
14521        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14522        long uptime = SystemClock.uptimeMillis();
14523        long realtime = SystemClock.elapsedRealtime();
14524        final long[] tmpLong = new long[1];
14525
14526        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14527        if (procs == null) {
14528            // No Java processes.  Maybe they want to print a native process.
14529            if (args != null && args.length > opti
14530                    && args[opti].charAt(0) != '-') {
14531                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14532                        = new ArrayList<ProcessCpuTracker.Stats>();
14533                updateCpuStatsNow();
14534                int findPid = -1;
14535                try {
14536                    findPid = Integer.parseInt(args[opti]);
14537                } catch (NumberFormatException e) {
14538                }
14539                synchronized (mProcessCpuTracker) {
14540                    final int N = mProcessCpuTracker.countStats();
14541                    for (int i=0; i<N; i++) {
14542                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14543                        if (st.pid == findPid || (st.baseName != null
14544                                && st.baseName.equals(args[opti]))) {
14545                            nativeProcs.add(st);
14546                        }
14547                    }
14548                }
14549                if (nativeProcs.size() > 0) {
14550                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14551                            isCompact);
14552                    Debug.MemoryInfo mi = null;
14553                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14554                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14555                        final int pid = r.pid;
14556                        if (!isCheckinRequest && dumpDetails) {
14557                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14558                        }
14559                        if (mi == null) {
14560                            mi = new Debug.MemoryInfo();
14561                        }
14562                        if (dumpDetails || (!brief && !oomOnly)) {
14563                            Debug.getMemoryInfo(pid, mi);
14564                        } else {
14565                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14566                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14567                        }
14568                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14569                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14570                        if (isCheckinRequest) {
14571                            pw.println();
14572                        }
14573                    }
14574                    return;
14575                }
14576            }
14577            pw.println("No process found for: " + args[opti]);
14578            return;
14579        }
14580
14581        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14582            dumpDetails = true;
14583        }
14584
14585        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14586
14587        String[] innerArgs = new String[args.length-opti];
14588        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14589
14590        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14591        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14592        long nativePss = 0;
14593        long dalvikPss = 0;
14594        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14595                EmptyArray.LONG;
14596        long otherPss = 0;
14597        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14598
14599        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14600        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14601                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14602
14603        long totalPss = 0;
14604        long cachedPss = 0;
14605
14606        Debug.MemoryInfo mi = null;
14607        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14608            final ProcessRecord r = procs.get(i);
14609            final IApplicationThread thread;
14610            final int pid;
14611            final int oomAdj;
14612            final boolean hasActivities;
14613            synchronized (this) {
14614                thread = r.thread;
14615                pid = r.pid;
14616                oomAdj = r.getSetAdjWithServices();
14617                hasActivities = r.activities.size() > 0;
14618            }
14619            if (thread != null) {
14620                if (!isCheckinRequest && dumpDetails) {
14621                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14622                }
14623                if (mi == null) {
14624                    mi = new Debug.MemoryInfo();
14625                }
14626                if (dumpDetails || (!brief && !oomOnly)) {
14627                    Debug.getMemoryInfo(pid, mi);
14628                } else {
14629                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14630                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14631                }
14632                if (dumpDetails) {
14633                    if (localOnly) {
14634                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14635                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14636                        if (isCheckinRequest) {
14637                            pw.println();
14638                        }
14639                    } else {
14640                        try {
14641                            pw.flush();
14642                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14643                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14644                        } catch (RemoteException e) {
14645                            if (!isCheckinRequest) {
14646                                pw.println("Got RemoteException!");
14647                                pw.flush();
14648                            }
14649                        }
14650                    }
14651                }
14652
14653                final long myTotalPss = mi.getTotalPss();
14654                final long myTotalUss = mi.getTotalUss();
14655
14656                synchronized (this) {
14657                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14658                        // Record this for posterity if the process has been stable.
14659                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14660                    }
14661                }
14662
14663                if (!isCheckinRequest && mi != null) {
14664                    totalPss += myTotalPss;
14665                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14666                            (hasActivities ? " / activities)" : ")"),
14667                            r.processName, myTotalPss, pid, hasActivities);
14668                    procMems.add(pssItem);
14669                    procMemsMap.put(pid, pssItem);
14670
14671                    nativePss += mi.nativePss;
14672                    dalvikPss += mi.dalvikPss;
14673                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14674                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14675                    }
14676                    otherPss += mi.otherPss;
14677                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14678                        long mem = mi.getOtherPss(j);
14679                        miscPss[j] += mem;
14680                        otherPss -= mem;
14681                    }
14682
14683                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14684                        cachedPss += myTotalPss;
14685                    }
14686
14687                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14688                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14689                                || oomIndex == (oomPss.length-1)) {
14690                            oomPss[oomIndex] += myTotalPss;
14691                            if (oomProcs[oomIndex] == null) {
14692                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14693                            }
14694                            oomProcs[oomIndex].add(pssItem);
14695                            break;
14696                        }
14697                    }
14698                }
14699            }
14700        }
14701
14702        long nativeProcTotalPss = 0;
14703
14704        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14705            // If we are showing aggregations, also look for native processes to
14706            // include so that our aggregations are more accurate.
14707            updateCpuStatsNow();
14708            mi = null;
14709            synchronized (mProcessCpuTracker) {
14710                final int N = mProcessCpuTracker.countStats();
14711                for (int i=0; i<N; i++) {
14712                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14713                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14714                        if (mi == null) {
14715                            mi = new Debug.MemoryInfo();
14716                        }
14717                        if (!brief && !oomOnly) {
14718                            Debug.getMemoryInfo(st.pid, mi);
14719                        } else {
14720                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14721                            mi.nativePrivateDirty = (int)tmpLong[0];
14722                        }
14723
14724                        final long myTotalPss = mi.getTotalPss();
14725                        totalPss += myTotalPss;
14726                        nativeProcTotalPss += myTotalPss;
14727
14728                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14729                                st.name, myTotalPss, st.pid, false);
14730                        procMems.add(pssItem);
14731
14732                        nativePss += mi.nativePss;
14733                        dalvikPss += mi.dalvikPss;
14734                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14735                            dalvikSubitemPss[j] += mi.getOtherPss(
14736                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14737                        }
14738                        otherPss += mi.otherPss;
14739                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14740                            long mem = mi.getOtherPss(j);
14741                            miscPss[j] += mem;
14742                            otherPss -= mem;
14743                        }
14744                        oomPss[0] += myTotalPss;
14745                        if (oomProcs[0] == null) {
14746                            oomProcs[0] = new ArrayList<MemItem>();
14747                        }
14748                        oomProcs[0].add(pssItem);
14749                    }
14750                }
14751            }
14752
14753            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14754
14755            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14756            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14757            if (dalvikSubitemPss.length > 0) {
14758                dalvikItem.subitems = new ArrayList<MemItem>();
14759                for (int j=0; j<dalvikSubitemPss.length; j++) {
14760                    final String name = Debug.MemoryInfo.getOtherLabel(
14761                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14762                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14763                }
14764            }
14765            catMems.add(dalvikItem);
14766            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14767            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14768                String label = Debug.MemoryInfo.getOtherLabel(j);
14769                catMems.add(new MemItem(label, label, miscPss[j], j));
14770            }
14771
14772            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14773            for (int j=0; j<oomPss.length; j++) {
14774                if (oomPss[j] != 0) {
14775                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14776                            : DUMP_MEM_OOM_LABEL[j];
14777                    MemItem item = new MemItem(label, label, oomPss[j],
14778                            DUMP_MEM_OOM_ADJ[j]);
14779                    item.subitems = oomProcs[j];
14780                    oomMems.add(item);
14781                }
14782            }
14783
14784            if (!brief && !oomOnly && !isCompact) {
14785                pw.println();
14786                pw.println("Total PSS by process:");
14787                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14788                pw.println();
14789            }
14790            if (!isCompact) {
14791                pw.println("Total PSS by OOM adjustment:");
14792            }
14793            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14794            if (!brief && !oomOnly) {
14795                PrintWriter out = categoryPw != null ? categoryPw : pw;
14796                if (!isCompact) {
14797                    out.println();
14798                    out.println("Total PSS by category:");
14799                }
14800                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14801            }
14802            if (!isCompact) {
14803                pw.println();
14804            }
14805            MemInfoReader memInfo = new MemInfoReader();
14806            memInfo.readMemInfo();
14807            if (nativeProcTotalPss > 0) {
14808                synchronized (this) {
14809                    final long cachedKb = memInfo.getCachedSizeKb();
14810                    final long freeKb = memInfo.getFreeSizeKb();
14811                    final long zramKb = memInfo.getZramTotalSizeKb();
14812                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14813                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14814                            kernelKb*1024, nativeProcTotalPss*1024);
14815                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14816                            nativeProcTotalPss);
14817                }
14818            }
14819            if (!brief) {
14820                if (!isCompact) {
14821                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14822                    pw.print(" kB (status ");
14823                    switch (mLastMemoryLevel) {
14824                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14825                            pw.println("normal)");
14826                            break;
14827                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14828                            pw.println("moderate)");
14829                            break;
14830                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14831                            pw.println("low)");
14832                            break;
14833                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14834                            pw.println("critical)");
14835                            break;
14836                        default:
14837                            pw.print(mLastMemoryLevel);
14838                            pw.println(")");
14839                            break;
14840                    }
14841                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14842                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14843                            pw.print(cachedPss); pw.print(" cached pss + ");
14844                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14845                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14846                } else {
14847                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14848                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14849                            + memInfo.getFreeSizeKb()); pw.print(",");
14850                    pw.println(totalPss - cachedPss);
14851                }
14852            }
14853            if (!isCompact) {
14854                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14855                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14856                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14857                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14858                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14859                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14860                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14861            }
14862            if (!brief) {
14863                if (memInfo.getZramTotalSizeKb() != 0) {
14864                    if (!isCompact) {
14865                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14866                                pw.print(" kB physical used for ");
14867                                pw.print(memInfo.getSwapTotalSizeKb()
14868                                        - memInfo.getSwapFreeSizeKb());
14869                                pw.print(" kB in swap (");
14870                                pw.print(memInfo.getSwapTotalSizeKb());
14871                                pw.println(" kB total swap)");
14872                    } else {
14873                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14874                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14875                                pw.println(memInfo.getSwapFreeSizeKb());
14876                    }
14877                }
14878                final long[] ksm = getKsmInfo();
14879                if (!isCompact) {
14880                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14881                            || ksm[KSM_VOLATILE] != 0) {
14882                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14883                                pw.print(" kB saved from shared ");
14884                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14885                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14886                                pw.print(" kB unshared; ");
14887                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14888                    }
14889                    pw.print("   Tuning: ");
14890                    pw.print(ActivityManager.staticGetMemoryClass());
14891                    pw.print(" (large ");
14892                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14893                    pw.print("), oom ");
14894                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14895                    pw.print(" kB");
14896                    pw.print(", restore limit ");
14897                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14898                    pw.print(" kB");
14899                    if (ActivityManager.isLowRamDeviceStatic()) {
14900                        pw.print(" (low-ram)");
14901                    }
14902                    if (ActivityManager.isHighEndGfx()) {
14903                        pw.print(" (high-end-gfx)");
14904                    }
14905                    pw.println();
14906                } else {
14907                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14908                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14909                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14910                    pw.print("tuning,");
14911                    pw.print(ActivityManager.staticGetMemoryClass());
14912                    pw.print(',');
14913                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14914                    pw.print(',');
14915                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14916                    if (ActivityManager.isLowRamDeviceStatic()) {
14917                        pw.print(",low-ram");
14918                    }
14919                    if (ActivityManager.isHighEndGfx()) {
14920                        pw.print(",high-end-gfx");
14921                    }
14922                    pw.println();
14923                }
14924            }
14925        }
14926    }
14927
14928    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14929            long memtrack, String name) {
14930        sb.append("  ");
14931        sb.append(ProcessList.makeOomAdjString(oomAdj));
14932        sb.append(' ');
14933        sb.append(ProcessList.makeProcStateString(procState));
14934        sb.append(' ');
14935        ProcessList.appendRamKb(sb, pss);
14936        sb.append(" kB: ");
14937        sb.append(name);
14938        if (memtrack > 0) {
14939            sb.append(" (");
14940            sb.append(memtrack);
14941            sb.append(" kB memtrack)");
14942        }
14943    }
14944
14945    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14946        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14947        sb.append(" (pid ");
14948        sb.append(mi.pid);
14949        sb.append(") ");
14950        sb.append(mi.adjType);
14951        sb.append('\n');
14952        if (mi.adjReason != null) {
14953            sb.append("                      ");
14954            sb.append(mi.adjReason);
14955            sb.append('\n');
14956        }
14957    }
14958
14959    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14960        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14961        for (int i=0, N=memInfos.size(); i<N; i++) {
14962            ProcessMemInfo mi = memInfos.get(i);
14963            infoMap.put(mi.pid, mi);
14964        }
14965        updateCpuStatsNow();
14966        long[] memtrackTmp = new long[1];
14967        synchronized (mProcessCpuTracker) {
14968            final int N = mProcessCpuTracker.countStats();
14969            for (int i=0; i<N; i++) {
14970                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14971                if (st.vsize > 0) {
14972                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14973                    if (pss > 0) {
14974                        if (infoMap.indexOfKey(st.pid) < 0) {
14975                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14976                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14977                            mi.pss = pss;
14978                            mi.memtrack = memtrackTmp[0];
14979                            memInfos.add(mi);
14980                        }
14981                    }
14982                }
14983            }
14984        }
14985
14986        long totalPss = 0;
14987        long totalMemtrack = 0;
14988        for (int i=0, N=memInfos.size(); i<N; i++) {
14989            ProcessMemInfo mi = memInfos.get(i);
14990            if (mi.pss == 0) {
14991                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14992                mi.memtrack = memtrackTmp[0];
14993            }
14994            totalPss += mi.pss;
14995            totalMemtrack += mi.memtrack;
14996        }
14997        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14998            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14999                if (lhs.oomAdj != rhs.oomAdj) {
15000                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15001                }
15002                if (lhs.pss != rhs.pss) {
15003                    return lhs.pss < rhs.pss ? 1 : -1;
15004                }
15005                return 0;
15006            }
15007        });
15008
15009        StringBuilder tag = new StringBuilder(128);
15010        StringBuilder stack = new StringBuilder(128);
15011        tag.append("Low on memory -- ");
15012        appendMemBucket(tag, totalPss, "total", false);
15013        appendMemBucket(stack, totalPss, "total", true);
15014
15015        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15016        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15017        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15018
15019        boolean firstLine = true;
15020        int lastOomAdj = Integer.MIN_VALUE;
15021        long extraNativeRam = 0;
15022        long extraNativeMemtrack = 0;
15023        long cachedPss = 0;
15024        for (int i=0, N=memInfos.size(); i<N; i++) {
15025            ProcessMemInfo mi = memInfos.get(i);
15026
15027            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15028                cachedPss += mi.pss;
15029            }
15030
15031            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15032                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15033                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15034                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15035                if (lastOomAdj != mi.oomAdj) {
15036                    lastOomAdj = mi.oomAdj;
15037                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15038                        tag.append(" / ");
15039                    }
15040                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15041                        if (firstLine) {
15042                            stack.append(":");
15043                            firstLine = false;
15044                        }
15045                        stack.append("\n\t at ");
15046                    } else {
15047                        stack.append("$");
15048                    }
15049                } else {
15050                    tag.append(" ");
15051                    stack.append("$");
15052                }
15053                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15054                    appendMemBucket(tag, mi.pss, mi.name, false);
15055                }
15056                appendMemBucket(stack, mi.pss, mi.name, true);
15057                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15058                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15059                    stack.append("(");
15060                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15061                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15062                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15063                            stack.append(":");
15064                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15065                        }
15066                    }
15067                    stack.append(")");
15068                }
15069            }
15070
15071            appendMemInfo(fullNativeBuilder, mi);
15072            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15073                // The short form only has native processes that are >= 512K.
15074                if (mi.pss >= 512) {
15075                    appendMemInfo(shortNativeBuilder, mi);
15076                } else {
15077                    extraNativeRam += mi.pss;
15078                    extraNativeMemtrack += mi.memtrack;
15079                }
15080            } else {
15081                // Short form has all other details, but if we have collected RAM
15082                // from smaller native processes let's dump a summary of that.
15083                if (extraNativeRam > 0) {
15084                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15085                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15086                    shortNativeBuilder.append('\n');
15087                    extraNativeRam = 0;
15088                }
15089                appendMemInfo(fullJavaBuilder, mi);
15090            }
15091        }
15092
15093        fullJavaBuilder.append("           ");
15094        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15095        fullJavaBuilder.append(" kB: TOTAL");
15096        if (totalMemtrack > 0) {
15097            fullJavaBuilder.append(" (");
15098            fullJavaBuilder.append(totalMemtrack);
15099            fullJavaBuilder.append(" kB memtrack)");
15100        } else {
15101        }
15102        fullJavaBuilder.append("\n");
15103
15104        MemInfoReader memInfo = new MemInfoReader();
15105        memInfo.readMemInfo();
15106        final long[] infos = memInfo.getRawInfo();
15107
15108        StringBuilder memInfoBuilder = new StringBuilder(1024);
15109        Debug.getMemInfo(infos);
15110        memInfoBuilder.append("  MemInfo: ");
15111        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15112        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15113        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15114        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15115        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15116        memInfoBuilder.append("           ");
15117        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15118        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15119        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15120        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15121        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15122            memInfoBuilder.append("  ZRAM: ");
15123            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15124            memInfoBuilder.append(" kB RAM, ");
15125            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15126            memInfoBuilder.append(" kB swap total, ");
15127            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15128            memInfoBuilder.append(" kB swap free\n");
15129        }
15130        final long[] ksm = getKsmInfo();
15131        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15132                || ksm[KSM_VOLATILE] != 0) {
15133            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15134            memInfoBuilder.append(" kB saved from shared ");
15135            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15136            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15137            memInfoBuilder.append(" kB unshared; ");
15138            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15139        }
15140        memInfoBuilder.append("  Free RAM: ");
15141        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15142                + memInfo.getFreeSizeKb());
15143        memInfoBuilder.append(" kB\n");
15144        memInfoBuilder.append("  Used RAM: ");
15145        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15146        memInfoBuilder.append(" kB\n");
15147        memInfoBuilder.append("  Lost RAM: ");
15148        memInfoBuilder.append(memInfo.getTotalSizeKb()
15149                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15150                - memInfo.getKernelUsedSizeKb());
15151        memInfoBuilder.append(" kB\n");
15152        Slog.i(TAG, "Low on memory:");
15153        Slog.i(TAG, shortNativeBuilder.toString());
15154        Slog.i(TAG, fullJavaBuilder.toString());
15155        Slog.i(TAG, memInfoBuilder.toString());
15156
15157        StringBuilder dropBuilder = new StringBuilder(1024);
15158        /*
15159        StringWriter oomSw = new StringWriter();
15160        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15161        StringWriter catSw = new StringWriter();
15162        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15163        String[] emptyArgs = new String[] { };
15164        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15165        oomPw.flush();
15166        String oomString = oomSw.toString();
15167        */
15168        dropBuilder.append("Low on memory:");
15169        dropBuilder.append(stack);
15170        dropBuilder.append('\n');
15171        dropBuilder.append(fullNativeBuilder);
15172        dropBuilder.append(fullJavaBuilder);
15173        dropBuilder.append('\n');
15174        dropBuilder.append(memInfoBuilder);
15175        dropBuilder.append('\n');
15176        /*
15177        dropBuilder.append(oomString);
15178        dropBuilder.append('\n');
15179        */
15180        StringWriter catSw = new StringWriter();
15181        synchronized (ActivityManagerService.this) {
15182            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15183            String[] emptyArgs = new String[] { };
15184            catPw.println();
15185            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15186            catPw.println();
15187            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15188                    false, false, null);
15189            catPw.println();
15190            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15191            catPw.flush();
15192        }
15193        dropBuilder.append(catSw.toString());
15194        addErrorToDropBox("lowmem", null, "system_server", null,
15195                null, tag.toString(), dropBuilder.toString(), null, null);
15196        //Slog.i(TAG, "Sent to dropbox:");
15197        //Slog.i(TAG, dropBuilder.toString());
15198        synchronized (ActivityManagerService.this) {
15199            long now = SystemClock.uptimeMillis();
15200            if (mLastMemUsageReportTime < now) {
15201                mLastMemUsageReportTime = now;
15202            }
15203        }
15204    }
15205
15206    /**
15207     * Searches array of arguments for the specified string
15208     * @param args array of argument strings
15209     * @param value value to search for
15210     * @return true if the value is contained in the array
15211     */
15212    private static boolean scanArgs(String[] args, String value) {
15213        if (args != null) {
15214            for (String arg : args) {
15215                if (value.equals(arg)) {
15216                    return true;
15217                }
15218            }
15219        }
15220        return false;
15221    }
15222
15223    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15224            ContentProviderRecord cpr, boolean always) {
15225        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15226
15227        if (!inLaunching || always) {
15228            synchronized (cpr) {
15229                cpr.launchingApp = null;
15230                cpr.notifyAll();
15231            }
15232            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15233            String names[] = cpr.info.authority.split(";");
15234            for (int j = 0; j < names.length; j++) {
15235                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15236            }
15237        }
15238
15239        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15240            ContentProviderConnection conn = cpr.connections.get(i);
15241            if (conn.waiting) {
15242                // If this connection is waiting for the provider, then we don't
15243                // need to mess with its process unless we are always removing
15244                // or for some reason the provider is not currently launching.
15245                if (inLaunching && !always) {
15246                    continue;
15247                }
15248            }
15249            ProcessRecord capp = conn.client;
15250            conn.dead = true;
15251            if (conn.stableCount > 0) {
15252                if (!capp.persistent && capp.thread != null
15253                        && capp.pid != 0
15254                        && capp.pid != MY_PID) {
15255                    capp.kill("depends on provider "
15256                            + cpr.name.flattenToShortString()
15257                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15258                }
15259            } else if (capp.thread != null && conn.provider.provider != null) {
15260                try {
15261                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15262                } catch (RemoteException e) {
15263                }
15264                // In the protocol here, we don't expect the client to correctly
15265                // clean up this connection, we'll just remove it.
15266                cpr.connections.remove(i);
15267                if (conn.client.conProviders.remove(conn)) {
15268                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15269                }
15270            }
15271        }
15272
15273        if (inLaunching && always) {
15274            mLaunchingProviders.remove(cpr);
15275        }
15276        return inLaunching;
15277    }
15278
15279    /**
15280     * Main code for cleaning up a process when it has gone away.  This is
15281     * called both as a result of the process dying, or directly when stopping
15282     * a process when running in single process mode.
15283     *
15284     * @return Returns true if the given process has been restarted, so the
15285     * app that was passed in must remain on the process lists.
15286     */
15287    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15288            boolean restarting, boolean allowRestart, int index) {
15289        if (index >= 0) {
15290            removeLruProcessLocked(app);
15291            ProcessList.remove(app.pid);
15292        }
15293
15294        mProcessesToGc.remove(app);
15295        mPendingPssProcesses.remove(app);
15296
15297        // Dismiss any open dialogs.
15298        if (app.crashDialog != null && !app.forceCrashReport) {
15299            app.crashDialog.dismiss();
15300            app.crashDialog = null;
15301        }
15302        if (app.anrDialog != null) {
15303            app.anrDialog.dismiss();
15304            app.anrDialog = null;
15305        }
15306        if (app.waitDialog != null) {
15307            app.waitDialog.dismiss();
15308            app.waitDialog = null;
15309        }
15310
15311        app.crashing = false;
15312        app.notResponding = false;
15313
15314        app.resetPackageList(mProcessStats);
15315        app.unlinkDeathRecipient();
15316        app.makeInactive(mProcessStats);
15317        app.waitingToKill = null;
15318        app.forcingToForeground = null;
15319        updateProcessForegroundLocked(app, false, false);
15320        app.foregroundActivities = false;
15321        app.hasShownUi = false;
15322        app.treatLikeActivity = false;
15323        app.hasAboveClient = false;
15324        app.hasClientActivities = false;
15325
15326        mServices.killServicesLocked(app, allowRestart);
15327
15328        boolean restart = false;
15329
15330        // Remove published content providers.
15331        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15332            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15333            final boolean always = app.bad || !allowRestart;
15334            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15335            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15336                // We left the provider in the launching list, need to
15337                // restart it.
15338                restart = true;
15339            }
15340
15341            cpr.provider = null;
15342            cpr.proc = null;
15343        }
15344        app.pubProviders.clear();
15345
15346        // Take care of any launching providers waiting for this process.
15347        if (checkAppInLaunchingProvidersLocked(app, false)) {
15348            restart = true;
15349        }
15350
15351        // Unregister from connected content providers.
15352        if (!app.conProviders.isEmpty()) {
15353            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15354                ContentProviderConnection conn = app.conProviders.get(i);
15355                conn.provider.connections.remove(conn);
15356                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15357                        conn.provider.name);
15358            }
15359            app.conProviders.clear();
15360        }
15361
15362        // At this point there may be remaining entries in mLaunchingProviders
15363        // where we were the only one waiting, so they are no longer of use.
15364        // Look for these and clean up if found.
15365        // XXX Commented out for now.  Trying to figure out a way to reproduce
15366        // the actual situation to identify what is actually going on.
15367        if (false) {
15368            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15369                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15370                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15371                    synchronized (cpr) {
15372                        cpr.launchingApp = null;
15373                        cpr.notifyAll();
15374                    }
15375                }
15376            }
15377        }
15378
15379        skipCurrentReceiverLocked(app);
15380
15381        // Unregister any receivers.
15382        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15383            removeReceiverLocked(app.receivers.valueAt(i));
15384        }
15385        app.receivers.clear();
15386
15387        // If the app is undergoing backup, tell the backup manager about it
15388        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15389            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15390                    + mBackupTarget.appInfo + " died during backup");
15391            try {
15392                IBackupManager bm = IBackupManager.Stub.asInterface(
15393                        ServiceManager.getService(Context.BACKUP_SERVICE));
15394                bm.agentDisconnected(app.info.packageName);
15395            } catch (RemoteException e) {
15396                // can't happen; backup manager is local
15397            }
15398        }
15399
15400        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15401            ProcessChangeItem item = mPendingProcessChanges.get(i);
15402            if (item.pid == app.pid) {
15403                mPendingProcessChanges.remove(i);
15404                mAvailProcessChanges.add(item);
15405            }
15406        }
15407        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15408
15409        // If the caller is restarting this app, then leave it in its
15410        // current lists and let the caller take care of it.
15411        if (restarting) {
15412            return false;
15413        }
15414
15415        if (!app.persistent || app.isolated) {
15416            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15417                    "Removing non-persistent process during cleanup: " + app);
15418            removeProcessNameLocked(app.processName, app.uid);
15419            if (mHeavyWeightProcess == app) {
15420                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15421                        mHeavyWeightProcess.userId, 0));
15422                mHeavyWeightProcess = null;
15423            }
15424        } else if (!app.removed) {
15425            // This app is persistent, so we need to keep its record around.
15426            // If it is not already on the pending app list, add it there
15427            // and start a new process for it.
15428            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15429                mPersistentStartingProcesses.add(app);
15430                restart = true;
15431            }
15432        }
15433        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15434                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15435        mProcessesOnHold.remove(app);
15436
15437        if (app == mHomeProcess) {
15438            mHomeProcess = null;
15439        }
15440        if (app == mPreviousProcess) {
15441            mPreviousProcess = null;
15442        }
15443
15444        if (restart && !app.isolated) {
15445            // We have components that still need to be running in the
15446            // process, so re-launch it.
15447            if (index < 0) {
15448                ProcessList.remove(app.pid);
15449            }
15450            addProcessNameLocked(app);
15451            startProcessLocked(app, "restart", app.processName);
15452            return true;
15453        } else if (app.pid > 0 && app.pid != MY_PID) {
15454            // Goodbye!
15455            boolean removed;
15456            synchronized (mPidsSelfLocked) {
15457                mPidsSelfLocked.remove(app.pid);
15458                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15459            }
15460            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15461            if (app.isolated) {
15462                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15463            }
15464            app.setPid(0);
15465        }
15466        return false;
15467    }
15468
15469    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15470        // Look through the content providers we are waiting to have launched,
15471        // and if any run in this process then either schedule a restart of
15472        // the process or kill the client waiting for it if this process has
15473        // gone bad.
15474        boolean restart = false;
15475        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15476            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15477            if (cpr.launchingApp == app) {
15478                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15479                    restart = true;
15480                } else {
15481                    removeDyingProviderLocked(app, cpr, true);
15482                }
15483            }
15484        }
15485        return restart;
15486    }
15487
15488    // =========================================================
15489    // SERVICES
15490    // =========================================================
15491
15492    @Override
15493    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15494            int flags) {
15495        enforceNotIsolatedCaller("getServices");
15496        synchronized (this) {
15497            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15498        }
15499    }
15500
15501    @Override
15502    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15503        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15504        synchronized (this) {
15505            return mServices.getRunningServiceControlPanelLocked(name);
15506        }
15507    }
15508
15509    @Override
15510    public ComponentName startService(IApplicationThread caller, Intent service,
15511            String resolvedType, int userId) throws TransactionTooLargeException {
15512        enforceNotIsolatedCaller("startService");
15513        // Refuse possible leaked file descriptors
15514        if (service != null && service.hasFileDescriptors() == true) {
15515            throw new IllegalArgumentException("File descriptors passed in Intent");
15516        }
15517
15518        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15519                "startService: " + service + " type=" + resolvedType);
15520        synchronized(this) {
15521            final int callingPid = Binder.getCallingPid();
15522            final int callingUid = Binder.getCallingUid();
15523            final long origId = Binder.clearCallingIdentity();
15524            ComponentName res = mServices.startServiceLocked(caller, service,
15525                    resolvedType, callingPid, callingUid, userId);
15526            Binder.restoreCallingIdentity(origId);
15527            return res;
15528        }
15529    }
15530
15531    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15532            throws TransactionTooLargeException {
15533        synchronized(this) {
15534            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15535                    "startServiceInPackage: " + service + " type=" + resolvedType);
15536            final long origId = Binder.clearCallingIdentity();
15537            ComponentName res = mServices.startServiceLocked(null, service,
15538                    resolvedType, -1, uid, userId);
15539            Binder.restoreCallingIdentity(origId);
15540            return res;
15541        }
15542    }
15543
15544    @Override
15545    public int stopService(IApplicationThread caller, Intent service,
15546            String resolvedType, int userId) {
15547        enforceNotIsolatedCaller("stopService");
15548        // Refuse possible leaked file descriptors
15549        if (service != null && service.hasFileDescriptors() == true) {
15550            throw new IllegalArgumentException("File descriptors passed in Intent");
15551        }
15552
15553        synchronized(this) {
15554            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15555        }
15556    }
15557
15558    @Override
15559    public IBinder peekService(Intent service, String resolvedType) {
15560        enforceNotIsolatedCaller("peekService");
15561        // Refuse possible leaked file descriptors
15562        if (service != null && service.hasFileDescriptors() == true) {
15563            throw new IllegalArgumentException("File descriptors passed in Intent");
15564        }
15565        synchronized(this) {
15566            return mServices.peekServiceLocked(service, resolvedType);
15567        }
15568    }
15569
15570    @Override
15571    public boolean stopServiceToken(ComponentName className, IBinder token,
15572            int startId) {
15573        synchronized(this) {
15574            return mServices.stopServiceTokenLocked(className, token, startId);
15575        }
15576    }
15577
15578    @Override
15579    public void setServiceForeground(ComponentName className, IBinder token,
15580            int id, Notification notification, boolean removeNotification) {
15581        synchronized(this) {
15582            mServices.setServiceForegroundLocked(className, token, id, notification,
15583                    removeNotification);
15584        }
15585    }
15586
15587    @Override
15588    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15589            boolean requireFull, String name, String callerPackage) {
15590        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15591                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15592    }
15593
15594    int unsafeConvertIncomingUser(int userId) {
15595        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15596                ? mCurrentUserId : userId;
15597    }
15598
15599    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15600            int allowMode, String name, String callerPackage) {
15601        final int callingUserId = UserHandle.getUserId(callingUid);
15602        if (callingUserId == userId) {
15603            return userId;
15604        }
15605
15606        // Note that we may be accessing mCurrentUserId outside of a lock...
15607        // shouldn't be a big deal, if this is being called outside
15608        // of a locked context there is intrinsically a race with
15609        // the value the caller will receive and someone else changing it.
15610        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15611        // we will switch to the calling user if access to the current user fails.
15612        int targetUserId = unsafeConvertIncomingUser(userId);
15613
15614        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15615            final boolean allow;
15616            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15617                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15618                // If the caller has this permission, they always pass go.  And collect $200.
15619                allow = true;
15620            } else if (allowMode == ALLOW_FULL_ONLY) {
15621                // We require full access, sucks to be you.
15622                allow = false;
15623            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15624                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15625                // If the caller does not have either permission, they are always doomed.
15626                allow = false;
15627            } else if (allowMode == ALLOW_NON_FULL) {
15628                // We are blanket allowing non-full access, you lucky caller!
15629                allow = true;
15630            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15631                // We may or may not allow this depending on whether the two users are
15632                // in the same profile.
15633                synchronized (mUserProfileGroupIdsSelfLocked) {
15634                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15635                            UserInfo.NO_PROFILE_GROUP_ID);
15636                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15637                            UserInfo.NO_PROFILE_GROUP_ID);
15638                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15639                            && callingProfile == targetProfile;
15640                }
15641            } else {
15642                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15643            }
15644            if (!allow) {
15645                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15646                    // In this case, they would like to just execute as their
15647                    // owner user instead of failing.
15648                    targetUserId = callingUserId;
15649                } else {
15650                    StringBuilder builder = new StringBuilder(128);
15651                    builder.append("Permission Denial: ");
15652                    builder.append(name);
15653                    if (callerPackage != null) {
15654                        builder.append(" from ");
15655                        builder.append(callerPackage);
15656                    }
15657                    builder.append(" asks to run as user ");
15658                    builder.append(userId);
15659                    builder.append(" but is calling from user ");
15660                    builder.append(UserHandle.getUserId(callingUid));
15661                    builder.append("; this requires ");
15662                    builder.append(INTERACT_ACROSS_USERS_FULL);
15663                    if (allowMode != ALLOW_FULL_ONLY) {
15664                        builder.append(" or ");
15665                        builder.append(INTERACT_ACROSS_USERS);
15666                    }
15667                    String msg = builder.toString();
15668                    Slog.w(TAG, msg);
15669                    throw new SecurityException(msg);
15670                }
15671            }
15672        }
15673        if (!allowAll && targetUserId < 0) {
15674            throw new IllegalArgumentException(
15675                    "Call does not support special user #" + targetUserId);
15676        }
15677        // Check shell permission
15678        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15679            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15680                    targetUserId)) {
15681                throw new SecurityException("Shell does not have permission to access user "
15682                        + targetUserId + "\n " + Debug.getCallers(3));
15683            }
15684        }
15685        return targetUserId;
15686    }
15687
15688    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15689            String className, int flags) {
15690        boolean result = false;
15691        // For apps that don't have pre-defined UIDs, check for permission
15692        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15693            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15694                if (ActivityManager.checkUidPermission(
15695                        INTERACT_ACROSS_USERS,
15696                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15697                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15698                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15699                            + " requests FLAG_SINGLE_USER, but app does not hold "
15700                            + INTERACT_ACROSS_USERS;
15701                    Slog.w(TAG, msg);
15702                    throw new SecurityException(msg);
15703                }
15704                // Permission passed
15705                result = true;
15706            }
15707        } else if ("system".equals(componentProcessName)) {
15708            result = true;
15709        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15710            // Phone app and persistent apps are allowed to export singleuser providers.
15711            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15712                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15713        }
15714        if (DEBUG_MU) Slog.v(TAG_MU,
15715                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15716                + Integer.toHexString(flags) + ") = " + result);
15717        return result;
15718    }
15719
15720    /**
15721     * Checks to see if the caller is in the same app as the singleton
15722     * component, or the component is in a special app. It allows special apps
15723     * to export singleton components but prevents exporting singleton
15724     * components for regular apps.
15725     */
15726    boolean isValidSingletonCall(int callingUid, int componentUid) {
15727        int componentAppId = UserHandle.getAppId(componentUid);
15728        return UserHandle.isSameApp(callingUid, componentUid)
15729                || componentAppId == Process.SYSTEM_UID
15730                || componentAppId == Process.PHONE_UID
15731                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15732                        == PackageManager.PERMISSION_GRANTED;
15733    }
15734
15735    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15736            String resolvedType, IServiceConnection connection, int flags, int userId)
15737            throws TransactionTooLargeException {
15738        enforceNotIsolatedCaller("bindService");
15739
15740        // Refuse possible leaked file descriptors
15741        if (service != null && service.hasFileDescriptors() == true) {
15742            throw new IllegalArgumentException("File descriptors passed in Intent");
15743        }
15744
15745        synchronized(this) {
15746            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15747                    connection, flags, userId);
15748        }
15749    }
15750
15751    public boolean unbindService(IServiceConnection connection) {
15752        synchronized (this) {
15753            return mServices.unbindServiceLocked(connection);
15754        }
15755    }
15756
15757    public void publishService(IBinder token, Intent intent, IBinder service) {
15758        // Refuse possible leaked file descriptors
15759        if (intent != null && intent.hasFileDescriptors() == true) {
15760            throw new IllegalArgumentException("File descriptors passed in Intent");
15761        }
15762
15763        synchronized(this) {
15764            if (!(token instanceof ServiceRecord)) {
15765                throw new IllegalArgumentException("Invalid service token");
15766            }
15767            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15768        }
15769    }
15770
15771    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15772        // Refuse possible leaked file descriptors
15773        if (intent != null && intent.hasFileDescriptors() == true) {
15774            throw new IllegalArgumentException("File descriptors passed in Intent");
15775        }
15776
15777        synchronized(this) {
15778            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15779        }
15780    }
15781
15782    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15783        synchronized(this) {
15784            if (!(token instanceof ServiceRecord)) {
15785                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15786                throw new IllegalArgumentException("Invalid service token");
15787            }
15788            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15789        }
15790    }
15791
15792    // =========================================================
15793    // BACKUP AND RESTORE
15794    // =========================================================
15795
15796    // Cause the target app to be launched if necessary and its backup agent
15797    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15798    // activity manager to announce its creation.
15799    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15800        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15801                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15802        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15803
15804        synchronized(this) {
15805            // !!! TODO: currently no check here that we're already bound
15806            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15807            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15808            synchronized (stats) {
15809                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15810            }
15811
15812            // Backup agent is now in use, its package can't be stopped.
15813            try {
15814                AppGlobals.getPackageManager().setPackageStoppedState(
15815                        app.packageName, false, UserHandle.getUserId(app.uid));
15816            } catch (RemoteException e) {
15817            } catch (IllegalArgumentException e) {
15818                Slog.w(TAG, "Failed trying to unstop package "
15819                        + app.packageName + ": " + e);
15820            }
15821
15822            BackupRecord r = new BackupRecord(ss, app, backupMode);
15823            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15824                    ? new ComponentName(app.packageName, app.backupAgentName)
15825                    : new ComponentName("android", "FullBackupAgent");
15826            // startProcessLocked() returns existing proc's record if it's already running
15827            ProcessRecord proc = startProcessLocked(app.processName, app,
15828                    false, 0, "backup", hostingName, false, false, false);
15829            if (proc == null) {
15830                Slog.e(TAG, "Unable to start backup agent process " + r);
15831                return false;
15832            }
15833
15834            r.app = proc;
15835            mBackupTarget = r;
15836            mBackupAppName = app.packageName;
15837
15838            // Try not to kill the process during backup
15839            updateOomAdjLocked(proc);
15840
15841            // If the process is already attached, schedule the creation of the backup agent now.
15842            // If it is not yet live, this will be done when it attaches to the framework.
15843            if (proc.thread != null) {
15844                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15845                try {
15846                    proc.thread.scheduleCreateBackupAgent(app,
15847                            compatibilityInfoForPackageLocked(app), backupMode);
15848                } catch (RemoteException e) {
15849                    // Will time out on the backup manager side
15850                }
15851            } else {
15852                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15853            }
15854            // Invariants: at this point, the target app process exists and the application
15855            // is either already running or in the process of coming up.  mBackupTarget and
15856            // mBackupAppName describe the app, so that when it binds back to the AM we
15857            // know that it's scheduled for a backup-agent operation.
15858        }
15859
15860        return true;
15861    }
15862
15863    @Override
15864    public void clearPendingBackup() {
15865        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15866        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15867
15868        synchronized (this) {
15869            mBackupTarget = null;
15870            mBackupAppName = null;
15871        }
15872    }
15873
15874    // A backup agent has just come up
15875    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15876        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15877                + " = " + agent);
15878
15879        synchronized(this) {
15880            if (!agentPackageName.equals(mBackupAppName)) {
15881                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15882                return;
15883            }
15884        }
15885
15886        long oldIdent = Binder.clearCallingIdentity();
15887        try {
15888            IBackupManager bm = IBackupManager.Stub.asInterface(
15889                    ServiceManager.getService(Context.BACKUP_SERVICE));
15890            bm.agentConnected(agentPackageName, agent);
15891        } catch (RemoteException e) {
15892            // can't happen; the backup manager service is local
15893        } catch (Exception e) {
15894            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15895            e.printStackTrace();
15896        } finally {
15897            Binder.restoreCallingIdentity(oldIdent);
15898        }
15899    }
15900
15901    // done with this agent
15902    public void unbindBackupAgent(ApplicationInfo appInfo) {
15903        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15904        if (appInfo == null) {
15905            Slog.w(TAG, "unbind backup agent for null app");
15906            return;
15907        }
15908
15909        synchronized(this) {
15910            try {
15911                if (mBackupAppName == null) {
15912                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15913                    return;
15914                }
15915
15916                if (!mBackupAppName.equals(appInfo.packageName)) {
15917                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15918                    return;
15919                }
15920
15921                // Not backing this app up any more; reset its OOM adjustment
15922                final ProcessRecord proc = mBackupTarget.app;
15923                updateOomAdjLocked(proc);
15924
15925                // If the app crashed during backup, 'thread' will be null here
15926                if (proc.thread != null) {
15927                    try {
15928                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15929                                compatibilityInfoForPackageLocked(appInfo));
15930                    } catch (Exception e) {
15931                        Slog.e(TAG, "Exception when unbinding backup agent:");
15932                        e.printStackTrace();
15933                    }
15934                }
15935            } finally {
15936                mBackupTarget = null;
15937                mBackupAppName = null;
15938            }
15939        }
15940    }
15941    // =========================================================
15942    // BROADCASTS
15943    // =========================================================
15944
15945    boolean isPendingBroadcastProcessLocked(int pid) {
15946        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15947                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15948    }
15949
15950    void skipPendingBroadcastLocked(int pid) {
15951            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15952            for (BroadcastQueue queue : mBroadcastQueues) {
15953                queue.skipPendingBroadcastLocked(pid);
15954            }
15955    }
15956
15957    // The app just attached; send any pending broadcasts that it should receive
15958    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15959        boolean didSomething = false;
15960        for (BroadcastQueue queue : mBroadcastQueues) {
15961            didSomething |= queue.sendPendingBroadcastsLocked(app);
15962        }
15963        return didSomething;
15964    }
15965
15966    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15967            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15968        enforceNotIsolatedCaller("registerReceiver");
15969        ArrayList<Intent> stickyIntents = null;
15970        ProcessRecord callerApp = null;
15971        int callingUid;
15972        int callingPid;
15973        synchronized(this) {
15974            if (caller != null) {
15975                callerApp = getRecordForAppLocked(caller);
15976                if (callerApp == null) {
15977                    throw new SecurityException(
15978                            "Unable to find app for caller " + caller
15979                            + " (pid=" + Binder.getCallingPid()
15980                            + ") when registering receiver " + receiver);
15981                }
15982                if (callerApp.info.uid != Process.SYSTEM_UID &&
15983                        !callerApp.pkgList.containsKey(callerPackage) &&
15984                        !"android".equals(callerPackage)) {
15985                    throw new SecurityException("Given caller package " + callerPackage
15986                            + " is not running in process " + callerApp);
15987                }
15988                callingUid = callerApp.info.uid;
15989                callingPid = callerApp.pid;
15990            } else {
15991                callerPackage = null;
15992                callingUid = Binder.getCallingUid();
15993                callingPid = Binder.getCallingPid();
15994            }
15995
15996            userId = handleIncomingUser(callingPid, callingUid, userId,
15997                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15998
15999            Iterator<String> actions = filter.actionsIterator();
16000            if (actions == null) {
16001                ArrayList<String> noAction = new ArrayList<String>(1);
16002                noAction.add(null);
16003                actions = noAction.iterator();
16004            }
16005
16006            // Collect stickies of users
16007            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16008            while (actions.hasNext()) {
16009                String action = actions.next();
16010                for (int id : userIds) {
16011                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16012                    if (stickies != null) {
16013                        ArrayList<Intent> intents = stickies.get(action);
16014                        if (intents != null) {
16015                            if (stickyIntents == null) {
16016                                stickyIntents = new ArrayList<Intent>();
16017                            }
16018                            stickyIntents.addAll(intents);
16019                        }
16020                    }
16021                }
16022            }
16023        }
16024
16025        ArrayList<Intent> allSticky = null;
16026        if (stickyIntents != null) {
16027            final ContentResolver resolver = mContext.getContentResolver();
16028            // Look for any matching sticky broadcasts...
16029            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16030                Intent intent = stickyIntents.get(i);
16031                // If intent has scheme "content", it will need to acccess
16032                // provider that needs to lock mProviderMap in ActivityThread
16033                // and also it may need to wait application response, so we
16034                // cannot lock ActivityManagerService here.
16035                if (filter.match(resolver, intent, true, TAG) >= 0) {
16036                    if (allSticky == null) {
16037                        allSticky = new ArrayList<Intent>();
16038                    }
16039                    allSticky.add(intent);
16040                }
16041            }
16042        }
16043
16044        // The first sticky in the list is returned directly back to the client.
16045        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16046        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16047        if (receiver == null) {
16048            return sticky;
16049        }
16050
16051        synchronized (this) {
16052            if (callerApp != null && (callerApp.thread == null
16053                    || callerApp.thread.asBinder() != caller.asBinder())) {
16054                // Original caller already died
16055                return null;
16056            }
16057            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16058            if (rl == null) {
16059                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16060                        userId, receiver);
16061                if (rl.app != null) {
16062                    rl.app.receivers.add(rl);
16063                } else {
16064                    try {
16065                        receiver.asBinder().linkToDeath(rl, 0);
16066                    } catch (RemoteException e) {
16067                        return sticky;
16068                    }
16069                    rl.linkedToDeath = true;
16070                }
16071                mRegisteredReceivers.put(receiver.asBinder(), rl);
16072            } else if (rl.uid != callingUid) {
16073                throw new IllegalArgumentException(
16074                        "Receiver requested to register for uid " + callingUid
16075                        + " was previously registered for uid " + rl.uid);
16076            } else if (rl.pid != callingPid) {
16077                throw new IllegalArgumentException(
16078                        "Receiver requested to register for pid " + callingPid
16079                        + " was previously registered for pid " + rl.pid);
16080            } else if (rl.userId != userId) {
16081                throw new IllegalArgumentException(
16082                        "Receiver requested to register for user " + userId
16083                        + " was previously registered for user " + rl.userId);
16084            }
16085            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16086                    permission, callingUid, userId);
16087            rl.add(bf);
16088            if (!bf.debugCheck()) {
16089                Slog.w(TAG, "==> For Dynamic broadcast");
16090            }
16091            mReceiverResolver.addFilter(bf);
16092
16093            // Enqueue broadcasts for all existing stickies that match
16094            // this filter.
16095            if (allSticky != null) {
16096                ArrayList receivers = new ArrayList();
16097                receivers.add(bf);
16098
16099                final int stickyCount = allSticky.size();
16100                for (int i = 0; i < stickyCount; i++) {
16101                    Intent intent = allSticky.get(i);
16102                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16103                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16104                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
16105                            null, null, false, true, true, -1);
16106                    queue.enqueueParallelBroadcastLocked(r);
16107                    queue.scheduleBroadcastsLocked();
16108                }
16109            }
16110
16111            return sticky;
16112        }
16113    }
16114
16115    public void unregisterReceiver(IIntentReceiver receiver) {
16116        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16117
16118        final long origId = Binder.clearCallingIdentity();
16119        try {
16120            boolean doTrim = false;
16121
16122            synchronized(this) {
16123                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16124                if (rl != null) {
16125                    final BroadcastRecord r = rl.curBroadcast;
16126                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16127                        final boolean doNext = r.queue.finishReceiverLocked(
16128                                r, r.resultCode, r.resultData, r.resultExtras,
16129                                r.resultAbort, false);
16130                        if (doNext) {
16131                            doTrim = true;
16132                            r.queue.processNextBroadcast(false);
16133                        }
16134                    }
16135
16136                    if (rl.app != null) {
16137                        rl.app.receivers.remove(rl);
16138                    }
16139                    removeReceiverLocked(rl);
16140                    if (rl.linkedToDeath) {
16141                        rl.linkedToDeath = false;
16142                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16143                    }
16144                }
16145            }
16146
16147            // If we actually concluded any broadcasts, we might now be able
16148            // to trim the recipients' apps from our working set
16149            if (doTrim) {
16150                trimApplications();
16151                return;
16152            }
16153
16154        } finally {
16155            Binder.restoreCallingIdentity(origId);
16156        }
16157    }
16158
16159    void removeReceiverLocked(ReceiverList rl) {
16160        mRegisteredReceivers.remove(rl.receiver.asBinder());
16161        for (int i = rl.size() - 1; i >= 0; i--) {
16162            mReceiverResolver.removeFilter(rl.get(i));
16163        }
16164    }
16165
16166    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16167        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16168            ProcessRecord r = mLruProcesses.get(i);
16169            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16170                try {
16171                    r.thread.dispatchPackageBroadcast(cmd, packages);
16172                } catch (RemoteException ex) {
16173                }
16174            }
16175        }
16176    }
16177
16178    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16179            int callingUid, int[] users) {
16180        List<ResolveInfo> receivers = null;
16181        try {
16182            HashSet<ComponentName> singleUserReceivers = null;
16183            boolean scannedFirstReceivers = false;
16184            for (int user : users) {
16185                // Skip users that have Shell restrictions
16186                if (callingUid == Process.SHELL_UID
16187                        && getUserManagerLocked().hasUserRestriction(
16188                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16189                    continue;
16190                }
16191                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16192                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16193                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16194                    // If this is not the primary user, we need to check for
16195                    // any receivers that should be filtered out.
16196                    for (int i=0; i<newReceivers.size(); i++) {
16197                        ResolveInfo ri = newReceivers.get(i);
16198                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16199                            newReceivers.remove(i);
16200                            i--;
16201                        }
16202                    }
16203                }
16204                if (newReceivers != null && newReceivers.size() == 0) {
16205                    newReceivers = null;
16206                }
16207                if (receivers == null) {
16208                    receivers = newReceivers;
16209                } else if (newReceivers != null) {
16210                    // We need to concatenate the additional receivers
16211                    // found with what we have do far.  This would be easy,
16212                    // but we also need to de-dup any receivers that are
16213                    // singleUser.
16214                    if (!scannedFirstReceivers) {
16215                        // Collect any single user receivers we had already retrieved.
16216                        scannedFirstReceivers = true;
16217                        for (int i=0; i<receivers.size(); i++) {
16218                            ResolveInfo ri = receivers.get(i);
16219                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16220                                ComponentName cn = new ComponentName(
16221                                        ri.activityInfo.packageName, ri.activityInfo.name);
16222                                if (singleUserReceivers == null) {
16223                                    singleUserReceivers = new HashSet<ComponentName>();
16224                                }
16225                                singleUserReceivers.add(cn);
16226                            }
16227                        }
16228                    }
16229                    // Add the new results to the existing results, tracking
16230                    // and de-dupping single user receivers.
16231                    for (int i=0; i<newReceivers.size(); i++) {
16232                        ResolveInfo ri = newReceivers.get(i);
16233                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16234                            ComponentName cn = new ComponentName(
16235                                    ri.activityInfo.packageName, ri.activityInfo.name);
16236                            if (singleUserReceivers == null) {
16237                                singleUserReceivers = new HashSet<ComponentName>();
16238                            }
16239                            if (!singleUserReceivers.contains(cn)) {
16240                                singleUserReceivers.add(cn);
16241                                receivers.add(ri);
16242                            }
16243                        } else {
16244                            receivers.add(ri);
16245                        }
16246                    }
16247                }
16248            }
16249        } catch (RemoteException ex) {
16250            // pm is in same process, this will never happen.
16251        }
16252        return receivers;
16253    }
16254
16255    private final int broadcastIntentLocked(ProcessRecord callerApp,
16256            String callerPackage, Intent intent, String resolvedType,
16257            IIntentReceiver resultTo, int resultCode, String resultData,
16258            Bundle map, String requiredPermission, int appOp,
16259            boolean ordered, boolean sticky, int callingPid, int callingUid,
16260            int userId) {
16261        intent = new Intent(intent);
16262
16263        // By default broadcasts do not go to stopped apps.
16264        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16265
16266        // If we have not finished booting, don't allow this to launch new processes.
16267        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16268            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16269        }
16270
16271        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16272                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16273                + " ordered=" + ordered + " userid=" + userId);
16274        if ((resultTo != null) && !ordered) {
16275            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16276        }
16277
16278        userId = handleIncomingUser(callingPid, callingUid, userId,
16279                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16280
16281        // Make sure that the user who is receiving this broadcast is running.
16282        // If not, we will just skip it. Make an exception for shutdown broadcasts
16283        // and upgrade steps.
16284
16285        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16286            if ((callingUid != Process.SYSTEM_UID
16287                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16288                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16289                Slog.w(TAG, "Skipping broadcast of " + intent
16290                        + ": user " + userId + " is stopped");
16291                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16292            }
16293        }
16294
16295        /*
16296         * Prevent non-system code (defined here to be non-persistent
16297         * processes) from sending protected broadcasts.
16298         */
16299        int callingAppId = UserHandle.getAppId(callingUid);
16300        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16301            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16302            || callingAppId == Process.NFC_UID || callingUid == 0) {
16303            // Always okay.
16304        } else if (callerApp == null || !callerApp.persistent) {
16305            try {
16306                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16307                        intent.getAction())) {
16308                    String msg = "Permission Denial: not allowed to send broadcast "
16309                            + intent.getAction() + " from pid="
16310                            + callingPid + ", uid=" + callingUid;
16311                    Slog.w(TAG, msg);
16312                    throw new SecurityException(msg);
16313                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16314                    // Special case for compatibility: we don't want apps to send this,
16315                    // but historically it has not been protected and apps may be using it
16316                    // to poke their own app widget.  So, instead of making it protected,
16317                    // just limit it to the caller.
16318                    if (callerApp == null) {
16319                        String msg = "Permission Denial: not allowed to send broadcast "
16320                                + intent.getAction() + " from unknown caller.";
16321                        Slog.w(TAG, msg);
16322                        throw new SecurityException(msg);
16323                    } else if (intent.getComponent() != null) {
16324                        // They are good enough to send to an explicit component...  verify
16325                        // it is being sent to the calling app.
16326                        if (!intent.getComponent().getPackageName().equals(
16327                                callerApp.info.packageName)) {
16328                            String msg = "Permission Denial: not allowed to send broadcast "
16329                                    + intent.getAction() + " to "
16330                                    + intent.getComponent().getPackageName() + " from "
16331                                    + callerApp.info.packageName;
16332                            Slog.w(TAG, msg);
16333                            throw new SecurityException(msg);
16334                        }
16335                    } else {
16336                        // Limit broadcast to their own package.
16337                        intent.setPackage(callerApp.info.packageName);
16338                    }
16339                }
16340            } catch (RemoteException e) {
16341                Slog.w(TAG, "Remote exception", e);
16342                return ActivityManager.BROADCAST_SUCCESS;
16343            }
16344        }
16345
16346        final String action = intent.getAction();
16347        if (action != null) {
16348            switch (action) {
16349                case Intent.ACTION_UID_REMOVED:
16350                case Intent.ACTION_PACKAGE_REMOVED:
16351                case Intent.ACTION_PACKAGE_CHANGED:
16352                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16353                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16354                    // Handle special intents: if this broadcast is from the package
16355                    // manager about a package being removed, we need to remove all of
16356                    // its activities from the history stack.
16357                    if (checkComponentPermission(
16358                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16359                            callingPid, callingUid, -1, true)
16360                            != PackageManager.PERMISSION_GRANTED) {
16361                        String msg = "Permission Denial: " + intent.getAction()
16362                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16363                                + ", uid=" + callingUid + ")"
16364                                + " requires "
16365                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16366                        Slog.w(TAG, msg);
16367                        throw new SecurityException(msg);
16368                    }
16369                    switch (action) {
16370                        case Intent.ACTION_UID_REMOVED:
16371                            final Bundle intentExtras = intent.getExtras();
16372                            final int uid = intentExtras != null
16373                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16374                            if (uid >= 0) {
16375                                mBatteryStatsService.removeUid(uid);
16376                                mAppOpsService.uidRemoved(uid);
16377                            }
16378                            break;
16379                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16380                            // If resources are unavailable just force stop all those packages
16381                            // and flush the attribute cache as well.
16382                            String list[] =
16383                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16384                            if (list != null && list.length > 0) {
16385                                for (int i = 0; i < list.length; i++) {
16386                                    forceStopPackageLocked(list[i], -1, false, true, true,
16387                                            false, false, userId, "storage unmount");
16388                                }
16389                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16390                                sendPackageBroadcastLocked(
16391                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16392                                        userId);
16393                            }
16394                            break;
16395                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16396                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16397                            break;
16398                        case Intent.ACTION_PACKAGE_REMOVED:
16399                        case Intent.ACTION_PACKAGE_CHANGED:
16400                            Uri data = intent.getData();
16401                            String ssp;
16402                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16403                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16404                                boolean fullUninstall = removed &&
16405                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16406                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16407                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16408                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16409                                            false, true, true, false, fullUninstall, userId,
16410                                            removed ? "pkg removed" : "pkg changed");
16411                                }
16412                                if (removed) {
16413                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16414                                            new String[] {ssp}, userId);
16415                                    if (fullUninstall) {
16416                                        mAppOpsService.packageRemoved(
16417                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16418
16419                                        // Remove all permissions granted from/to this package
16420                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16421
16422                                        removeTasksByPackageNameLocked(ssp, userId);
16423                                        mBatteryStatsService.notePackageUninstalled(ssp);
16424                                    }
16425                                } else {
16426                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16427                                            intent.getStringArrayExtra(
16428                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16429                                }
16430                            }
16431                            break;
16432                    }
16433                    break;
16434                case Intent.ACTION_PACKAGE_ADDED:
16435                    // Special case for adding a package: by default turn on compatibility mode.
16436                    Uri data = intent.getData();
16437                    String ssp;
16438                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16439                        final boolean replacing =
16440                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16441                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16442
16443                        try {
16444                            ApplicationInfo ai = AppGlobals.getPackageManager().
16445                                    getApplicationInfo(ssp, 0, 0);
16446                            mBatteryStatsService.notePackageInstalled(ssp,
16447                                    ai != null ? ai.versionCode : 0);
16448                        } catch (RemoteException e) {
16449                        }
16450                    }
16451                    break;
16452                case Intent.ACTION_TIMEZONE_CHANGED:
16453                    // If this is the time zone changed action, queue up a message that will reset
16454                    // the timezone of all currently running processes. This message will get
16455                    // queued up before the broadcast happens.
16456                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16457                    break;
16458                case Intent.ACTION_TIME_CHANGED:
16459                    // If the user set the time, let all running processes know.
16460                    final int is24Hour =
16461                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16462                                    : 0;
16463                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16464                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16465                    synchronized (stats) {
16466                        stats.noteCurrentTimeChangedLocked();
16467                    }
16468                    break;
16469                case Intent.ACTION_CLEAR_DNS_CACHE:
16470                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16471                    break;
16472                case Proxy.PROXY_CHANGE_ACTION:
16473                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16474                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16475                    break;
16476            }
16477        }
16478
16479        // Add to the sticky list if requested.
16480        if (sticky) {
16481            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16482                    callingPid, callingUid)
16483                    != PackageManager.PERMISSION_GRANTED) {
16484                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16485                        + callingPid + ", uid=" + callingUid
16486                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16487                Slog.w(TAG, msg);
16488                throw new SecurityException(msg);
16489            }
16490            if (requiredPermission != null) {
16491                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16492                        + " and enforce permission " + requiredPermission);
16493                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16494            }
16495            if (intent.getComponent() != null) {
16496                throw new SecurityException(
16497                        "Sticky broadcasts can't target a specific component");
16498            }
16499            // We use userId directly here, since the "all" target is maintained
16500            // as a separate set of sticky broadcasts.
16501            if (userId != UserHandle.USER_ALL) {
16502                // But first, if this is not a broadcast to all users, then
16503                // make sure it doesn't conflict with an existing broadcast to
16504                // all users.
16505                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16506                        UserHandle.USER_ALL);
16507                if (stickies != null) {
16508                    ArrayList<Intent> list = stickies.get(intent.getAction());
16509                    if (list != null) {
16510                        int N = list.size();
16511                        int i;
16512                        for (i=0; i<N; i++) {
16513                            if (intent.filterEquals(list.get(i))) {
16514                                throw new IllegalArgumentException(
16515                                        "Sticky broadcast " + intent + " for user "
16516                                        + userId + " conflicts with existing global broadcast");
16517                            }
16518                        }
16519                    }
16520                }
16521            }
16522            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16523            if (stickies == null) {
16524                stickies = new ArrayMap<>();
16525                mStickyBroadcasts.put(userId, stickies);
16526            }
16527            ArrayList<Intent> list = stickies.get(intent.getAction());
16528            if (list == null) {
16529                list = new ArrayList<>();
16530                stickies.put(intent.getAction(), list);
16531            }
16532            final int stickiesCount = list.size();
16533            int i;
16534            for (i = 0; i < stickiesCount; i++) {
16535                if (intent.filterEquals(list.get(i))) {
16536                    // This sticky already exists, replace it.
16537                    list.set(i, new Intent(intent));
16538                    break;
16539                }
16540            }
16541            if (i >= stickiesCount) {
16542                list.add(new Intent(intent));
16543            }
16544        }
16545
16546        int[] users;
16547        if (userId == UserHandle.USER_ALL) {
16548            // Caller wants broadcast to go to all started users.
16549            users = mStartedUserArray;
16550        } else {
16551            // Caller wants broadcast to go to one specific user.
16552            users = new int[] {userId};
16553        }
16554
16555        // Figure out who all will receive this broadcast.
16556        List receivers = null;
16557        List<BroadcastFilter> registeredReceivers = null;
16558        // Need to resolve the intent to interested receivers...
16559        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16560                 == 0) {
16561            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16562        }
16563        if (intent.getComponent() == null) {
16564            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16565                // Query one target user at a time, excluding shell-restricted users
16566                UserManagerService ums = getUserManagerLocked();
16567                for (int i = 0; i < users.length; i++) {
16568                    if (ums.hasUserRestriction(
16569                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16570                        continue;
16571                    }
16572                    List<BroadcastFilter> registeredReceiversForUser =
16573                            mReceiverResolver.queryIntent(intent,
16574                                    resolvedType, false, users[i]);
16575                    if (registeredReceivers == null) {
16576                        registeredReceivers = registeredReceiversForUser;
16577                    } else if (registeredReceiversForUser != null) {
16578                        registeredReceivers.addAll(registeredReceiversForUser);
16579                    }
16580                }
16581            } else {
16582                registeredReceivers = mReceiverResolver.queryIntent(intent,
16583                        resolvedType, false, userId);
16584            }
16585        }
16586
16587        final boolean replacePending =
16588                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16589
16590        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16591                + " replacePending=" + replacePending);
16592
16593        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16594        if (!ordered && NR > 0) {
16595            // If we are not serializing this broadcast, then send the
16596            // registered receivers separately so they don't wait for the
16597            // components to be launched.
16598            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16599            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16600                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16601                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16602                    ordered, sticky, false, userId);
16603            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16604            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16605            if (!replaced) {
16606                queue.enqueueParallelBroadcastLocked(r);
16607                queue.scheduleBroadcastsLocked();
16608            }
16609            registeredReceivers = null;
16610            NR = 0;
16611        }
16612
16613        // Merge into one list.
16614        int ir = 0;
16615        if (receivers != null) {
16616            // A special case for PACKAGE_ADDED: do not allow the package
16617            // being added to see this broadcast.  This prevents them from
16618            // using this as a back door to get run as soon as they are
16619            // installed.  Maybe in the future we want to have a special install
16620            // broadcast or such for apps, but we'd like to deliberately make
16621            // this decision.
16622            String skipPackages[] = null;
16623            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16624                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16625                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16626                Uri data = intent.getData();
16627                if (data != null) {
16628                    String pkgName = data.getSchemeSpecificPart();
16629                    if (pkgName != null) {
16630                        skipPackages = new String[] { pkgName };
16631                    }
16632                }
16633            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16634                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16635            }
16636            if (skipPackages != null && (skipPackages.length > 0)) {
16637                for (String skipPackage : skipPackages) {
16638                    if (skipPackage != null) {
16639                        int NT = receivers.size();
16640                        for (int it=0; it<NT; it++) {
16641                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16642                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16643                                receivers.remove(it);
16644                                it--;
16645                                NT--;
16646                            }
16647                        }
16648                    }
16649                }
16650            }
16651
16652            int NT = receivers != null ? receivers.size() : 0;
16653            int it = 0;
16654            ResolveInfo curt = null;
16655            BroadcastFilter curr = null;
16656            while (it < NT && ir < NR) {
16657                if (curt == null) {
16658                    curt = (ResolveInfo)receivers.get(it);
16659                }
16660                if (curr == null) {
16661                    curr = registeredReceivers.get(ir);
16662                }
16663                if (curr.getPriority() >= curt.priority) {
16664                    // Insert this broadcast record into the final list.
16665                    receivers.add(it, curr);
16666                    ir++;
16667                    curr = null;
16668                    it++;
16669                    NT++;
16670                } else {
16671                    // Skip to the next ResolveInfo in the final list.
16672                    it++;
16673                    curt = null;
16674                }
16675            }
16676        }
16677        while (ir < NR) {
16678            if (receivers == null) {
16679                receivers = new ArrayList();
16680            }
16681            receivers.add(registeredReceivers.get(ir));
16682            ir++;
16683        }
16684
16685        if ((receivers != null && receivers.size() > 0)
16686                || resultTo != null) {
16687            BroadcastQueue queue = broadcastQueueForIntent(intent);
16688            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16689                    callerPackage, callingPid, callingUid, resolvedType,
16690                    requiredPermission, appOp, receivers, resultTo, resultCode,
16691                    resultData, map, ordered, sticky, false, userId);
16692
16693            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16694                    + ": prev had " + queue.mOrderedBroadcasts.size());
16695            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16696                    "Enqueueing broadcast " + r.intent.getAction());
16697
16698            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16699            if (!replaced) {
16700                queue.enqueueOrderedBroadcastLocked(r);
16701                queue.scheduleBroadcastsLocked();
16702            }
16703        }
16704
16705        return ActivityManager.BROADCAST_SUCCESS;
16706    }
16707
16708    final Intent verifyBroadcastLocked(Intent intent) {
16709        // Refuse possible leaked file descriptors
16710        if (intent != null && intent.hasFileDescriptors() == true) {
16711            throw new IllegalArgumentException("File descriptors passed in Intent");
16712        }
16713
16714        int flags = intent.getFlags();
16715
16716        if (!mProcessesReady) {
16717            // if the caller really truly claims to know what they're doing, go
16718            // ahead and allow the broadcast without launching any receivers
16719            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16720                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16721            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16722                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16723                        + " before boot completion");
16724                throw new IllegalStateException("Cannot broadcast before boot completed");
16725            }
16726        }
16727
16728        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16729            throw new IllegalArgumentException(
16730                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16731        }
16732
16733        return intent;
16734    }
16735
16736    public final int broadcastIntent(IApplicationThread caller,
16737            Intent intent, String resolvedType, IIntentReceiver resultTo,
16738            int resultCode, String resultData, Bundle map,
16739            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16740        enforceNotIsolatedCaller("broadcastIntent");
16741        synchronized(this) {
16742            intent = verifyBroadcastLocked(intent);
16743
16744            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16745            final int callingPid = Binder.getCallingPid();
16746            final int callingUid = Binder.getCallingUid();
16747            final long origId = Binder.clearCallingIdentity();
16748            int res = broadcastIntentLocked(callerApp,
16749                    callerApp != null ? callerApp.info.packageName : null,
16750                    intent, resolvedType, resultTo,
16751                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16752                    callingPid, callingUid, userId);
16753            Binder.restoreCallingIdentity(origId);
16754            return res;
16755        }
16756    }
16757
16758    int broadcastIntentInPackage(String packageName, int uid,
16759            Intent intent, String resolvedType, IIntentReceiver resultTo,
16760            int resultCode, String resultData, Bundle map,
16761            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16762        synchronized(this) {
16763            intent = verifyBroadcastLocked(intent);
16764
16765            final long origId = Binder.clearCallingIdentity();
16766            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16767                    resultTo, resultCode, resultData, map, requiredPermission,
16768                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16769            Binder.restoreCallingIdentity(origId);
16770            return res;
16771        }
16772    }
16773
16774    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16775        // Refuse possible leaked file descriptors
16776        if (intent != null && intent.hasFileDescriptors() == true) {
16777            throw new IllegalArgumentException("File descriptors passed in Intent");
16778        }
16779
16780        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16781                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16782
16783        synchronized(this) {
16784            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16785                    != PackageManager.PERMISSION_GRANTED) {
16786                String msg = "Permission Denial: unbroadcastIntent() from pid="
16787                        + Binder.getCallingPid()
16788                        + ", uid=" + Binder.getCallingUid()
16789                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16790                Slog.w(TAG, msg);
16791                throw new SecurityException(msg);
16792            }
16793            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16794            if (stickies != null) {
16795                ArrayList<Intent> list = stickies.get(intent.getAction());
16796                if (list != null) {
16797                    int N = list.size();
16798                    int i;
16799                    for (i=0; i<N; i++) {
16800                        if (intent.filterEquals(list.get(i))) {
16801                            list.remove(i);
16802                            break;
16803                        }
16804                    }
16805                    if (list.size() <= 0) {
16806                        stickies.remove(intent.getAction());
16807                    }
16808                }
16809                if (stickies.size() <= 0) {
16810                    mStickyBroadcasts.remove(userId);
16811                }
16812            }
16813        }
16814    }
16815
16816    void backgroundServicesFinishedLocked(int userId) {
16817        for (BroadcastQueue queue : mBroadcastQueues) {
16818            queue.backgroundServicesFinishedLocked(userId);
16819        }
16820    }
16821
16822    public void finishReceiver(IBinder who, int resultCode, String resultData,
16823            Bundle resultExtras, boolean resultAbort, int flags) {
16824        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16825
16826        // Refuse possible leaked file descriptors
16827        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16828            throw new IllegalArgumentException("File descriptors passed in Bundle");
16829        }
16830
16831        final long origId = Binder.clearCallingIdentity();
16832        try {
16833            boolean doNext = false;
16834            BroadcastRecord r;
16835
16836            synchronized(this) {
16837                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16838                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16839                r = queue.getMatchingOrderedReceiver(who);
16840                if (r != null) {
16841                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16842                        resultData, resultExtras, resultAbort, true);
16843                }
16844            }
16845
16846            if (doNext) {
16847                r.queue.processNextBroadcast(false);
16848            }
16849            trimApplications();
16850        } finally {
16851            Binder.restoreCallingIdentity(origId);
16852        }
16853    }
16854
16855    // =========================================================
16856    // INSTRUMENTATION
16857    // =========================================================
16858
16859    public boolean startInstrumentation(ComponentName className,
16860            String profileFile, int flags, Bundle arguments,
16861            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16862            int userId, String abiOverride) {
16863        enforceNotIsolatedCaller("startInstrumentation");
16864        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16865                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16866        // Refuse possible leaked file descriptors
16867        if (arguments != null && arguments.hasFileDescriptors()) {
16868            throw new IllegalArgumentException("File descriptors passed in Bundle");
16869        }
16870
16871        synchronized(this) {
16872            InstrumentationInfo ii = null;
16873            ApplicationInfo ai = null;
16874            try {
16875                ii = mContext.getPackageManager().getInstrumentationInfo(
16876                    className, STOCK_PM_FLAGS);
16877                ai = AppGlobals.getPackageManager().getApplicationInfo(
16878                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16879            } catch (PackageManager.NameNotFoundException e) {
16880            } catch (RemoteException e) {
16881            }
16882            if (ii == null) {
16883                reportStartInstrumentationFailure(watcher, className,
16884                        "Unable to find instrumentation info for: " + className);
16885                return false;
16886            }
16887            if (ai == null) {
16888                reportStartInstrumentationFailure(watcher, className,
16889                        "Unable to find instrumentation target package: " + ii.targetPackage);
16890                return false;
16891            }
16892
16893            int match = mContext.getPackageManager().checkSignatures(
16894                    ii.targetPackage, ii.packageName);
16895            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16896                String msg = "Permission Denial: starting instrumentation "
16897                        + className + " from pid="
16898                        + Binder.getCallingPid()
16899                        + ", uid=" + Binder.getCallingPid()
16900                        + " not allowed because package " + ii.packageName
16901                        + " does not have a signature matching the target "
16902                        + ii.targetPackage;
16903                reportStartInstrumentationFailure(watcher, className, msg);
16904                throw new SecurityException(msg);
16905            }
16906
16907            final long origId = Binder.clearCallingIdentity();
16908            // Instrumentation can kill and relaunch even persistent processes
16909            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16910                    "start instr");
16911            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16912            app.instrumentationClass = className;
16913            app.instrumentationInfo = ai;
16914            app.instrumentationProfileFile = profileFile;
16915            app.instrumentationArguments = arguments;
16916            app.instrumentationWatcher = watcher;
16917            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16918            app.instrumentationResultClass = className;
16919            Binder.restoreCallingIdentity(origId);
16920        }
16921
16922        return true;
16923    }
16924
16925    /**
16926     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16927     * error to the logs, but if somebody is watching, send the report there too.  This enables
16928     * the "am" command to report errors with more information.
16929     *
16930     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16931     * @param cn The component name of the instrumentation.
16932     * @param report The error report.
16933     */
16934    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16935            ComponentName cn, String report) {
16936        Slog.w(TAG, report);
16937        try {
16938            if (watcher != null) {
16939                Bundle results = new Bundle();
16940                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16941                results.putString("Error", report);
16942                watcher.instrumentationStatus(cn, -1, results);
16943            }
16944        } catch (RemoteException e) {
16945            Slog.w(TAG, e);
16946        }
16947    }
16948
16949    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16950        if (app.instrumentationWatcher != null) {
16951            try {
16952                // NOTE:  IInstrumentationWatcher *must* be oneway here
16953                app.instrumentationWatcher.instrumentationFinished(
16954                    app.instrumentationClass,
16955                    resultCode,
16956                    results);
16957            } catch (RemoteException e) {
16958            }
16959        }
16960        if (app.instrumentationUiAutomationConnection != null) {
16961            try {
16962                app.instrumentationUiAutomationConnection.shutdown();
16963            } catch (RemoteException re) {
16964                /* ignore */
16965            }
16966            // Only a UiAutomation can set this flag and now that
16967            // it is finished we make sure it is reset to its default.
16968            mUserIsMonkey = false;
16969        }
16970        app.instrumentationWatcher = null;
16971        app.instrumentationUiAutomationConnection = null;
16972        app.instrumentationClass = null;
16973        app.instrumentationInfo = null;
16974        app.instrumentationProfileFile = null;
16975        app.instrumentationArguments = null;
16976
16977        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16978                "finished inst");
16979    }
16980
16981    public void finishInstrumentation(IApplicationThread target,
16982            int resultCode, Bundle results) {
16983        int userId = UserHandle.getCallingUserId();
16984        // Refuse possible leaked file descriptors
16985        if (results != null && results.hasFileDescriptors()) {
16986            throw new IllegalArgumentException("File descriptors passed in Intent");
16987        }
16988
16989        synchronized(this) {
16990            ProcessRecord app = getRecordForAppLocked(target);
16991            if (app == null) {
16992                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16993                return;
16994            }
16995            final long origId = Binder.clearCallingIdentity();
16996            finishInstrumentationLocked(app, resultCode, results);
16997            Binder.restoreCallingIdentity(origId);
16998        }
16999    }
17000
17001    // =========================================================
17002    // CONFIGURATION
17003    // =========================================================
17004
17005    public ConfigurationInfo getDeviceConfigurationInfo() {
17006        ConfigurationInfo config = new ConfigurationInfo();
17007        synchronized (this) {
17008            config.reqTouchScreen = mConfiguration.touchscreen;
17009            config.reqKeyboardType = mConfiguration.keyboard;
17010            config.reqNavigation = mConfiguration.navigation;
17011            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17012                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17013                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17014            }
17015            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17016                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17017                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17018            }
17019            config.reqGlEsVersion = GL_ES_VERSION;
17020        }
17021        return config;
17022    }
17023
17024    ActivityStack getFocusedStack() {
17025        return mStackSupervisor.getFocusedStack();
17026    }
17027
17028    @Override
17029    public int getFocusedStackId() throws RemoteException {
17030        ActivityStack focusedStack = getFocusedStack();
17031        if (focusedStack != null) {
17032            return focusedStack.getStackId();
17033        }
17034        return -1;
17035    }
17036
17037    public Configuration getConfiguration() {
17038        Configuration ci;
17039        synchronized(this) {
17040            ci = new Configuration(mConfiguration);
17041            ci.userSetLocale = false;
17042        }
17043        return ci;
17044    }
17045
17046    public void updatePersistentConfiguration(Configuration values) {
17047        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17048                "updateConfiguration()");
17049        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17050                "updateConfiguration()");
17051        if (values == null) {
17052            throw new NullPointerException("Configuration must not be null");
17053        }
17054
17055        synchronized(this) {
17056            final long origId = Binder.clearCallingIdentity();
17057            updateConfigurationLocked(values, null, true, false);
17058            Binder.restoreCallingIdentity(origId);
17059        }
17060    }
17061
17062    public void updateConfiguration(Configuration values) {
17063        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17064                "updateConfiguration()");
17065
17066        synchronized(this) {
17067            if (values == null && mWindowManager != null) {
17068                // sentinel: fetch the current configuration from the window manager
17069                values = mWindowManager.computeNewConfiguration();
17070            }
17071
17072            if (mWindowManager != null) {
17073                mProcessList.applyDisplaySize(mWindowManager);
17074            }
17075
17076            final long origId = Binder.clearCallingIdentity();
17077            if (values != null) {
17078                Settings.System.clearConfiguration(values);
17079            }
17080            updateConfigurationLocked(values, null, false, false);
17081            Binder.restoreCallingIdentity(origId);
17082        }
17083    }
17084
17085    /**
17086     * Do either or both things: (1) change the current configuration, and (2)
17087     * make sure the given activity is running with the (now) current
17088     * configuration.  Returns true if the activity has been left running, or
17089     * false if <var>starting</var> is being destroyed to match the new
17090     * configuration.
17091     * @param persistent TODO
17092     */
17093    boolean updateConfigurationLocked(Configuration values,
17094            ActivityRecord starting, boolean persistent, boolean initLocale) {
17095        int changes = 0;
17096
17097        if (values != null) {
17098            Configuration newConfig = new Configuration(mConfiguration);
17099            changes = newConfig.updateFrom(values);
17100            if (changes != 0) {
17101                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17102                        "Updating configuration to: " + values);
17103
17104                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17105
17106                if (!initLocale && values.locale != null && values.userSetLocale) {
17107                    final String languageTag = values.locale.toLanguageTag();
17108                    SystemProperties.set("persist.sys.locale", languageTag);
17109                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17110                            values.locale));
17111                }
17112
17113                mConfigurationSeq++;
17114                if (mConfigurationSeq <= 0) {
17115                    mConfigurationSeq = 1;
17116                }
17117                newConfig.seq = mConfigurationSeq;
17118                mConfiguration = newConfig;
17119                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17120                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17121                //mUsageStatsService.noteStartConfig(newConfig);
17122
17123                final Configuration configCopy = new Configuration(mConfiguration);
17124
17125                // TODO: If our config changes, should we auto dismiss any currently
17126                // showing dialogs?
17127                mShowDialogs = shouldShowDialogs(newConfig);
17128
17129                AttributeCache ac = AttributeCache.instance();
17130                if (ac != null) {
17131                    ac.updateConfiguration(configCopy);
17132                }
17133
17134                // Make sure all resources in our process are updated
17135                // right now, so that anyone who is going to retrieve
17136                // resource values after we return will be sure to get
17137                // the new ones.  This is especially important during
17138                // boot, where the first config change needs to guarantee
17139                // all resources have that config before following boot
17140                // code is executed.
17141                mSystemThread.applyConfigurationToResources(configCopy);
17142
17143                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17144                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17145                    msg.obj = new Configuration(configCopy);
17146                    mHandler.sendMessage(msg);
17147                }
17148
17149                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17150                    ProcessRecord app = mLruProcesses.get(i);
17151                    try {
17152                        if (app.thread != null) {
17153                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17154                                    + app.processName + " new config " + mConfiguration);
17155                            app.thread.scheduleConfigurationChanged(configCopy);
17156                        }
17157                    } catch (Exception e) {
17158                    }
17159                }
17160                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17161                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17162                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17163                        | Intent.FLAG_RECEIVER_FOREGROUND);
17164                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17165                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
17166                        Process.SYSTEM_UID, UserHandle.USER_ALL);
17167                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17168                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17169                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17170                    if (!mProcessesReady) {
17171                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17172                    }
17173                    broadcastIntentLocked(null, null, intent,
17174                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17175                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17176                }
17177            }
17178        }
17179
17180        boolean kept = true;
17181        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17182        // mainStack is null during startup.
17183        if (mainStack != null) {
17184            if (changes != 0 && starting == null) {
17185                // If the configuration changed, and the caller is not already
17186                // in the process of starting an activity, then find the top
17187                // activity to check if its configuration needs to change.
17188                starting = mainStack.topRunningActivityLocked(null);
17189            }
17190
17191            if (starting != null) {
17192                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17193                // And we need to make sure at this point that all other activities
17194                // are made visible with the correct configuration.
17195                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17196            }
17197        }
17198
17199        if (values != null && mWindowManager != null) {
17200            mWindowManager.setNewConfiguration(mConfiguration);
17201        }
17202
17203        return kept;
17204    }
17205
17206    /**
17207     * Decide based on the configuration whether we should shouw the ANR,
17208     * crash, etc dialogs.  The idea is that if there is no affordnace to
17209     * press the on-screen buttons, we shouldn't show the dialog.
17210     *
17211     * A thought: SystemUI might also want to get told about this, the Power
17212     * dialog / global actions also might want different behaviors.
17213     */
17214    private static final boolean shouldShowDialogs(Configuration config) {
17215        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17216                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17217                && config.navigation == Configuration.NAVIGATION_NONAV);
17218    }
17219
17220    @Override
17221    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17222        synchronized (this) {
17223            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17224            if (srec != null) {
17225                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17226            }
17227        }
17228        return false;
17229    }
17230
17231    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17232            Intent resultData) {
17233
17234        synchronized (this) {
17235            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17236            if (r != null) {
17237                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17238            }
17239            return false;
17240        }
17241    }
17242
17243    public int getLaunchedFromUid(IBinder activityToken) {
17244        ActivityRecord srec;
17245        synchronized (this) {
17246            srec = ActivityRecord.forTokenLocked(activityToken);
17247        }
17248        if (srec == null) {
17249            return -1;
17250        }
17251        return srec.launchedFromUid;
17252    }
17253
17254    public String getLaunchedFromPackage(IBinder activityToken) {
17255        ActivityRecord srec;
17256        synchronized (this) {
17257            srec = ActivityRecord.forTokenLocked(activityToken);
17258        }
17259        if (srec == null) {
17260            return null;
17261        }
17262        return srec.launchedFromPackage;
17263    }
17264
17265    // =========================================================
17266    // LIFETIME MANAGEMENT
17267    // =========================================================
17268
17269    // Returns which broadcast queue the app is the current [or imminent] receiver
17270    // on, or 'null' if the app is not an active broadcast recipient.
17271    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17272        BroadcastRecord r = app.curReceiver;
17273        if (r != null) {
17274            return r.queue;
17275        }
17276
17277        // It's not the current receiver, but it might be starting up to become one
17278        synchronized (this) {
17279            for (BroadcastQueue queue : mBroadcastQueues) {
17280                r = queue.mPendingBroadcast;
17281                if (r != null && r.curApp == app) {
17282                    // found it; report which queue it's in
17283                    return queue;
17284                }
17285            }
17286        }
17287
17288        return null;
17289    }
17290
17291    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17292            ComponentName targetComponent, String targetProcess) {
17293        if (!mTrackingAssociations) {
17294            return null;
17295        }
17296        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17297                = mAssociations.get(targetUid);
17298        if (components == null) {
17299            components = new ArrayMap<>();
17300            mAssociations.put(targetUid, components);
17301        }
17302        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17303        if (sourceUids == null) {
17304            sourceUids = new SparseArray<>();
17305            components.put(targetComponent, sourceUids);
17306        }
17307        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17308        if (sourceProcesses == null) {
17309            sourceProcesses = new ArrayMap<>();
17310            sourceUids.put(sourceUid, sourceProcesses);
17311        }
17312        Association ass = sourceProcesses.get(sourceProcess);
17313        if (ass == null) {
17314            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17315                    targetProcess);
17316            sourceProcesses.put(sourceProcess, ass);
17317        }
17318        ass.mCount++;
17319        ass.mNesting++;
17320        if (ass.mNesting == 1) {
17321            ass.mStartTime = SystemClock.uptimeMillis();
17322        }
17323        return ass;
17324    }
17325
17326    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17327            ComponentName targetComponent) {
17328        if (!mTrackingAssociations) {
17329            return;
17330        }
17331        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17332                = mAssociations.get(targetUid);
17333        if (components == null) {
17334            return;
17335        }
17336        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17337        if (sourceUids == null) {
17338            return;
17339        }
17340        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17341        if (sourceProcesses == null) {
17342            return;
17343        }
17344        Association ass = sourceProcesses.get(sourceProcess);
17345        if (ass == null || ass.mNesting <= 0) {
17346            return;
17347        }
17348        ass.mNesting--;
17349        if (ass.mNesting == 0) {
17350            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17351        }
17352    }
17353
17354    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17355            boolean doingAll, long now) {
17356        if (mAdjSeq == app.adjSeq) {
17357            // This adjustment has already been computed.
17358            return app.curRawAdj;
17359        }
17360
17361        if (app.thread == null) {
17362            app.adjSeq = mAdjSeq;
17363            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17364            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17365            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17366        }
17367
17368        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17369        app.adjSource = null;
17370        app.adjTarget = null;
17371        app.empty = false;
17372        app.cached = false;
17373
17374        final int activitiesSize = app.activities.size();
17375
17376        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17377            // The max adjustment doesn't allow this app to be anything
17378            // below foreground, so it is not worth doing work for it.
17379            app.adjType = "fixed";
17380            app.adjSeq = mAdjSeq;
17381            app.curRawAdj = app.maxAdj;
17382            app.foregroundActivities = false;
17383            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17384            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17385            // System processes can do UI, and when they do we want to have
17386            // them trim their memory after the user leaves the UI.  To
17387            // facilitate this, here we need to determine whether or not it
17388            // is currently showing UI.
17389            app.systemNoUi = true;
17390            if (app == TOP_APP) {
17391                app.systemNoUi = false;
17392            } else if (activitiesSize > 0) {
17393                for (int j = 0; j < activitiesSize; j++) {
17394                    final ActivityRecord r = app.activities.get(j);
17395                    if (r.visible) {
17396                        app.systemNoUi = false;
17397                    }
17398                }
17399            }
17400            if (!app.systemNoUi) {
17401                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17402            }
17403            return (app.curAdj=app.maxAdj);
17404        }
17405
17406        app.systemNoUi = false;
17407
17408        final int PROCESS_STATE_TOP = mTopProcessState;
17409
17410        // Determine the importance of the process, starting with most
17411        // important to least, and assign an appropriate OOM adjustment.
17412        int adj;
17413        int schedGroup;
17414        int procState;
17415        boolean foregroundActivities = false;
17416        BroadcastQueue queue;
17417        if (app == TOP_APP) {
17418            // The last app on the list is the foreground app.
17419            adj = ProcessList.FOREGROUND_APP_ADJ;
17420            schedGroup = Process.THREAD_GROUP_DEFAULT;
17421            app.adjType = "top-activity";
17422            foregroundActivities = true;
17423            procState = PROCESS_STATE_TOP;
17424        } else if (app.instrumentationClass != null) {
17425            // Don't want to kill running instrumentation.
17426            adj = ProcessList.FOREGROUND_APP_ADJ;
17427            schedGroup = Process.THREAD_GROUP_DEFAULT;
17428            app.adjType = "instrumentation";
17429            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17430        } else if ((queue = isReceivingBroadcast(app)) != null) {
17431            // An app that is currently receiving a broadcast also
17432            // counts as being in the foreground for OOM killer purposes.
17433            // It's placed in a sched group based on the nature of the
17434            // broadcast as reflected by which queue it's active in.
17435            adj = ProcessList.FOREGROUND_APP_ADJ;
17436            schedGroup = (queue == mFgBroadcastQueue)
17437                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17438            app.adjType = "broadcast";
17439            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17440        } else if (app.executingServices.size() > 0) {
17441            // An app that is currently executing a service callback also
17442            // counts as being in the foreground.
17443            adj = ProcessList.FOREGROUND_APP_ADJ;
17444            schedGroup = app.execServicesFg ?
17445                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17446            app.adjType = "exec-service";
17447            procState = ActivityManager.PROCESS_STATE_SERVICE;
17448            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17449        } else {
17450            // As far as we know the process is empty.  We may change our mind later.
17451            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17452            // At this point we don't actually know the adjustment.  Use the cached adj
17453            // value that the caller wants us to.
17454            adj = cachedAdj;
17455            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17456            app.cached = true;
17457            app.empty = true;
17458            app.adjType = "cch-empty";
17459        }
17460
17461        // Examine all activities if not already foreground.
17462        if (!foregroundActivities && activitiesSize > 0) {
17463            for (int j = 0; j < activitiesSize; j++) {
17464                final ActivityRecord r = app.activities.get(j);
17465                if (r.app != app) {
17466                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17467                            + app + "?!? Using " + r.app + " instead.");
17468                    continue;
17469                }
17470                if (r.visible) {
17471                    // App has a visible activity; only upgrade adjustment.
17472                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17473                        adj = ProcessList.VISIBLE_APP_ADJ;
17474                        app.adjType = "visible";
17475                    }
17476                    if (procState > PROCESS_STATE_TOP) {
17477                        procState = PROCESS_STATE_TOP;
17478                    }
17479                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17480                    app.cached = false;
17481                    app.empty = false;
17482                    foregroundActivities = true;
17483                    break;
17484                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17485                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17486                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17487                        app.adjType = "pausing";
17488                    }
17489                    if (procState > PROCESS_STATE_TOP) {
17490                        procState = PROCESS_STATE_TOP;
17491                    }
17492                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17493                    app.cached = false;
17494                    app.empty = false;
17495                    foregroundActivities = true;
17496                } else if (r.state == ActivityState.STOPPING) {
17497                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17498                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17499                        app.adjType = "stopping";
17500                    }
17501                    // For the process state, we will at this point consider the
17502                    // process to be cached.  It will be cached either as an activity
17503                    // or empty depending on whether the activity is finishing.  We do
17504                    // this so that we can treat the process as cached for purposes of
17505                    // memory trimming (determing current memory level, trim command to
17506                    // send to process) since there can be an arbitrary number of stopping
17507                    // processes and they should soon all go into the cached state.
17508                    if (!r.finishing) {
17509                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17510                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17511                        }
17512                    }
17513                    app.cached = false;
17514                    app.empty = false;
17515                    foregroundActivities = true;
17516                } else {
17517                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17518                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17519                        app.adjType = "cch-act";
17520                    }
17521                }
17522            }
17523        }
17524
17525        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17526            if (app.foregroundServices) {
17527                // The user is aware of this app, so make it visible.
17528                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17529                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17530                app.cached = false;
17531                app.adjType = "fg-service";
17532                schedGroup = Process.THREAD_GROUP_DEFAULT;
17533            } else if (app.forcingToForeground != null) {
17534                // The user is aware of this app, so make it visible.
17535                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17536                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17537                app.cached = false;
17538                app.adjType = "force-fg";
17539                app.adjSource = app.forcingToForeground;
17540                schedGroup = Process.THREAD_GROUP_DEFAULT;
17541            }
17542        }
17543
17544        if (app == mHeavyWeightProcess) {
17545            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17546                // We don't want to kill the current heavy-weight process.
17547                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17548                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17549                app.cached = false;
17550                app.adjType = "heavy";
17551            }
17552            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17553                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17554            }
17555        }
17556
17557        if (app == mHomeProcess) {
17558            if (adj > ProcessList.HOME_APP_ADJ) {
17559                // This process is hosting what we currently consider to be the
17560                // home app, so we don't want to let it go into the background.
17561                adj = ProcessList.HOME_APP_ADJ;
17562                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17563                app.cached = false;
17564                app.adjType = "home";
17565            }
17566            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17567                procState = ActivityManager.PROCESS_STATE_HOME;
17568            }
17569        }
17570
17571        if (app == mPreviousProcess && app.activities.size() > 0) {
17572            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17573                // This was the previous process that showed UI to the user.
17574                // We want to try to keep it around more aggressively, to give
17575                // a good experience around switching between two apps.
17576                adj = ProcessList.PREVIOUS_APP_ADJ;
17577                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17578                app.cached = false;
17579                app.adjType = "previous";
17580            }
17581            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17582                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17583            }
17584        }
17585
17586        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17587                + " reason=" + app.adjType);
17588
17589        // By default, we use the computed adjustment.  It may be changed if
17590        // there are applications dependent on our services or providers, but
17591        // this gives us a baseline and makes sure we don't get into an
17592        // infinite recursion.
17593        app.adjSeq = mAdjSeq;
17594        app.curRawAdj = adj;
17595        app.hasStartedServices = false;
17596
17597        if (mBackupTarget != null && app == mBackupTarget.app) {
17598            // If possible we want to avoid killing apps while they're being backed up
17599            if (adj > ProcessList.BACKUP_APP_ADJ) {
17600                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17601                adj = ProcessList.BACKUP_APP_ADJ;
17602                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17603                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17604                }
17605                app.adjType = "backup";
17606                app.cached = false;
17607            }
17608            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17609                procState = ActivityManager.PROCESS_STATE_BACKUP;
17610            }
17611        }
17612
17613        boolean mayBeTop = false;
17614
17615        for (int is = app.services.size()-1;
17616                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17617                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17618                        || procState > ActivityManager.PROCESS_STATE_TOP);
17619                is--) {
17620            ServiceRecord s = app.services.valueAt(is);
17621            if (s.startRequested) {
17622                app.hasStartedServices = true;
17623                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17624                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17625                }
17626                if (app.hasShownUi && app != mHomeProcess) {
17627                    // If this process has shown some UI, let it immediately
17628                    // go to the LRU list because it may be pretty heavy with
17629                    // UI stuff.  We'll tag it with a label just to help
17630                    // debug and understand what is going on.
17631                    if (adj > ProcessList.SERVICE_ADJ) {
17632                        app.adjType = "cch-started-ui-services";
17633                    }
17634                } else {
17635                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17636                        // This service has seen some activity within
17637                        // recent memory, so we will keep its process ahead
17638                        // of the background processes.
17639                        if (adj > ProcessList.SERVICE_ADJ) {
17640                            adj = ProcessList.SERVICE_ADJ;
17641                            app.adjType = "started-services";
17642                            app.cached = false;
17643                        }
17644                    }
17645                    // If we have let the service slide into the background
17646                    // state, still have some text describing what it is doing
17647                    // even though the service no longer has an impact.
17648                    if (adj > ProcessList.SERVICE_ADJ) {
17649                        app.adjType = "cch-started-services";
17650                    }
17651                }
17652            }
17653            for (int conni = s.connections.size()-1;
17654                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17655                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17656                            || procState > ActivityManager.PROCESS_STATE_TOP);
17657                    conni--) {
17658                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17659                for (int i = 0;
17660                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17661                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17662                                || procState > ActivityManager.PROCESS_STATE_TOP);
17663                        i++) {
17664                    // XXX should compute this based on the max of
17665                    // all connected clients.
17666                    ConnectionRecord cr = clist.get(i);
17667                    if (cr.binding.client == app) {
17668                        // Binding to ourself is not interesting.
17669                        continue;
17670                    }
17671                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17672                        ProcessRecord client = cr.binding.client;
17673                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17674                                TOP_APP, doingAll, now);
17675                        int clientProcState = client.curProcState;
17676                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17677                            // If the other app is cached for any reason, for purposes here
17678                            // we are going to consider it empty.  The specific cached state
17679                            // doesn't propagate except under certain conditions.
17680                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17681                        }
17682                        String adjType = null;
17683                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17684                            // Not doing bind OOM management, so treat
17685                            // this guy more like a started service.
17686                            if (app.hasShownUi && app != mHomeProcess) {
17687                                // If this process has shown some UI, let it immediately
17688                                // go to the LRU list because it may be pretty heavy with
17689                                // UI stuff.  We'll tag it with a label just to help
17690                                // debug and understand what is going on.
17691                                if (adj > clientAdj) {
17692                                    adjType = "cch-bound-ui-services";
17693                                }
17694                                app.cached = false;
17695                                clientAdj = adj;
17696                                clientProcState = procState;
17697                            } else {
17698                                if (now >= (s.lastActivity
17699                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17700                                    // This service has not seen activity within
17701                                    // recent memory, so allow it to drop to the
17702                                    // LRU list if there is no other reason to keep
17703                                    // it around.  We'll also tag it with a label just
17704                                    // to help debug and undertand what is going on.
17705                                    if (adj > clientAdj) {
17706                                        adjType = "cch-bound-services";
17707                                    }
17708                                    clientAdj = adj;
17709                                }
17710                            }
17711                        }
17712                        if (adj > clientAdj) {
17713                            // If this process has recently shown UI, and
17714                            // the process that is binding to it is less
17715                            // important than being visible, then we don't
17716                            // care about the binding as much as we care
17717                            // about letting this process get into the LRU
17718                            // list to be killed and restarted if needed for
17719                            // memory.
17720                            if (app.hasShownUi && app != mHomeProcess
17721                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17722                                adjType = "cch-bound-ui-services";
17723                            } else {
17724                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17725                                        |Context.BIND_IMPORTANT)) != 0) {
17726                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17727                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17728                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17729                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17730                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17731                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17732                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17733                                    adj = clientAdj;
17734                                } else {
17735                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17736                                        adj = ProcessList.VISIBLE_APP_ADJ;
17737                                    }
17738                                }
17739                                if (!client.cached) {
17740                                    app.cached = false;
17741                                }
17742                                adjType = "service";
17743                            }
17744                        }
17745                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17746                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17747                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17748                            }
17749                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17750                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17751                                    // Special handling of clients who are in the top state.
17752                                    // We *may* want to consider this process to be in the
17753                                    // top state as well, but only if there is not another
17754                                    // reason for it to be running.  Being on the top is a
17755                                    // special state, meaning you are specifically running
17756                                    // for the current top app.  If the process is already
17757                                    // running in the background for some other reason, it
17758                                    // is more important to continue considering it to be
17759                                    // in the background state.
17760                                    mayBeTop = true;
17761                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17762                                } else {
17763                                    // Special handling for above-top states (persistent
17764                                    // processes).  These should not bring the current process
17765                                    // into the top state, since they are not on top.  Instead
17766                                    // give them the best state after that.
17767                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17768                                        clientProcState =
17769                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17770                                    } else if (mWakefulness
17771                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17772                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17773                                                    != 0) {
17774                                        clientProcState =
17775                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17776                                    } else {
17777                                        clientProcState =
17778                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17779                                    }
17780                                }
17781                            }
17782                        } else {
17783                            if (clientProcState <
17784                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17785                                clientProcState =
17786                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17787                            }
17788                        }
17789                        if (procState > clientProcState) {
17790                            procState = clientProcState;
17791                        }
17792                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17793                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17794                            app.pendingUiClean = true;
17795                        }
17796                        if (adjType != null) {
17797                            app.adjType = adjType;
17798                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17799                                    .REASON_SERVICE_IN_USE;
17800                            app.adjSource = cr.binding.client;
17801                            app.adjSourceProcState = clientProcState;
17802                            app.adjTarget = s.name;
17803                        }
17804                    }
17805                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17806                        app.treatLikeActivity = true;
17807                    }
17808                    final ActivityRecord a = cr.activity;
17809                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17810                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17811                                (a.visible || a.state == ActivityState.RESUMED
17812                                 || a.state == ActivityState.PAUSING)) {
17813                            adj = ProcessList.FOREGROUND_APP_ADJ;
17814                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17815                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17816                            }
17817                            app.cached = false;
17818                            app.adjType = "service";
17819                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17820                                    .REASON_SERVICE_IN_USE;
17821                            app.adjSource = a;
17822                            app.adjSourceProcState = procState;
17823                            app.adjTarget = s.name;
17824                        }
17825                    }
17826                }
17827            }
17828        }
17829
17830        for (int provi = app.pubProviders.size()-1;
17831                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17832                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17833                        || procState > ActivityManager.PROCESS_STATE_TOP);
17834                provi--) {
17835            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17836            for (int i = cpr.connections.size()-1;
17837                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17838                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17839                            || procState > ActivityManager.PROCESS_STATE_TOP);
17840                    i--) {
17841                ContentProviderConnection conn = cpr.connections.get(i);
17842                ProcessRecord client = conn.client;
17843                if (client == app) {
17844                    // Being our own client is not interesting.
17845                    continue;
17846                }
17847                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17848                int clientProcState = client.curProcState;
17849                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17850                    // If the other app is cached for any reason, for purposes here
17851                    // we are going to consider it empty.
17852                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17853                }
17854                if (adj > clientAdj) {
17855                    if (app.hasShownUi && app != mHomeProcess
17856                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17857                        app.adjType = "cch-ui-provider";
17858                    } else {
17859                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17860                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17861                        app.adjType = "provider";
17862                    }
17863                    app.cached &= client.cached;
17864                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17865                            .REASON_PROVIDER_IN_USE;
17866                    app.adjSource = client;
17867                    app.adjSourceProcState = clientProcState;
17868                    app.adjTarget = cpr.name;
17869                }
17870                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17871                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17872                        // Special handling of clients who are in the top state.
17873                        // We *may* want to consider this process to be in the
17874                        // top state as well, but only if there is not another
17875                        // reason for it to be running.  Being on the top is a
17876                        // special state, meaning you are specifically running
17877                        // for the current top app.  If the process is already
17878                        // running in the background for some other reason, it
17879                        // is more important to continue considering it to be
17880                        // in the background state.
17881                        mayBeTop = true;
17882                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17883                    } else {
17884                        // Special handling for above-top states (persistent
17885                        // processes).  These should not bring the current process
17886                        // into the top state, since they are not on top.  Instead
17887                        // give them the best state after that.
17888                        clientProcState =
17889                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17890                    }
17891                }
17892                if (procState > clientProcState) {
17893                    procState = clientProcState;
17894                }
17895                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17896                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17897                }
17898            }
17899            // If the provider has external (non-framework) process
17900            // dependencies, ensure that its adjustment is at least
17901            // FOREGROUND_APP_ADJ.
17902            if (cpr.hasExternalProcessHandles()) {
17903                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17904                    adj = ProcessList.FOREGROUND_APP_ADJ;
17905                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17906                    app.cached = false;
17907                    app.adjType = "provider";
17908                    app.adjTarget = cpr.name;
17909                }
17910                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17911                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17912                }
17913            }
17914        }
17915
17916        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17917            // A client of one of our services or providers is in the top state.  We
17918            // *may* want to be in the top state, but not if we are already running in
17919            // the background for some other reason.  For the decision here, we are going
17920            // to pick out a few specific states that we want to remain in when a client
17921            // is top (states that tend to be longer-term) and otherwise allow it to go
17922            // to the top state.
17923            switch (procState) {
17924                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17925                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17926                case ActivityManager.PROCESS_STATE_SERVICE:
17927                    // These all are longer-term states, so pull them up to the top
17928                    // of the background states, but not all the way to the top state.
17929                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17930                    break;
17931                default:
17932                    // Otherwise, top is a better choice, so take it.
17933                    procState = ActivityManager.PROCESS_STATE_TOP;
17934                    break;
17935            }
17936        }
17937
17938        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17939            if (app.hasClientActivities) {
17940                // This is a cached process, but with client activities.  Mark it so.
17941                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17942                app.adjType = "cch-client-act";
17943            } else if (app.treatLikeActivity) {
17944                // This is a cached process, but somebody wants us to treat it like it has
17945                // an activity, okay!
17946                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17947                app.adjType = "cch-as-act";
17948            }
17949        }
17950
17951        if (adj == ProcessList.SERVICE_ADJ) {
17952            if (doingAll) {
17953                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17954                mNewNumServiceProcs++;
17955                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17956                if (!app.serviceb) {
17957                    // This service isn't far enough down on the LRU list to
17958                    // normally be a B service, but if we are low on RAM and it
17959                    // is large we want to force it down since we would prefer to
17960                    // keep launcher over it.
17961                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17962                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17963                        app.serviceHighRam = true;
17964                        app.serviceb = true;
17965                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17966                    } else {
17967                        mNewNumAServiceProcs++;
17968                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17969                    }
17970                } else {
17971                    app.serviceHighRam = false;
17972                }
17973            }
17974            if (app.serviceb) {
17975                adj = ProcessList.SERVICE_B_ADJ;
17976            }
17977        }
17978
17979        app.curRawAdj = adj;
17980
17981        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17982        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17983        if (adj > app.maxAdj) {
17984            adj = app.maxAdj;
17985            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17986                schedGroup = Process.THREAD_GROUP_DEFAULT;
17987            }
17988        }
17989
17990        // Do final modification to adj.  Everything we do between here and applying
17991        // the final setAdj must be done in this function, because we will also use
17992        // it when computing the final cached adj later.  Note that we don't need to
17993        // worry about this for max adj above, since max adj will always be used to
17994        // keep it out of the cached vaues.
17995        app.curAdj = app.modifyRawOomAdj(adj);
17996        app.curSchedGroup = schedGroup;
17997        app.curProcState = procState;
17998        app.foregroundActivities = foregroundActivities;
17999
18000        return app.curRawAdj;
18001    }
18002
18003    /**
18004     * Record new PSS sample for a process.
18005     */
18006    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18007        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18008        proc.lastPssTime = now;
18009        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18010        if (DEBUG_PSS) Slog.d(TAG_PSS,
18011                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18012                + " state=" + ProcessList.makeProcStateString(procState));
18013        if (proc.initialIdlePss == 0) {
18014            proc.initialIdlePss = pss;
18015        }
18016        proc.lastPss = pss;
18017        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18018            proc.lastCachedPss = pss;
18019        }
18020
18021        final SparseArray<Pair<Long, String>> watchUids
18022                = mMemWatchProcesses.getMap().get(proc.processName);
18023        Long check = null;
18024        if (watchUids != null) {
18025            Pair<Long, String> val = watchUids.get(proc.uid);
18026            if (val == null) {
18027                val = watchUids.get(0);
18028            }
18029            if (val != null) {
18030                check = val.first;
18031            }
18032        }
18033        if (check != null) {
18034            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18035                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18036                if (!isDebuggable) {
18037                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18038                        isDebuggable = true;
18039                    }
18040                }
18041                if (isDebuggable) {
18042                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18043                    final ProcessRecord myProc = proc;
18044                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18045                    mMemWatchDumpProcName = proc.processName;
18046                    mMemWatchDumpFile = heapdumpFile.toString();
18047                    mMemWatchDumpPid = proc.pid;
18048                    mMemWatchDumpUid = proc.uid;
18049                    BackgroundThread.getHandler().post(new Runnable() {
18050                        @Override
18051                        public void run() {
18052                            revokeUriPermission(ActivityThread.currentActivityThread()
18053                                            .getApplicationThread(),
18054                                    DumpHeapActivity.JAVA_URI,
18055                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18056                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18057                                    UserHandle.myUserId());
18058                            ParcelFileDescriptor fd = null;
18059                            try {
18060                                heapdumpFile.delete();
18061                                fd = ParcelFileDescriptor.open(heapdumpFile,
18062                                        ParcelFileDescriptor.MODE_CREATE |
18063                                                ParcelFileDescriptor.MODE_TRUNCATE |
18064                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18065                                                ParcelFileDescriptor.MODE_APPEND);
18066                                IApplicationThread thread = myProc.thread;
18067                                if (thread != null) {
18068                                    try {
18069                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18070                                                "Requesting dump heap from "
18071                                                + myProc + " to " + heapdumpFile);
18072                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18073                                    } catch (RemoteException e) {
18074                                    }
18075                                }
18076                            } catch (FileNotFoundException e) {
18077                                e.printStackTrace();
18078                            } finally {
18079                                if (fd != null) {
18080                                    try {
18081                                        fd.close();
18082                                    } catch (IOException e) {
18083                                    }
18084                                }
18085                            }
18086                        }
18087                    });
18088                } else {
18089                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18090                            + ", but debugging not enabled");
18091                }
18092            }
18093        }
18094    }
18095
18096    /**
18097     * Schedule PSS collection of a process.
18098     */
18099    void requestPssLocked(ProcessRecord proc, int procState) {
18100        if (mPendingPssProcesses.contains(proc)) {
18101            return;
18102        }
18103        if (mPendingPssProcesses.size() == 0) {
18104            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18105        }
18106        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18107        proc.pssProcState = procState;
18108        mPendingPssProcesses.add(proc);
18109    }
18110
18111    /**
18112     * Schedule PSS collection of all processes.
18113     */
18114    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18115        if (!always) {
18116            if (now < (mLastFullPssTime +
18117                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18118                return;
18119            }
18120        }
18121        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18122        mLastFullPssTime = now;
18123        mFullPssPending = true;
18124        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18125        mPendingPssProcesses.clear();
18126        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18127            ProcessRecord app = mLruProcesses.get(i);
18128            if (app.thread == null
18129                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18130                continue;
18131            }
18132            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18133                app.pssProcState = app.setProcState;
18134                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18135                        mTestPssMode, isSleeping(), now);
18136                mPendingPssProcesses.add(app);
18137            }
18138        }
18139        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18140    }
18141
18142    public void setTestPssMode(boolean enabled) {
18143        synchronized (this) {
18144            mTestPssMode = enabled;
18145            if (enabled) {
18146                // Whenever we enable the mode, we want to take a snapshot all of current
18147                // process mem use.
18148                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18149            }
18150        }
18151    }
18152
18153    /**
18154     * Ask a given process to GC right now.
18155     */
18156    final void performAppGcLocked(ProcessRecord app) {
18157        try {
18158            app.lastRequestedGc = SystemClock.uptimeMillis();
18159            if (app.thread != null) {
18160                if (app.reportLowMemory) {
18161                    app.reportLowMemory = false;
18162                    app.thread.scheduleLowMemory();
18163                } else {
18164                    app.thread.processInBackground();
18165                }
18166            }
18167        } catch (Exception e) {
18168            // whatever.
18169        }
18170    }
18171
18172    /**
18173     * Returns true if things are idle enough to perform GCs.
18174     */
18175    private final boolean canGcNowLocked() {
18176        boolean processingBroadcasts = false;
18177        for (BroadcastQueue q : mBroadcastQueues) {
18178            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18179                processingBroadcasts = true;
18180            }
18181        }
18182        return !processingBroadcasts
18183                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18184    }
18185
18186    /**
18187     * Perform GCs on all processes that are waiting for it, but only
18188     * if things are idle.
18189     */
18190    final void performAppGcsLocked() {
18191        final int N = mProcessesToGc.size();
18192        if (N <= 0) {
18193            return;
18194        }
18195        if (canGcNowLocked()) {
18196            while (mProcessesToGc.size() > 0) {
18197                ProcessRecord proc = mProcessesToGc.remove(0);
18198                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18199                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18200                            <= SystemClock.uptimeMillis()) {
18201                        // To avoid spamming the system, we will GC processes one
18202                        // at a time, waiting a few seconds between each.
18203                        performAppGcLocked(proc);
18204                        scheduleAppGcsLocked();
18205                        return;
18206                    } else {
18207                        // It hasn't been long enough since we last GCed this
18208                        // process...  put it in the list to wait for its time.
18209                        addProcessToGcListLocked(proc);
18210                        break;
18211                    }
18212                }
18213            }
18214
18215            scheduleAppGcsLocked();
18216        }
18217    }
18218
18219    /**
18220     * If all looks good, perform GCs on all processes waiting for them.
18221     */
18222    final void performAppGcsIfAppropriateLocked() {
18223        if (canGcNowLocked()) {
18224            performAppGcsLocked();
18225            return;
18226        }
18227        // Still not idle, wait some more.
18228        scheduleAppGcsLocked();
18229    }
18230
18231    /**
18232     * Schedule the execution of all pending app GCs.
18233     */
18234    final void scheduleAppGcsLocked() {
18235        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18236
18237        if (mProcessesToGc.size() > 0) {
18238            // Schedule a GC for the time to the next process.
18239            ProcessRecord proc = mProcessesToGc.get(0);
18240            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18241
18242            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18243            long now = SystemClock.uptimeMillis();
18244            if (when < (now+GC_TIMEOUT)) {
18245                when = now + GC_TIMEOUT;
18246            }
18247            mHandler.sendMessageAtTime(msg, when);
18248        }
18249    }
18250
18251    /**
18252     * Add a process to the array of processes waiting to be GCed.  Keeps the
18253     * list in sorted order by the last GC time.  The process can't already be
18254     * on the list.
18255     */
18256    final void addProcessToGcListLocked(ProcessRecord proc) {
18257        boolean added = false;
18258        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18259            if (mProcessesToGc.get(i).lastRequestedGc <
18260                    proc.lastRequestedGc) {
18261                added = true;
18262                mProcessesToGc.add(i+1, proc);
18263                break;
18264            }
18265        }
18266        if (!added) {
18267            mProcessesToGc.add(0, proc);
18268        }
18269    }
18270
18271    /**
18272     * Set up to ask a process to GC itself.  This will either do it
18273     * immediately, or put it on the list of processes to gc the next
18274     * time things are idle.
18275     */
18276    final void scheduleAppGcLocked(ProcessRecord app) {
18277        long now = SystemClock.uptimeMillis();
18278        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18279            return;
18280        }
18281        if (!mProcessesToGc.contains(app)) {
18282            addProcessToGcListLocked(app);
18283            scheduleAppGcsLocked();
18284        }
18285    }
18286
18287    final void checkExcessivePowerUsageLocked(boolean doKills) {
18288        updateCpuStatsNow();
18289
18290        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18291        boolean doWakeKills = doKills;
18292        boolean doCpuKills = doKills;
18293        if (mLastPowerCheckRealtime == 0) {
18294            doWakeKills = false;
18295        }
18296        if (mLastPowerCheckUptime == 0) {
18297            doCpuKills = false;
18298        }
18299        if (stats.isScreenOn()) {
18300            doWakeKills = false;
18301        }
18302        final long curRealtime = SystemClock.elapsedRealtime();
18303        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18304        final long curUptime = SystemClock.uptimeMillis();
18305        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18306        mLastPowerCheckRealtime = curRealtime;
18307        mLastPowerCheckUptime = curUptime;
18308        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18309            doWakeKills = false;
18310        }
18311        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18312            doCpuKills = false;
18313        }
18314        int i = mLruProcesses.size();
18315        while (i > 0) {
18316            i--;
18317            ProcessRecord app = mLruProcesses.get(i);
18318            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18319                long wtime;
18320                synchronized (stats) {
18321                    wtime = stats.getProcessWakeTime(app.info.uid,
18322                            app.pid, curRealtime);
18323                }
18324                long wtimeUsed = wtime - app.lastWakeTime;
18325                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18326                if (DEBUG_POWER) {
18327                    StringBuilder sb = new StringBuilder(128);
18328                    sb.append("Wake for ");
18329                    app.toShortString(sb);
18330                    sb.append(": over ");
18331                    TimeUtils.formatDuration(realtimeSince, sb);
18332                    sb.append(" used ");
18333                    TimeUtils.formatDuration(wtimeUsed, sb);
18334                    sb.append(" (");
18335                    sb.append((wtimeUsed*100)/realtimeSince);
18336                    sb.append("%)");
18337                    Slog.i(TAG_POWER, sb.toString());
18338                    sb.setLength(0);
18339                    sb.append("CPU for ");
18340                    app.toShortString(sb);
18341                    sb.append(": over ");
18342                    TimeUtils.formatDuration(uptimeSince, sb);
18343                    sb.append(" used ");
18344                    TimeUtils.formatDuration(cputimeUsed, sb);
18345                    sb.append(" (");
18346                    sb.append((cputimeUsed*100)/uptimeSince);
18347                    sb.append("%)");
18348                    Slog.i(TAG_POWER, sb.toString());
18349                }
18350                // If a process has held a wake lock for more
18351                // than 50% of the time during this period,
18352                // that sounds bad.  Kill!
18353                if (doWakeKills && realtimeSince > 0
18354                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18355                    synchronized (stats) {
18356                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18357                                realtimeSince, wtimeUsed);
18358                    }
18359                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18360                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18361                } else if (doCpuKills && uptimeSince > 0
18362                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18363                    synchronized (stats) {
18364                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18365                                uptimeSince, cputimeUsed);
18366                    }
18367                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18368                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18369                } else {
18370                    app.lastWakeTime = wtime;
18371                    app.lastCpuTime = app.curCpuTime;
18372                }
18373            }
18374        }
18375    }
18376
18377    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18378        boolean success = true;
18379
18380        if (app.curRawAdj != app.setRawAdj) {
18381            app.setRawAdj = app.curRawAdj;
18382        }
18383
18384        int changes = 0;
18385
18386        if (app.curAdj != app.setAdj) {
18387            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18388            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18389                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18390                    + app.adjType);
18391            app.setAdj = app.curAdj;
18392        }
18393
18394        if (app.setSchedGroup != app.curSchedGroup) {
18395            app.setSchedGroup = app.curSchedGroup;
18396            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18397                    "Setting process group of " + app.processName
18398                    + " to " + app.curSchedGroup);
18399            if (app.waitingToKill != null && app.curReceiver == null
18400                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18401                app.kill(app.waitingToKill, true);
18402                success = false;
18403            } else {
18404                if (true) {
18405                    long oldId = Binder.clearCallingIdentity();
18406                    try {
18407                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18408                    } catch (Exception e) {
18409                        Slog.w(TAG, "Failed setting process group of " + app.pid
18410                                + " to " + app.curSchedGroup);
18411                        e.printStackTrace();
18412                    } finally {
18413                        Binder.restoreCallingIdentity(oldId);
18414                    }
18415                } else {
18416                    if (app.thread != null) {
18417                        try {
18418                            app.thread.setSchedulingGroup(app.curSchedGroup);
18419                        } catch (RemoteException e) {
18420                        }
18421                    }
18422                }
18423                Process.setSwappiness(app.pid,
18424                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18425            }
18426        }
18427        if (app.repForegroundActivities != app.foregroundActivities) {
18428            app.repForegroundActivities = app.foregroundActivities;
18429            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18430        }
18431        if (app.repProcState != app.curProcState) {
18432            app.repProcState = app.curProcState;
18433            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18434            if (app.thread != null) {
18435                try {
18436                    if (false) {
18437                        //RuntimeException h = new RuntimeException("here");
18438                        Slog.i(TAG, "Sending new process state " + app.repProcState
18439                                + " to " + app /*, h*/);
18440                    }
18441                    app.thread.setProcessState(app.repProcState);
18442                } catch (RemoteException e) {
18443                }
18444            }
18445        }
18446        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18447                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18448            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18449                // Experimental code to more aggressively collect pss while
18450                // running test...  the problem is that this tends to collect
18451                // the data right when a process is transitioning between process
18452                // states, which well tend to give noisy data.
18453                long start = SystemClock.uptimeMillis();
18454                long pss = Debug.getPss(app.pid, mTmpLong, null);
18455                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18456                mPendingPssProcesses.remove(app);
18457                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18458                        + " to " + app.curProcState + ": "
18459                        + (SystemClock.uptimeMillis()-start) + "ms");
18460            }
18461            app.lastStateTime = now;
18462            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18463                    mTestPssMode, isSleeping(), now);
18464            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18465                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18466                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18467                    + (app.nextPssTime-now) + ": " + app);
18468        } else {
18469            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18470                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18471                    mTestPssMode)))) {
18472                requestPssLocked(app, app.setProcState);
18473                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18474                        mTestPssMode, isSleeping(), now);
18475            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18476                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18477        }
18478        if (app.setProcState != app.curProcState) {
18479            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18480                    "Proc state change of " + app.processName
18481                    + " to " + app.curProcState);
18482            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18483            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18484            if (setImportant && !curImportant) {
18485                // This app is no longer something we consider important enough to allow to
18486                // use arbitrary amounts of battery power.  Note
18487                // its current wake lock time to later know to kill it if
18488                // it is not behaving well.
18489                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18490                synchronized (stats) {
18491                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18492                            app.pid, SystemClock.elapsedRealtime());
18493                }
18494                app.lastCpuTime = app.curCpuTime;
18495
18496            }
18497            // Inform UsageStats of important process state change
18498            // Must be called before updating setProcState
18499            maybeUpdateUsageStatsLocked(app);
18500
18501            app.setProcState = app.curProcState;
18502            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18503                app.notCachedSinceIdle = false;
18504            }
18505            if (!doingAll) {
18506                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18507            } else {
18508                app.procStateChanged = true;
18509            }
18510        }
18511
18512        if (changes != 0) {
18513            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18514                    "Changes in " + app + ": " + changes);
18515            int i = mPendingProcessChanges.size()-1;
18516            ProcessChangeItem item = null;
18517            while (i >= 0) {
18518                item = mPendingProcessChanges.get(i);
18519                if (item.pid == app.pid) {
18520                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18521                            "Re-using existing item: " + item);
18522                    break;
18523                }
18524                i--;
18525            }
18526            if (i < 0) {
18527                // No existing item in pending changes; need a new one.
18528                final int NA = mAvailProcessChanges.size();
18529                if (NA > 0) {
18530                    item = mAvailProcessChanges.remove(NA-1);
18531                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18532                            "Retrieving available item: " + item);
18533                } else {
18534                    item = new ProcessChangeItem();
18535                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18536                            "Allocating new item: " + item);
18537                }
18538                item.changes = 0;
18539                item.pid = app.pid;
18540                item.uid = app.info.uid;
18541                if (mPendingProcessChanges.size() == 0) {
18542                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18543                            "*** Enqueueing dispatch processes changed!");
18544                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18545                }
18546                mPendingProcessChanges.add(item);
18547            }
18548            item.changes |= changes;
18549            item.processState = app.repProcState;
18550            item.foregroundActivities = app.repForegroundActivities;
18551            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18552                    "Item " + Integer.toHexString(System.identityHashCode(item))
18553                    + " " + app.toShortString() + ": changes=" + item.changes
18554                    + " procState=" + item.processState
18555                    + " foreground=" + item.foregroundActivities
18556                    + " type=" + app.adjType + " source=" + app.adjSource
18557                    + " target=" + app.adjTarget);
18558        }
18559
18560        return success;
18561    }
18562
18563    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18564        if (uidRec.pendingChange == null) {
18565            if (mPendingUidChanges.size() == 0) {
18566                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18567                        "*** Enqueueing dispatch uid changed!");
18568                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18569            }
18570            final int NA = mAvailUidChanges.size();
18571            if (NA > 0) {
18572                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18573                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18574                        "Retrieving available item: " + uidRec.pendingChange);
18575            } else {
18576                uidRec.pendingChange = new UidRecord.ChangeItem();
18577                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18578                        "Allocating new item: " + uidRec.pendingChange);
18579            }
18580            uidRec.pendingChange.uidRecord = uidRec;
18581            uidRec.pendingChange.uid = uidRec.uid;
18582            mPendingUidChanges.add(uidRec.pendingChange);
18583        }
18584        uidRec.pendingChange.gone = gone;
18585        uidRec.pendingChange.processState = uidRec.setProcState;
18586    }
18587
18588    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18589        if (DEBUG_USAGE_STATS) {
18590            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18591                    + "] state changes: old = " + app.setProcState + ", new = "
18592                    + app.curProcState);
18593        }
18594        if (mUsageStatsService == null) {
18595            return;
18596        }
18597        boolean isInteraction;
18598        if (!mSleeping) {
18599            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18600            app.fgInteractionTime = 0;
18601        } else {
18602            // If the display is off, we are going to be more restrictive about what we consider
18603            // to be an app interaction.  Being the top activity doesn't count, nor do generally
18604            // foreground services.
18605            if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18606                isInteraction = true;
18607                app.fgInteractionTime = 0;
18608            } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18609                final long now = SystemClock.elapsedRealtime();
18610                if (app.fgInteractionTime == 0) {
18611                    app.fgInteractionTime = now;
18612                    isInteraction = false;
18613                } else {
18614                    isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18615                }
18616            } else {
18617                isInteraction = app.curProcState
18618                        <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18619                app.fgInteractionTime = 0;
18620            }
18621        }
18622        if (isInteraction && !app.reportedInteraction) {
18623            String[] packages = app.getPackageList();
18624            if (packages != null) {
18625                for (int i = 0; i < packages.length; i++) {
18626                    mUsageStatsService.reportEvent(packages[i], app.userId,
18627                            UsageEvents.Event.SYSTEM_INTERACTION);
18628                }
18629            }
18630        }
18631        app.reportedInteraction = isInteraction;
18632    }
18633
18634    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18635        if (proc.thread != null) {
18636            if (proc.baseProcessTracker != null) {
18637                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18638            }
18639            if (proc.repProcState >= 0) {
18640                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18641                        proc.repProcState);
18642            }
18643        }
18644    }
18645
18646    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18647            ProcessRecord TOP_APP, boolean doingAll, long now) {
18648        if (app.thread == null) {
18649            return false;
18650        }
18651
18652        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18653
18654        return applyOomAdjLocked(app, doingAll, now);
18655    }
18656
18657    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18658            boolean oomAdj) {
18659        if (isForeground != proc.foregroundServices) {
18660            proc.foregroundServices = isForeground;
18661            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18662                    proc.info.uid);
18663            if (isForeground) {
18664                if (curProcs == null) {
18665                    curProcs = new ArrayList<ProcessRecord>();
18666                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18667                }
18668                if (!curProcs.contains(proc)) {
18669                    curProcs.add(proc);
18670                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18671                            proc.info.packageName, proc.info.uid);
18672                }
18673            } else {
18674                if (curProcs != null) {
18675                    if (curProcs.remove(proc)) {
18676                        mBatteryStatsService.noteEvent(
18677                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18678                                proc.info.packageName, proc.info.uid);
18679                        if (curProcs.size() <= 0) {
18680                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18681                        }
18682                    }
18683                }
18684            }
18685            if (oomAdj) {
18686                updateOomAdjLocked();
18687            }
18688        }
18689    }
18690
18691    private final ActivityRecord resumedAppLocked() {
18692        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18693        String pkg;
18694        int uid;
18695        if (act != null) {
18696            pkg = act.packageName;
18697            uid = act.info.applicationInfo.uid;
18698        } else {
18699            pkg = null;
18700            uid = -1;
18701        }
18702        // Has the UID or resumed package name changed?
18703        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18704                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18705            if (mCurResumedPackage != null) {
18706                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18707                        mCurResumedPackage, mCurResumedUid);
18708            }
18709            mCurResumedPackage = pkg;
18710            mCurResumedUid = uid;
18711            if (mCurResumedPackage != null) {
18712                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18713                        mCurResumedPackage, mCurResumedUid);
18714            }
18715        }
18716        return act;
18717    }
18718
18719    final boolean updateOomAdjLocked(ProcessRecord app) {
18720        final ActivityRecord TOP_ACT = resumedAppLocked();
18721        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18722        final boolean wasCached = app.cached;
18723
18724        mAdjSeq++;
18725
18726        // This is the desired cached adjusment we want to tell it to use.
18727        // If our app is currently cached, we know it, and that is it.  Otherwise,
18728        // we don't know it yet, and it needs to now be cached we will then
18729        // need to do a complete oom adj.
18730        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18731                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18732        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18733                SystemClock.uptimeMillis());
18734        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18735            // Changed to/from cached state, so apps after it in the LRU
18736            // list may also be changed.
18737            updateOomAdjLocked();
18738        }
18739        return success;
18740    }
18741
18742    final void updateOomAdjLocked() {
18743        final ActivityRecord TOP_ACT = resumedAppLocked();
18744        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18745        final long now = SystemClock.uptimeMillis();
18746        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18747        final int N = mLruProcesses.size();
18748
18749        if (false) {
18750            RuntimeException e = new RuntimeException();
18751            e.fillInStackTrace();
18752            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18753        }
18754
18755        // Reset state in all uid records.
18756        for (int i=mActiveUids.size()-1; i>=0; i--) {
18757            final UidRecord uidRec = mActiveUids.valueAt(i);
18758            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18759                    "Starting update of " + uidRec);
18760            uidRec.reset();
18761        }
18762
18763        mAdjSeq++;
18764        mNewNumServiceProcs = 0;
18765        mNewNumAServiceProcs = 0;
18766
18767        final int emptyProcessLimit;
18768        final int cachedProcessLimit;
18769        if (mProcessLimit <= 0) {
18770            emptyProcessLimit = cachedProcessLimit = 0;
18771        } else if (mProcessLimit == 1) {
18772            emptyProcessLimit = 1;
18773            cachedProcessLimit = 0;
18774        } else {
18775            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18776            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18777        }
18778
18779        // Let's determine how many processes we have running vs.
18780        // how many slots we have for background processes; we may want
18781        // to put multiple processes in a slot of there are enough of
18782        // them.
18783        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18784                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18785        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18786        if (numEmptyProcs > cachedProcessLimit) {
18787            // If there are more empty processes than our limit on cached
18788            // processes, then use the cached process limit for the factor.
18789            // This ensures that the really old empty processes get pushed
18790            // down to the bottom, so if we are running low on memory we will
18791            // have a better chance at keeping around more cached processes
18792            // instead of a gazillion empty processes.
18793            numEmptyProcs = cachedProcessLimit;
18794        }
18795        int emptyFactor = numEmptyProcs/numSlots;
18796        if (emptyFactor < 1) emptyFactor = 1;
18797        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18798        if (cachedFactor < 1) cachedFactor = 1;
18799        int stepCached = 0;
18800        int stepEmpty = 0;
18801        int numCached = 0;
18802        int numEmpty = 0;
18803        int numTrimming = 0;
18804
18805        mNumNonCachedProcs = 0;
18806        mNumCachedHiddenProcs = 0;
18807
18808        // First update the OOM adjustment for each of the
18809        // application processes based on their current state.
18810        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18811        int nextCachedAdj = curCachedAdj+1;
18812        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18813        int nextEmptyAdj = curEmptyAdj+2;
18814        for (int i=N-1; i>=0; i--) {
18815            ProcessRecord app = mLruProcesses.get(i);
18816            if (!app.killedByAm && app.thread != null) {
18817                app.procStateChanged = false;
18818                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18819
18820                // If we haven't yet assigned the final cached adj
18821                // to the process, do that now.
18822                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18823                    switch (app.curProcState) {
18824                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18825                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18826                            // This process is a cached process holding activities...
18827                            // assign it the next cached value for that type, and then
18828                            // step that cached level.
18829                            app.curRawAdj = curCachedAdj;
18830                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18831                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18832                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18833                                    + ")");
18834                            if (curCachedAdj != nextCachedAdj) {
18835                                stepCached++;
18836                                if (stepCached >= cachedFactor) {
18837                                    stepCached = 0;
18838                                    curCachedAdj = nextCachedAdj;
18839                                    nextCachedAdj += 2;
18840                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18841                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18842                                    }
18843                                }
18844                            }
18845                            break;
18846                        default:
18847                            // For everything else, assign next empty cached process
18848                            // level and bump that up.  Note that this means that
18849                            // long-running services that have dropped down to the
18850                            // cached level will be treated as empty (since their process
18851                            // state is still as a service), which is what we want.
18852                            app.curRawAdj = curEmptyAdj;
18853                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18854                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18855                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18856                                    + ")");
18857                            if (curEmptyAdj != nextEmptyAdj) {
18858                                stepEmpty++;
18859                                if (stepEmpty >= emptyFactor) {
18860                                    stepEmpty = 0;
18861                                    curEmptyAdj = nextEmptyAdj;
18862                                    nextEmptyAdj += 2;
18863                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18864                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18865                                    }
18866                                }
18867                            }
18868                            break;
18869                    }
18870                }
18871
18872                applyOomAdjLocked(app, true, now);
18873
18874                // Count the number of process types.
18875                switch (app.curProcState) {
18876                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18877                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18878                        mNumCachedHiddenProcs++;
18879                        numCached++;
18880                        if (numCached > cachedProcessLimit) {
18881                            app.kill("cached #" + numCached, true);
18882                        }
18883                        break;
18884                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18885                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18886                                && app.lastActivityTime < oldTime) {
18887                            app.kill("empty for "
18888                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18889                                    / 1000) + "s", true);
18890                        } else {
18891                            numEmpty++;
18892                            if (numEmpty > emptyProcessLimit) {
18893                                app.kill("empty #" + numEmpty, true);
18894                            }
18895                        }
18896                        break;
18897                    default:
18898                        mNumNonCachedProcs++;
18899                        break;
18900                }
18901
18902                if (app.isolated && app.services.size() <= 0) {
18903                    // If this is an isolated process, and there are no
18904                    // services running in it, then the process is no longer
18905                    // needed.  We agressively kill these because we can by
18906                    // definition not re-use the same process again, and it is
18907                    // good to avoid having whatever code was running in them
18908                    // left sitting around after no longer needed.
18909                    app.kill("isolated not needed", true);
18910                } else {
18911                    // Keeping this process, update its uid.
18912                    final UidRecord uidRec = app.uidRecord;
18913                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
18914                        uidRec.curProcState = app.curProcState;
18915                    }
18916                }
18917
18918                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18919                        && !app.killedByAm) {
18920                    numTrimming++;
18921                }
18922            }
18923        }
18924
18925        mNumServiceProcs = mNewNumServiceProcs;
18926
18927        // Now determine the memory trimming level of background processes.
18928        // Unfortunately we need to start at the back of the list to do this
18929        // properly.  We only do this if the number of background apps we
18930        // are managing to keep around is less than half the maximum we desire;
18931        // if we are keeping a good number around, we'll let them use whatever
18932        // memory they want.
18933        final int numCachedAndEmpty = numCached + numEmpty;
18934        int memFactor;
18935        if (numCached <= ProcessList.TRIM_CACHED_APPS
18936                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18937            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18938                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18939            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18940                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18941            } else {
18942                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18943            }
18944        } else {
18945            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18946        }
18947        // We always allow the memory level to go up (better).  We only allow it to go
18948        // down if we are in a state where that is allowed, *and* the total number of processes
18949        // has gone down since last time.
18950        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18951                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18952                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18953        if (memFactor > mLastMemoryLevel) {
18954            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18955                memFactor = mLastMemoryLevel;
18956                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18957            }
18958        }
18959        mLastMemoryLevel = memFactor;
18960        mLastNumProcesses = mLruProcesses.size();
18961        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18962        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18963        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18964            if (mLowRamStartTime == 0) {
18965                mLowRamStartTime = now;
18966            }
18967            int step = 0;
18968            int fgTrimLevel;
18969            switch (memFactor) {
18970                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18971                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18972                    break;
18973                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18974                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18975                    break;
18976                default:
18977                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18978                    break;
18979            }
18980            int factor = numTrimming/3;
18981            int minFactor = 2;
18982            if (mHomeProcess != null) minFactor++;
18983            if (mPreviousProcess != null) minFactor++;
18984            if (factor < minFactor) factor = minFactor;
18985            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18986            for (int i=N-1; i>=0; i--) {
18987                ProcessRecord app = mLruProcesses.get(i);
18988                if (allChanged || app.procStateChanged) {
18989                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18990                    app.procStateChanged = false;
18991                }
18992                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18993                        && !app.killedByAm) {
18994                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18995                        try {
18996                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18997                                    "Trimming memory of " + app.processName + " to " + curLevel);
18998                            app.thread.scheduleTrimMemory(curLevel);
18999                        } catch (RemoteException e) {
19000                        }
19001                        if (false) {
19002                            // For now we won't do this; our memory trimming seems
19003                            // to be good enough at this point that destroying
19004                            // activities causes more harm than good.
19005                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19006                                    && app != mHomeProcess && app != mPreviousProcess) {
19007                                // Need to do this on its own message because the stack may not
19008                                // be in a consistent state at this point.
19009                                // For these apps we will also finish their activities
19010                                // to help them free memory.
19011                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19012                            }
19013                        }
19014                    }
19015                    app.trimMemoryLevel = curLevel;
19016                    step++;
19017                    if (step >= factor) {
19018                        step = 0;
19019                        switch (curLevel) {
19020                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19021                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19022                                break;
19023                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19024                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19025                                break;
19026                        }
19027                    }
19028                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19029                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19030                            && app.thread != null) {
19031                        try {
19032                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19033                                    "Trimming memory of heavy-weight " + app.processName
19034                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19035                            app.thread.scheduleTrimMemory(
19036                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19037                        } catch (RemoteException e) {
19038                        }
19039                    }
19040                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19041                } else {
19042                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19043                            || app.systemNoUi) && app.pendingUiClean) {
19044                        // If this application is now in the background and it
19045                        // had done UI, then give it the special trim level to
19046                        // have it free UI resources.
19047                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19048                        if (app.trimMemoryLevel < level && app.thread != null) {
19049                            try {
19050                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19051                                        "Trimming memory of bg-ui " + app.processName
19052                                        + " to " + level);
19053                                app.thread.scheduleTrimMemory(level);
19054                            } catch (RemoteException e) {
19055                            }
19056                        }
19057                        app.pendingUiClean = false;
19058                    }
19059                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19060                        try {
19061                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19062                                    "Trimming memory of fg " + app.processName
19063                                    + " to " + fgTrimLevel);
19064                            app.thread.scheduleTrimMemory(fgTrimLevel);
19065                        } catch (RemoteException e) {
19066                        }
19067                    }
19068                    app.trimMemoryLevel = fgTrimLevel;
19069                }
19070            }
19071        } else {
19072            if (mLowRamStartTime != 0) {
19073                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19074                mLowRamStartTime = 0;
19075            }
19076            for (int i=N-1; i>=0; i--) {
19077                ProcessRecord app = mLruProcesses.get(i);
19078                if (allChanged || app.procStateChanged) {
19079                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19080                    app.procStateChanged = false;
19081                }
19082                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19083                        || app.systemNoUi) && app.pendingUiClean) {
19084                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19085                            && app.thread != null) {
19086                        try {
19087                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19088                                    "Trimming memory of ui hidden " + app.processName
19089                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19090                            app.thread.scheduleTrimMemory(
19091                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19092                        } catch (RemoteException e) {
19093                        }
19094                    }
19095                    app.pendingUiClean = false;
19096                }
19097                app.trimMemoryLevel = 0;
19098            }
19099        }
19100
19101        if (mAlwaysFinishActivities) {
19102            // Need to do this on its own message because the stack may not
19103            // be in a consistent state at this point.
19104            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19105        }
19106
19107        if (allChanged) {
19108            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19109        }
19110
19111        // Update from any uid changes.
19112        for (int i=mActiveUids.size()-1; i>=0; i--) {
19113            final UidRecord uidRec = mActiveUids.valueAt(i);
19114            if (uidRec.setProcState != uidRec.curProcState) {
19115                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19116                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19117                        + " to " + uidRec.curProcState);
19118                uidRec.setProcState = uidRec.curProcState;
19119                enqueueUidChangeLocked(uidRec, false);
19120            }
19121        }
19122
19123        if (mProcessStats.shouldWriteNowLocked(now)) {
19124            mHandler.post(new Runnable() {
19125                @Override public void run() {
19126                    synchronized (ActivityManagerService.this) {
19127                        mProcessStats.writeStateAsyncLocked();
19128                    }
19129                }
19130            });
19131        }
19132
19133        if (DEBUG_OOM_ADJ) {
19134            final long duration = SystemClock.uptimeMillis() - now;
19135            if (false) {
19136                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19137                        new RuntimeException("here").fillInStackTrace());
19138            } else {
19139                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19140            }
19141        }
19142    }
19143
19144    final void trimApplications() {
19145        synchronized (this) {
19146            int i;
19147
19148            // First remove any unused application processes whose package
19149            // has been removed.
19150            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19151                final ProcessRecord app = mRemovedProcesses.get(i);
19152                if (app.activities.size() == 0
19153                        && app.curReceiver == null && app.services.size() == 0) {
19154                    Slog.i(
19155                        TAG, "Exiting empty application process "
19156                        + app.processName + " ("
19157                        + (app.thread != null ? app.thread.asBinder() : null)
19158                        + ")\n");
19159                    if (app.pid > 0 && app.pid != MY_PID) {
19160                        app.kill("empty", false);
19161                    } else {
19162                        try {
19163                            app.thread.scheduleExit();
19164                        } catch (Exception e) {
19165                            // Ignore exceptions.
19166                        }
19167                    }
19168                    cleanUpApplicationRecordLocked(app, false, true, -1);
19169                    mRemovedProcesses.remove(i);
19170
19171                    if (app.persistent) {
19172                        addAppLocked(app.info, false, null /* ABI override */);
19173                    }
19174                }
19175            }
19176
19177            // Now update the oom adj for all processes.
19178            updateOomAdjLocked();
19179        }
19180    }
19181
19182    /** This method sends the specified signal to each of the persistent apps */
19183    public void signalPersistentProcesses(int sig) throws RemoteException {
19184        if (sig != Process.SIGNAL_USR1) {
19185            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19186        }
19187
19188        synchronized (this) {
19189            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19190                    != PackageManager.PERMISSION_GRANTED) {
19191                throw new SecurityException("Requires permission "
19192                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19193            }
19194
19195            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19196                ProcessRecord r = mLruProcesses.get(i);
19197                if (r.thread != null && r.persistent) {
19198                    Process.sendSignal(r.pid, sig);
19199                }
19200            }
19201        }
19202    }
19203
19204    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19205        if (proc == null || proc == mProfileProc) {
19206            proc = mProfileProc;
19207            profileType = mProfileType;
19208            clearProfilerLocked();
19209        }
19210        if (proc == null) {
19211            return;
19212        }
19213        try {
19214            proc.thread.profilerControl(false, null, profileType);
19215        } catch (RemoteException e) {
19216            throw new IllegalStateException("Process disappeared");
19217        }
19218    }
19219
19220    private void clearProfilerLocked() {
19221        if (mProfileFd != null) {
19222            try {
19223                mProfileFd.close();
19224            } catch (IOException e) {
19225            }
19226        }
19227        mProfileApp = null;
19228        mProfileProc = null;
19229        mProfileFile = null;
19230        mProfileType = 0;
19231        mAutoStopProfiler = false;
19232        mSamplingInterval = 0;
19233    }
19234
19235    public boolean profileControl(String process, int userId, boolean start,
19236            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19237
19238        try {
19239            synchronized (this) {
19240                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19241                // its own permission.
19242                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19243                        != PackageManager.PERMISSION_GRANTED) {
19244                    throw new SecurityException("Requires permission "
19245                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19246                }
19247
19248                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19249                    throw new IllegalArgumentException("null profile info or fd");
19250                }
19251
19252                ProcessRecord proc = null;
19253                if (process != null) {
19254                    proc = findProcessLocked(process, userId, "profileControl");
19255                }
19256
19257                if (start && (proc == null || proc.thread == null)) {
19258                    throw new IllegalArgumentException("Unknown process: " + process);
19259                }
19260
19261                if (start) {
19262                    stopProfilerLocked(null, 0);
19263                    setProfileApp(proc.info, proc.processName, profilerInfo);
19264                    mProfileProc = proc;
19265                    mProfileType = profileType;
19266                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19267                    try {
19268                        fd = fd.dup();
19269                    } catch (IOException e) {
19270                        fd = null;
19271                    }
19272                    profilerInfo.profileFd = fd;
19273                    proc.thread.profilerControl(start, profilerInfo, profileType);
19274                    fd = null;
19275                    mProfileFd = null;
19276                } else {
19277                    stopProfilerLocked(proc, profileType);
19278                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19279                        try {
19280                            profilerInfo.profileFd.close();
19281                        } catch (IOException e) {
19282                        }
19283                    }
19284                }
19285
19286                return true;
19287            }
19288        } catch (RemoteException e) {
19289            throw new IllegalStateException("Process disappeared");
19290        } finally {
19291            if (profilerInfo != null && profilerInfo.profileFd != null) {
19292                try {
19293                    profilerInfo.profileFd.close();
19294                } catch (IOException e) {
19295                }
19296            }
19297        }
19298    }
19299
19300    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19301        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19302                userId, true, ALLOW_FULL_ONLY, callName, null);
19303        ProcessRecord proc = null;
19304        try {
19305            int pid = Integer.parseInt(process);
19306            synchronized (mPidsSelfLocked) {
19307                proc = mPidsSelfLocked.get(pid);
19308            }
19309        } catch (NumberFormatException e) {
19310        }
19311
19312        if (proc == null) {
19313            ArrayMap<String, SparseArray<ProcessRecord>> all
19314                    = mProcessNames.getMap();
19315            SparseArray<ProcessRecord> procs = all.get(process);
19316            if (procs != null && procs.size() > 0) {
19317                proc = procs.valueAt(0);
19318                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19319                    for (int i=1; i<procs.size(); i++) {
19320                        ProcessRecord thisProc = procs.valueAt(i);
19321                        if (thisProc.userId == userId) {
19322                            proc = thisProc;
19323                            break;
19324                        }
19325                    }
19326                }
19327            }
19328        }
19329
19330        return proc;
19331    }
19332
19333    public boolean dumpHeap(String process, int userId, boolean managed,
19334            String path, ParcelFileDescriptor fd) throws RemoteException {
19335
19336        try {
19337            synchronized (this) {
19338                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19339                // its own permission (same as profileControl).
19340                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19341                        != PackageManager.PERMISSION_GRANTED) {
19342                    throw new SecurityException("Requires permission "
19343                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19344                }
19345
19346                if (fd == null) {
19347                    throw new IllegalArgumentException("null fd");
19348                }
19349
19350                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19351                if (proc == null || proc.thread == null) {
19352                    throw new IllegalArgumentException("Unknown process: " + process);
19353                }
19354
19355                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19356                if (!isDebuggable) {
19357                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19358                        throw new SecurityException("Process not debuggable: " + proc);
19359                    }
19360                }
19361
19362                proc.thread.dumpHeap(managed, path, fd);
19363                fd = null;
19364                return true;
19365            }
19366        } catch (RemoteException e) {
19367            throw new IllegalStateException("Process disappeared");
19368        } finally {
19369            if (fd != null) {
19370                try {
19371                    fd.close();
19372                } catch (IOException e) {
19373                }
19374            }
19375        }
19376    }
19377
19378    @Override
19379    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19380            String reportPackage) {
19381        if (processName != null) {
19382            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19383                    "setDumpHeapDebugLimit()");
19384        } else {
19385            synchronized (mPidsSelfLocked) {
19386                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19387                if (proc == null) {
19388                    throw new SecurityException("No process found for calling pid "
19389                            + Binder.getCallingPid());
19390                }
19391                if (!Build.IS_DEBUGGABLE
19392                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19393                    throw new SecurityException("Not running a debuggable build");
19394                }
19395                processName = proc.processName;
19396                uid = proc.uid;
19397                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19398                    throw new SecurityException("Package " + reportPackage + " is not running in "
19399                            + proc);
19400                }
19401            }
19402        }
19403        synchronized (this) {
19404            if (maxMemSize > 0) {
19405                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19406            } else {
19407                if (uid != 0) {
19408                    mMemWatchProcesses.remove(processName, uid);
19409                } else {
19410                    mMemWatchProcesses.getMap().remove(processName);
19411                }
19412            }
19413        }
19414    }
19415
19416    @Override
19417    public void dumpHeapFinished(String path) {
19418        synchronized (this) {
19419            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19420                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19421                        + " does not match last pid " + mMemWatchDumpPid);
19422                return;
19423            }
19424            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19425                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19426                        + " does not match last path " + mMemWatchDumpFile);
19427                return;
19428            }
19429            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19430            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19431        }
19432    }
19433
19434    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19435    public void monitor() {
19436        synchronized (this) { }
19437    }
19438
19439    void onCoreSettingsChange(Bundle settings) {
19440        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19441            ProcessRecord processRecord = mLruProcesses.get(i);
19442            try {
19443                if (processRecord.thread != null) {
19444                    processRecord.thread.setCoreSettings(settings);
19445                }
19446            } catch (RemoteException re) {
19447                /* ignore */
19448            }
19449        }
19450    }
19451
19452    // Multi-user methods
19453
19454    /**
19455     * Start user, if its not already running, but don't bring it to foreground.
19456     */
19457    @Override
19458    public boolean startUserInBackground(final int userId) {
19459        return startUser(userId, /* foreground */ false);
19460    }
19461
19462    /**
19463     * Start user, if its not already running, and bring it to foreground.
19464     */
19465    boolean startUserInForeground(final int userId, Dialog dlg) {
19466        boolean result = startUser(userId, /* foreground */ true);
19467        dlg.dismiss();
19468        return result;
19469    }
19470
19471    /**
19472     * Refreshes the list of users related to the current user when either a
19473     * user switch happens or when a new related user is started in the
19474     * background.
19475     */
19476    private void updateCurrentProfileIdsLocked() {
19477        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19478                mCurrentUserId, false /* enabledOnly */);
19479        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19480        for (int i = 0; i < currentProfileIds.length; i++) {
19481            currentProfileIds[i] = profiles.get(i).id;
19482        }
19483        mCurrentProfileIds = currentProfileIds;
19484
19485        synchronized (mUserProfileGroupIdsSelfLocked) {
19486            mUserProfileGroupIdsSelfLocked.clear();
19487            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19488            for (int i = 0; i < users.size(); i++) {
19489                UserInfo user = users.get(i);
19490                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19491                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19492                }
19493            }
19494        }
19495    }
19496
19497    private Set<Integer> getProfileIdsLocked(int userId) {
19498        Set<Integer> userIds = new HashSet<Integer>();
19499        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19500                userId, false /* enabledOnly */);
19501        for (UserInfo user : profiles) {
19502            userIds.add(Integer.valueOf(user.id));
19503        }
19504        return userIds;
19505    }
19506
19507    @Override
19508    public boolean switchUser(final int userId) {
19509        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19510        String userName;
19511        synchronized (this) {
19512            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19513            if (userInfo == null) {
19514                Slog.w(TAG, "No user info for user #" + userId);
19515                return false;
19516            }
19517            if (userInfo.isManagedProfile()) {
19518                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19519                return false;
19520            }
19521            userName = userInfo.name;
19522            mTargetUserId = userId;
19523        }
19524        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19525        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19526        return true;
19527    }
19528
19529    private void showUserSwitchDialog(int userId, String userName) {
19530        // The dialog will show and then initiate the user switch by calling startUserInForeground
19531        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19532                true /* above system */);
19533        d.show();
19534    }
19535
19536    private boolean startUser(final int userId, final boolean foreground) {
19537        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19538                != PackageManager.PERMISSION_GRANTED) {
19539            String msg = "Permission Denial: switchUser() from pid="
19540                    + Binder.getCallingPid()
19541                    + ", uid=" + Binder.getCallingUid()
19542                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19543            Slog.w(TAG, msg);
19544            throw new SecurityException(msg);
19545        }
19546
19547        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19548
19549        final long ident = Binder.clearCallingIdentity();
19550        try {
19551            synchronized (this) {
19552                final int oldUserId = mCurrentUserId;
19553                if (oldUserId == userId) {
19554                    return true;
19555                }
19556
19557                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19558                        "startUser", false);
19559
19560                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19561                if (userInfo == null) {
19562                    Slog.w(TAG, "No user info for user #" + userId);
19563                    return false;
19564                }
19565                if (foreground && userInfo.isManagedProfile()) {
19566                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19567                    return false;
19568                }
19569
19570                if (foreground) {
19571                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19572                            R.anim.screen_user_enter);
19573                }
19574
19575                boolean needStart = false;
19576
19577                // If the user we are switching to is not currently started, then
19578                // we need to start it now.
19579                if (mStartedUsers.get(userId) == null) {
19580                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19581                    updateStartedUserArrayLocked();
19582                    needStart = true;
19583                }
19584
19585                final Integer userIdInt = Integer.valueOf(userId);
19586                mUserLru.remove(userIdInt);
19587                mUserLru.add(userIdInt);
19588
19589                if (foreground) {
19590                    mCurrentUserId = userId;
19591                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19592                    updateCurrentProfileIdsLocked();
19593                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19594                    // Once the internal notion of the active user has switched, we lock the device
19595                    // with the option to show the user switcher on the keyguard.
19596                    mWindowManager.lockNow(null);
19597                } else {
19598                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19599                    updateCurrentProfileIdsLocked();
19600                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19601                    mUserLru.remove(currentUserIdInt);
19602                    mUserLru.add(currentUserIdInt);
19603                }
19604
19605                final UserStartedState uss = mStartedUsers.get(userId);
19606
19607                // Make sure user is in the started state.  If it is currently
19608                // stopping, we need to knock that off.
19609                if (uss.mState == UserStartedState.STATE_STOPPING) {
19610                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19611                    // so we can just fairly silently bring the user back from
19612                    // the almost-dead.
19613                    uss.mState = UserStartedState.STATE_RUNNING;
19614                    updateStartedUserArrayLocked();
19615                    needStart = true;
19616                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19617                    // This means ACTION_SHUTDOWN has been sent, so we will
19618                    // need to treat this as a new boot of the user.
19619                    uss.mState = UserStartedState.STATE_BOOTING;
19620                    updateStartedUserArrayLocked();
19621                    needStart = true;
19622                }
19623
19624                if (uss.mState == UserStartedState.STATE_BOOTING) {
19625                    // Booting up a new user, need to tell system services about it.
19626                    // Note that this is on the same handler as scheduling of broadcasts,
19627                    // which is important because it needs to go first.
19628                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19629                }
19630
19631                if (foreground) {
19632                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19633                            oldUserId));
19634                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19635                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19636                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19637                            oldUserId, userId, uss));
19638                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19639                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19640                }
19641
19642                if (needStart) {
19643                    // Send USER_STARTED broadcast
19644                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19645                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19646                            | Intent.FLAG_RECEIVER_FOREGROUND);
19647                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19648                    broadcastIntentLocked(null, null, intent,
19649                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19650                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19651                }
19652
19653                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19654                    if (userId != UserHandle.USER_OWNER) {
19655                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19656                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19657                        broadcastIntentLocked(null, null, intent, null,
19658                                new IIntentReceiver.Stub() {
19659                                    public void performReceive(Intent intent, int resultCode,
19660                                            String data, Bundle extras, boolean ordered,
19661                                            boolean sticky, int sendingUser) {
19662                                        onUserInitialized(uss, foreground, oldUserId, userId);
19663                                    }
19664                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19665                                true, false, MY_PID, Process.SYSTEM_UID,
19666                                userId);
19667                        uss.initializing = true;
19668                    } else {
19669                        getUserManagerLocked().makeInitialized(userInfo.id);
19670                    }
19671                }
19672
19673                if (foreground) {
19674                    if (!uss.initializing) {
19675                        moveUserToForeground(uss, oldUserId, userId);
19676                    }
19677                } else {
19678                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19679                }
19680
19681                if (needStart) {
19682                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19683                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19684                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19685                    broadcastIntentLocked(null, null, intent,
19686                            null, new IIntentReceiver.Stub() {
19687                                @Override
19688                                public void performReceive(Intent intent, int resultCode, String data,
19689                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19690                                        throws RemoteException {
19691                                }
19692                            }, 0, null, null,
19693                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19694                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19695                }
19696            }
19697        } finally {
19698            Binder.restoreCallingIdentity(ident);
19699        }
19700
19701        return true;
19702    }
19703
19704    void dispatchForegroundProfileChanged(int userId) {
19705        final int N = mUserSwitchObservers.beginBroadcast();
19706        for (int i = 0; i < N; i++) {
19707            try {
19708                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19709            } catch (RemoteException e) {
19710                // Ignore
19711            }
19712        }
19713        mUserSwitchObservers.finishBroadcast();
19714    }
19715
19716    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19717        long ident = Binder.clearCallingIdentity();
19718        try {
19719            Intent intent;
19720            if (oldUserId >= 0) {
19721                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19722                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19723                int count = profiles.size();
19724                for (int i = 0; i < count; i++) {
19725                    int profileUserId = profiles.get(i).id;
19726                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19727                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19728                            | Intent.FLAG_RECEIVER_FOREGROUND);
19729                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19730                    broadcastIntentLocked(null, null, intent,
19731                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19732                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19733                }
19734            }
19735            if (newUserId >= 0) {
19736                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19737                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19738                int count = profiles.size();
19739                for (int i = 0; i < count; i++) {
19740                    int profileUserId = profiles.get(i).id;
19741                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19742                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19743                            | Intent.FLAG_RECEIVER_FOREGROUND);
19744                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19745                    broadcastIntentLocked(null, null, intent,
19746                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19747                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19748                }
19749                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19750                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19751                        | Intent.FLAG_RECEIVER_FOREGROUND);
19752                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19753                broadcastIntentLocked(null, null, intent,
19754                        null, null, 0, null, null,
19755                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19756                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19757            }
19758        } finally {
19759            Binder.restoreCallingIdentity(ident);
19760        }
19761    }
19762
19763    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19764            final int newUserId) {
19765        final int N = mUserSwitchObservers.beginBroadcast();
19766        if (N > 0) {
19767            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19768                int mCount = 0;
19769                @Override
19770                public void sendResult(Bundle data) throws RemoteException {
19771                    synchronized (ActivityManagerService.this) {
19772                        if (mCurUserSwitchCallback == this) {
19773                            mCount++;
19774                            if (mCount == N) {
19775                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19776                            }
19777                        }
19778                    }
19779                }
19780            };
19781            synchronized (this) {
19782                uss.switching = true;
19783                mCurUserSwitchCallback = callback;
19784            }
19785            for (int i=0; i<N; i++) {
19786                try {
19787                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19788                            newUserId, callback);
19789                } catch (RemoteException e) {
19790                }
19791            }
19792        } else {
19793            synchronized (this) {
19794                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19795            }
19796        }
19797        mUserSwitchObservers.finishBroadcast();
19798    }
19799
19800    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19801        synchronized (this) {
19802            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19803            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19804        }
19805    }
19806
19807    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19808        mCurUserSwitchCallback = null;
19809        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19810        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19811                oldUserId, newUserId, uss));
19812    }
19813
19814    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19815        synchronized (this) {
19816            if (foreground) {
19817                moveUserToForeground(uss, oldUserId, newUserId);
19818            }
19819        }
19820
19821        completeSwitchAndInitalize(uss, newUserId, true, false);
19822    }
19823
19824    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19825        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19826        if (homeInFront) {
19827            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19828        } else {
19829            mStackSupervisor.resumeTopActivitiesLocked();
19830        }
19831        EventLogTags.writeAmSwitchUser(newUserId);
19832        getUserManagerLocked().onUserForeground(newUserId);
19833        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19834    }
19835
19836    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19837        completeSwitchAndInitalize(uss, newUserId, false, true);
19838    }
19839
19840    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19841            boolean clearInitializing, boolean clearSwitching) {
19842        boolean unfrozen = false;
19843        synchronized (this) {
19844            if (clearInitializing) {
19845                uss.initializing = false;
19846                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19847            }
19848            if (clearSwitching) {
19849                uss.switching = false;
19850            }
19851            if (!uss.switching && !uss.initializing) {
19852                mWindowManager.stopFreezingScreen();
19853                unfrozen = true;
19854            }
19855        }
19856        if (unfrozen) {
19857            final int N = mUserSwitchObservers.beginBroadcast();
19858            for (int i=0; i<N; i++) {
19859                try {
19860                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19861                } catch (RemoteException e) {
19862                }
19863            }
19864            mUserSwitchObservers.finishBroadcast();
19865        }
19866        stopGuestUserIfBackground();
19867    }
19868
19869    /**
19870     * Stops the guest user if it has gone to the background.
19871     */
19872    private void stopGuestUserIfBackground() {
19873        synchronized (this) {
19874            final int num = mUserLru.size();
19875            for (int i = 0; i < num; i++) {
19876                Integer oldUserId = mUserLru.get(i);
19877                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19878                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19879                        || oldUss.mState == UserStartedState.STATE_STOPPING
19880                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19881                    continue;
19882                }
19883                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19884                if (userInfo.isGuest()) {
19885                    // This is a user to be stopped.
19886                    stopUserLocked(oldUserId, null);
19887                    break;
19888                }
19889            }
19890        }
19891    }
19892
19893    void scheduleStartProfilesLocked() {
19894        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19895            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19896                    DateUtils.SECOND_IN_MILLIS);
19897        }
19898    }
19899
19900    void startProfilesLocked() {
19901        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19902        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19903                mCurrentUserId, false /* enabledOnly */);
19904        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19905        for (UserInfo user : profiles) {
19906            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19907                    && user.id != mCurrentUserId) {
19908                toStart.add(user);
19909            }
19910        }
19911        final int n = toStart.size();
19912        int i = 0;
19913        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19914            startUserInBackground(toStart.get(i).id);
19915        }
19916        if (i < n) {
19917            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19918        }
19919    }
19920
19921    void finishUserBoot(UserStartedState uss) {
19922        synchronized (this) {
19923            if (uss.mState == UserStartedState.STATE_BOOTING
19924                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19925                uss.mState = UserStartedState.STATE_RUNNING;
19926                final int userId = uss.mHandle.getIdentifier();
19927                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19928                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19929                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19930                broadcastIntentLocked(null, null, intent,
19931                        null, null, 0, null, null,
19932                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19933                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19934            }
19935        }
19936    }
19937
19938    void finishUserSwitch(UserStartedState uss) {
19939        synchronized (this) {
19940            finishUserBoot(uss);
19941
19942            startProfilesLocked();
19943
19944            int num = mUserLru.size();
19945            int i = 0;
19946            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19947                Integer oldUserId = mUserLru.get(i);
19948                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19949                if (oldUss == null) {
19950                    // Shouldn't happen, but be sane if it does.
19951                    mUserLru.remove(i);
19952                    num--;
19953                    continue;
19954                }
19955                if (oldUss.mState == UserStartedState.STATE_STOPPING
19956                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19957                    // This user is already stopping, doesn't count.
19958                    num--;
19959                    i++;
19960                    continue;
19961                }
19962                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19963                    // Owner and current can't be stopped, but count as running.
19964                    i++;
19965                    continue;
19966                }
19967                // This is a user to be stopped.
19968                stopUserLocked(oldUserId, null);
19969                num--;
19970                i++;
19971            }
19972        }
19973    }
19974
19975    @Override
19976    public int stopUser(final int userId, final IStopUserCallback callback) {
19977        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19978                != PackageManager.PERMISSION_GRANTED) {
19979            String msg = "Permission Denial: switchUser() from pid="
19980                    + Binder.getCallingPid()
19981                    + ", uid=" + Binder.getCallingUid()
19982                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19983            Slog.w(TAG, msg);
19984            throw new SecurityException(msg);
19985        }
19986        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19987            throw new IllegalArgumentException("Can't stop primary user " + userId);
19988        }
19989        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19990        synchronized (this) {
19991            return stopUserLocked(userId, callback);
19992        }
19993    }
19994
19995    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19996        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19997        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19998            return ActivityManager.USER_OP_IS_CURRENT;
19999        }
20000
20001        final UserStartedState uss = mStartedUsers.get(userId);
20002        if (uss == null) {
20003            // User is not started, nothing to do...  but we do need to
20004            // callback if requested.
20005            if (callback != null) {
20006                mHandler.post(new Runnable() {
20007                    @Override
20008                    public void run() {
20009                        try {
20010                            callback.userStopped(userId);
20011                        } catch (RemoteException e) {
20012                        }
20013                    }
20014                });
20015            }
20016            return ActivityManager.USER_OP_SUCCESS;
20017        }
20018
20019        if (callback != null) {
20020            uss.mStopCallbacks.add(callback);
20021        }
20022
20023        if (uss.mState != UserStartedState.STATE_STOPPING
20024                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20025            uss.mState = UserStartedState.STATE_STOPPING;
20026            updateStartedUserArrayLocked();
20027
20028            long ident = Binder.clearCallingIdentity();
20029            try {
20030                // We are going to broadcast ACTION_USER_STOPPING and then
20031                // once that is done send a final ACTION_SHUTDOWN and then
20032                // stop the user.
20033                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20034                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20035                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20036                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20037                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20038                // This is the result receiver for the final shutdown broadcast.
20039                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20040                    @Override
20041                    public void performReceive(Intent intent, int resultCode, String data,
20042                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20043                        finishUserStop(uss);
20044                    }
20045                };
20046                // This is the result receiver for the initial stopping broadcast.
20047                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20048                    @Override
20049                    public void performReceive(Intent intent, int resultCode, String data,
20050                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20051                        // On to the next.
20052                        synchronized (ActivityManagerService.this) {
20053                            if (uss.mState != UserStartedState.STATE_STOPPING) {
20054                                // Whoops, we are being started back up.  Abort, abort!
20055                                return;
20056                            }
20057                            uss.mState = UserStartedState.STATE_SHUTDOWN;
20058                        }
20059                        mBatteryStatsService.noteEvent(
20060                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20061                                Integer.toString(userId), userId);
20062                        mSystemServiceManager.stopUser(userId);
20063                        broadcastIntentLocked(null, null, shutdownIntent,
20064                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20065                                true, false, MY_PID, Process.SYSTEM_UID, userId);
20066                    }
20067                };
20068                // Kick things off.
20069                broadcastIntentLocked(null, null, stoppingIntent,
20070                        null, stoppingReceiver, 0, null, null,
20071                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20072                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20073            } finally {
20074                Binder.restoreCallingIdentity(ident);
20075            }
20076        }
20077
20078        return ActivityManager.USER_OP_SUCCESS;
20079    }
20080
20081    void finishUserStop(UserStartedState uss) {
20082        final int userId = uss.mHandle.getIdentifier();
20083        boolean stopped;
20084        ArrayList<IStopUserCallback> callbacks;
20085        synchronized (this) {
20086            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20087            if (mStartedUsers.get(userId) != uss) {
20088                stopped = false;
20089            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
20090                stopped = false;
20091            } else {
20092                stopped = true;
20093                // User can no longer run.
20094                mStartedUsers.remove(userId);
20095                mUserLru.remove(Integer.valueOf(userId));
20096                updateStartedUserArrayLocked();
20097
20098                // Clean up all state and processes associated with the user.
20099                // Kill all the processes for the user.
20100                forceStopUserLocked(userId, "finish user");
20101            }
20102
20103            // Explicitly remove the old information in mRecentTasks.
20104            mRecentTasks.removeTasksForUserLocked(userId);
20105        }
20106
20107        for (int i=0; i<callbacks.size(); i++) {
20108            try {
20109                if (stopped) callbacks.get(i).userStopped(userId);
20110                else callbacks.get(i).userStopAborted(userId);
20111            } catch (RemoteException e) {
20112            }
20113        }
20114
20115        if (stopped) {
20116            mSystemServiceManager.cleanupUser(userId);
20117            synchronized (this) {
20118                mStackSupervisor.removeUserLocked(userId);
20119            }
20120        }
20121    }
20122
20123    @Override
20124    public UserInfo getCurrentUser() {
20125        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20126                != PackageManager.PERMISSION_GRANTED) && (
20127                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20128                != PackageManager.PERMISSION_GRANTED)) {
20129            String msg = "Permission Denial: getCurrentUser() from pid="
20130                    + Binder.getCallingPid()
20131                    + ", uid=" + Binder.getCallingUid()
20132                    + " requires " + INTERACT_ACROSS_USERS;
20133            Slog.w(TAG, msg);
20134            throw new SecurityException(msg);
20135        }
20136        synchronized (this) {
20137            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20138            return getUserManagerLocked().getUserInfo(userId);
20139        }
20140    }
20141
20142    int getCurrentUserIdLocked() {
20143        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20144    }
20145
20146    @Override
20147    public boolean isUserRunning(int userId, boolean orStopped) {
20148        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20149                != PackageManager.PERMISSION_GRANTED) {
20150            String msg = "Permission Denial: isUserRunning() from pid="
20151                    + Binder.getCallingPid()
20152                    + ", uid=" + Binder.getCallingUid()
20153                    + " requires " + INTERACT_ACROSS_USERS;
20154            Slog.w(TAG, msg);
20155            throw new SecurityException(msg);
20156        }
20157        synchronized (this) {
20158            return isUserRunningLocked(userId, orStopped);
20159        }
20160    }
20161
20162    boolean isUserRunningLocked(int userId, boolean orStopped) {
20163        UserStartedState state = mStartedUsers.get(userId);
20164        if (state == null) {
20165            return false;
20166        }
20167        if (orStopped) {
20168            return true;
20169        }
20170        return state.mState != UserStartedState.STATE_STOPPING
20171                && state.mState != UserStartedState.STATE_SHUTDOWN;
20172    }
20173
20174    @Override
20175    public int[] getRunningUserIds() {
20176        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20177                != PackageManager.PERMISSION_GRANTED) {
20178            String msg = "Permission Denial: isUserRunning() from pid="
20179                    + Binder.getCallingPid()
20180                    + ", uid=" + Binder.getCallingUid()
20181                    + " requires " + INTERACT_ACROSS_USERS;
20182            Slog.w(TAG, msg);
20183            throw new SecurityException(msg);
20184        }
20185        synchronized (this) {
20186            return mStartedUserArray;
20187        }
20188    }
20189
20190    private void updateStartedUserArrayLocked() {
20191        int num = 0;
20192        for (int i=0; i<mStartedUsers.size();  i++) {
20193            UserStartedState uss = mStartedUsers.valueAt(i);
20194            // This list does not include stopping users.
20195            if (uss.mState != UserStartedState.STATE_STOPPING
20196                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20197                num++;
20198            }
20199        }
20200        mStartedUserArray = new int[num];
20201        num = 0;
20202        for (int i=0; i<mStartedUsers.size();  i++) {
20203            UserStartedState uss = mStartedUsers.valueAt(i);
20204            if (uss.mState != UserStartedState.STATE_STOPPING
20205                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20206                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20207                num++;
20208            }
20209        }
20210    }
20211
20212    @Override
20213    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20214        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20215                != PackageManager.PERMISSION_GRANTED) {
20216            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20217                    + Binder.getCallingPid()
20218                    + ", uid=" + Binder.getCallingUid()
20219                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20220            Slog.w(TAG, msg);
20221            throw new SecurityException(msg);
20222        }
20223
20224        mUserSwitchObservers.register(observer);
20225    }
20226
20227    @Override
20228    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20229        mUserSwitchObservers.unregister(observer);
20230    }
20231
20232    int[] getUsersLocked() {
20233        UserManagerService ums = getUserManagerLocked();
20234        return ums != null ? ums.getUserIds() : new int[] { 0 };
20235    }
20236
20237    UserManagerService getUserManagerLocked() {
20238        if (mUserManager == null) {
20239            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20240            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20241        }
20242        return mUserManager;
20243    }
20244
20245    private int applyUserId(int uid, int userId) {
20246        return UserHandle.getUid(userId, uid);
20247    }
20248
20249    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20250        if (info == null) return null;
20251        ApplicationInfo newInfo = new ApplicationInfo(info);
20252        newInfo.uid = applyUserId(info.uid, userId);
20253        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20254                userId).getAbsolutePath();
20255        return newInfo;
20256    }
20257
20258    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20259        if (aInfo == null
20260                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20261            return aInfo;
20262        }
20263
20264        ActivityInfo info = new ActivityInfo(aInfo);
20265        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20266        return info;
20267    }
20268
20269    private final class LocalService extends ActivityManagerInternal {
20270        @Override
20271        public void onWakefulnessChanged(int wakefulness) {
20272            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20273        }
20274
20275        @Override
20276        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20277                String processName, String abiOverride, int uid, Runnable crashHandler) {
20278            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20279                    processName, abiOverride, uid, crashHandler);
20280        }
20281
20282        @Override
20283        public SleepToken acquireSleepToken(String tag) {
20284            Preconditions.checkNotNull(tag);
20285
20286            synchronized (ActivityManagerService.this) {
20287                SleepTokenImpl token = new SleepTokenImpl(tag);
20288                mSleepTokens.add(token);
20289                updateSleepIfNeededLocked();
20290                return token;
20291            }
20292        }
20293
20294        @Override
20295        public ComponentName getHomeActivityForUser(int userId) {
20296            synchronized (ActivityManagerService.this) {
20297                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20298                return homeActivity == null ? null : homeActivity.realActivity;
20299            }
20300        }
20301    }
20302
20303    private final class SleepTokenImpl extends SleepToken {
20304        private final String mTag;
20305        private final long mAcquireTime;
20306
20307        public SleepTokenImpl(String tag) {
20308            mTag = tag;
20309            mAcquireTime = SystemClock.uptimeMillis();
20310        }
20311
20312        @Override
20313        public void release() {
20314            synchronized (ActivityManagerService.this) {
20315                if (mSleepTokens.remove(this)) {
20316                    updateSleepIfNeededLocked();
20317                }
20318            }
20319        }
20320
20321        @Override
20322        public String toString() {
20323            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20324        }
20325    }
20326
20327    /**
20328     * An implementation of IAppTask, that allows an app to manage its own tasks via
20329     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20330     * only the process that calls getAppTasks() can call the AppTask methods.
20331     */
20332    class AppTaskImpl extends IAppTask.Stub {
20333        private int mTaskId;
20334        private int mCallingUid;
20335
20336        public AppTaskImpl(int taskId, int callingUid) {
20337            mTaskId = taskId;
20338            mCallingUid = callingUid;
20339        }
20340
20341        private void checkCaller() {
20342            if (mCallingUid != Binder.getCallingUid()) {
20343                throw new SecurityException("Caller " + mCallingUid
20344                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20345            }
20346        }
20347
20348        @Override
20349        public void finishAndRemoveTask() {
20350            checkCaller();
20351
20352            synchronized (ActivityManagerService.this) {
20353                long origId = Binder.clearCallingIdentity();
20354                try {
20355                    if (!removeTaskByIdLocked(mTaskId, false)) {
20356                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20357                    }
20358                } finally {
20359                    Binder.restoreCallingIdentity(origId);
20360                }
20361            }
20362        }
20363
20364        @Override
20365        public ActivityManager.RecentTaskInfo getTaskInfo() {
20366            checkCaller();
20367
20368            synchronized (ActivityManagerService.this) {
20369                long origId = Binder.clearCallingIdentity();
20370                try {
20371                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20372                    if (tr == null) {
20373                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20374                    }
20375                    return createRecentTaskInfoFromTaskRecord(tr);
20376                } finally {
20377                    Binder.restoreCallingIdentity(origId);
20378                }
20379            }
20380        }
20381
20382        @Override
20383        public void moveToFront() {
20384            checkCaller();
20385            // Will bring task to front if it already has a root activity.
20386            startActivityFromRecentsInner(mTaskId, null);
20387        }
20388
20389        @Override
20390        public int startActivity(IBinder whoThread, String callingPackage,
20391                Intent intent, String resolvedType, Bundle options) {
20392            checkCaller();
20393
20394            int callingUser = UserHandle.getCallingUserId();
20395            TaskRecord tr;
20396            IApplicationThread appThread;
20397            synchronized (ActivityManagerService.this) {
20398                tr = mRecentTasks.taskForIdLocked(mTaskId);
20399                if (tr == null) {
20400                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20401                }
20402                appThread = ApplicationThreadNative.asInterface(whoThread);
20403                if (appThread == null) {
20404                    throw new IllegalArgumentException("Bad app thread " + appThread);
20405                }
20406            }
20407            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20408                    resolvedType, null, null, null, null, 0, 0, null, null,
20409                    null, options, callingUser, null, tr);
20410        }
20411
20412        @Override
20413        public void setExcludeFromRecents(boolean exclude) {
20414            checkCaller();
20415
20416            synchronized (ActivityManagerService.this) {
20417                long origId = Binder.clearCallingIdentity();
20418                try {
20419                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20420                    if (tr == null) {
20421                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20422                    }
20423                    Intent intent = tr.getBaseIntent();
20424                    if (exclude) {
20425                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20426                    } else {
20427                        intent.setFlags(intent.getFlags()
20428                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20429                    }
20430                } finally {
20431                    Binder.restoreCallingIdentity(origId);
20432                }
20433            }
20434        }
20435    }
20436}
20437