ActivityManagerService.java revision 09d57fe9b357495b7bc62be39a8befa00d9d7ffb
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_PINNABLE;
36import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37import static org.xmlpull.v1.XmlPullParser.START_TAG;
38
39import android.Manifest;
40import android.app.AppOpsManager;
41import android.app.ApplicationThreadNative;
42import android.app.AssistContent;
43import android.app.AssistStructure;
44import android.app.IActivityContainer;
45import android.app.IActivityContainerCallback;
46import android.app.IAppTask;
47import android.app.ITaskStackListener;
48import android.app.ProfilerInfo;
49import android.app.usage.UsageEvents;
50import android.app.usage.UsageStatsManagerInternal;
51import android.appwidget.AppWidgetManager;
52import android.content.pm.PermissionInfo;
53import android.content.res.Resources;
54import android.graphics.Bitmap;
55import android.graphics.Point;
56import android.graphics.Rect;
57import android.os.BatteryStats;
58import android.os.PersistableBundle;
59import android.os.PowerManager;
60import android.os.TransactionTooLargeException;
61import android.os.WorkSource;
62import android.os.storage.IMountService;
63import android.os.storage.StorageManager;
64import android.service.voice.IVoiceInteractionSession;
65import android.util.ArrayMap;
66import android.util.ArraySet;
67import android.util.DebugUtils;
68import android.util.SparseIntArray;
69import android.view.Display;
70
71import com.android.internal.R;
72import com.android.internal.annotations.GuardedBy;
73import com.android.internal.app.DumpHeapActivity;
74import com.android.internal.app.IAppOpsService;
75import com.android.internal.app.IVoiceInteractor;
76import com.android.internal.app.ProcessMap;
77import com.android.internal.app.ProcessStats;
78import com.android.internal.os.BackgroundThread;
79import com.android.internal.os.BatteryStatsImpl;
80import com.android.internal.os.IResultReceiver;
81import com.android.internal.os.ProcessCpuTracker;
82import com.android.internal.os.TransferPipe;
83import com.android.internal.os.Zygote;
84import com.android.internal.util.ArrayUtils;
85import com.android.internal.util.FastPrintWriter;
86import com.android.internal.util.FastXmlSerializer;
87import com.android.internal.util.MemInfoReader;
88import com.android.internal.util.Preconditions;
89import com.android.server.AppOpsService;
90import com.android.server.AttributeCache;
91import com.android.server.IntentResolver;
92import com.android.server.LocalServices;
93import com.android.server.ServiceThread;
94import com.android.server.SystemService;
95import com.android.server.SystemServiceManager;
96import com.android.server.Watchdog;
97import com.android.server.am.ActivityStack.ActivityState;
98import com.android.server.firewall.IntentFirewall;
99import com.android.server.pm.Installer;
100import com.android.server.pm.UserManagerService;
101import com.android.server.statusbar.StatusBarManagerInternal;
102import com.android.server.wm.AppTransition;
103import com.android.server.wm.WindowManagerService;
104import com.google.android.collect.Lists;
105import com.google.android.collect.Maps;
106
107import libcore.io.IoUtils;
108import libcore.util.EmptyArray;
109
110import org.xmlpull.v1.XmlPullParser;
111import org.xmlpull.v1.XmlPullParserException;
112import org.xmlpull.v1.XmlSerializer;
113
114import android.app.Activity;
115import android.app.ActivityManager;
116import android.app.ActivityManager.RunningTaskInfo;
117import android.app.ActivityManager.StackInfo;
118import android.app.ActivityManagerInternal;
119import android.app.ActivityManagerInternal.SleepToken;
120import android.app.ActivityManagerNative;
121import android.app.ActivityOptions;
122import android.app.ActivityThread;
123import android.app.AlertDialog;
124import android.app.AppGlobals;
125import android.app.ApplicationErrorReport;
126import android.app.Dialog;
127import android.app.IActivityController;
128import android.app.IApplicationThread;
129import android.app.IInstrumentationWatcher;
130import android.app.INotificationManager;
131import android.app.IProcessObserver;
132import android.app.IServiceConnection;
133import android.app.IStopUserCallback;
134import android.app.IUidObserver;
135import android.app.IUiAutomationConnection;
136import android.app.IUserSwitchObserver;
137import android.app.Instrumentation;
138import android.app.Notification;
139import android.app.NotificationManager;
140import android.app.PendingIntent;
141import android.app.backup.IBackupManager;
142import android.content.ActivityNotFoundException;
143import android.content.BroadcastReceiver;
144import android.content.ClipData;
145import android.content.ComponentCallbacks2;
146import android.content.ComponentName;
147import android.content.ContentProvider;
148import android.content.ContentResolver;
149import android.content.Context;
150import android.content.DialogInterface;
151import android.content.IContentProvider;
152import android.content.IIntentReceiver;
153import android.content.IIntentSender;
154import android.content.Intent;
155import android.content.IntentFilter;
156import android.content.IntentSender;
157import android.content.pm.ActivityInfo;
158import android.content.pm.ApplicationInfo;
159import android.content.pm.ConfigurationInfo;
160import android.content.pm.IPackageDataObserver;
161import android.content.pm.IPackageManager;
162import android.content.pm.InstrumentationInfo;
163import android.content.pm.PackageInfo;
164import android.content.pm.PackageManager;
165import android.content.pm.ParceledListSlice;
166import android.content.pm.UserInfo;
167import android.content.pm.PackageManager.NameNotFoundException;
168import android.content.pm.PathPermission;
169import android.content.pm.ProviderInfo;
170import android.content.pm.ResolveInfo;
171import android.content.pm.ServiceInfo;
172import android.content.res.CompatibilityInfo;
173import android.content.res.Configuration;
174import android.net.Proxy;
175import android.net.ProxyInfo;
176import android.net.Uri;
177import android.os.Binder;
178import android.os.Build;
179import android.os.Bundle;
180import android.os.Debug;
181import android.os.DropBoxManager;
182import android.os.Environment;
183import android.os.FactoryTest;
184import android.os.FileObserver;
185import android.os.FileUtils;
186import android.os.Handler;
187import android.os.IBinder;
188import android.os.IPermissionController;
189import android.os.IProcessInfoService;
190import android.os.IRemoteCallback;
191import android.os.IUserManager;
192import android.os.Looper;
193import android.os.Message;
194import android.os.Parcel;
195import android.os.ParcelFileDescriptor;
196import android.os.PowerManagerInternal;
197import android.os.Process;
198import android.os.RemoteCallbackList;
199import android.os.RemoteException;
200import android.os.SELinux;
201import android.os.ServiceManager;
202import android.os.StrictMode;
203import android.os.SystemClock;
204import android.os.SystemProperties;
205import android.os.UpdateLock;
206import android.os.UserHandle;
207import android.os.UserManager;
208import android.provider.Settings;
209import android.text.format.DateUtils;
210import android.text.format.Time;
211import android.util.AtomicFile;
212import android.util.EventLog;
213import android.util.Log;
214import android.util.Pair;
215import android.util.PrintWriterPrinter;
216import android.util.Slog;
217import android.util.SparseArray;
218import android.util.TimeUtils;
219import android.util.Xml;
220import android.view.Gravity;
221import android.view.LayoutInflater;
222import android.view.View;
223import android.view.WindowManager;
224
225import dalvik.system.VMRuntime;
226
227import java.io.BufferedInputStream;
228import java.io.BufferedOutputStream;
229import java.io.DataInputStream;
230import java.io.DataOutputStream;
231import java.io.File;
232import java.io.FileDescriptor;
233import java.io.FileInputStream;
234import java.io.FileNotFoundException;
235import java.io.FileOutputStream;
236import java.io.IOException;
237import java.io.InputStreamReader;
238import java.io.PrintWriter;
239import java.io.StringWriter;
240import java.lang.ref.WeakReference;
241import java.nio.charset.StandardCharsets;
242import java.util.ArrayList;
243import java.util.Arrays;
244import java.util.Collections;
245import java.util.Comparator;
246import java.util.HashMap;
247import java.util.HashSet;
248import java.util.Iterator;
249import java.util.List;
250import java.util.Locale;
251import java.util.Map;
252import java.util.Set;
253import java.util.concurrent.atomic.AtomicBoolean;
254import java.util.concurrent.atomic.AtomicLong;
255
256public final class ActivityManagerService extends ActivityManagerNative
257        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
258
259    // File that stores last updated system version and called preboot receivers
260    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
261
262    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
263    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
264    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
265    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
266    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
267    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
268    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
269    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
270    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
271    private static final String TAG_LRU = TAG + POSTFIX_LRU;
272    private static final String TAG_MU = TAG + POSTFIX_MU;
273    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
274    private static final String TAG_POWER = TAG + POSTFIX_POWER;
275    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
276    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
277    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
278    private static final String TAG_PSS = TAG + POSTFIX_PSS;
279    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
280    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
281    private static final String TAG_STACK = TAG + POSTFIX_STACK;
282    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
283    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
284    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
285    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
286
287    /** Control over CPU and battery monitoring */
288    // write battery stats every 30 minutes.
289    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
290    static final boolean MONITOR_CPU_USAGE = true;
291    // don't sample cpu less than every 5 seconds.
292    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
293    // wait possibly forever for next cpu sample.
294    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
295    static final boolean MONITOR_THREAD_CPU_USAGE = false;
296
297    // The flags that are set for all calls we make to the package manager.
298    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
299
300    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
301
302    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
303
304    // Amount of time after a call to stopAppSwitches() during which we will
305    // prevent further untrusted switches from happening.
306    static final long APP_SWITCH_DELAY_TIME = 5*1000;
307
308    // How long we wait for a launched process to attach to the activity manager
309    // before we decide it's never going to come up for real.
310    static final int PROC_START_TIMEOUT = 10*1000;
311
312    // How long we wait for a launched process to attach to the activity manager
313    // before we decide it's never going to come up for real, when the process was
314    // started with a wrapper for instrumentation (such as Valgrind) because it
315    // could take much longer than usual.
316    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
317
318    // How long to wait after going idle before forcing apps to GC.
319    static final int GC_TIMEOUT = 5*1000;
320
321    // The minimum amount of time between successive GC requests for a process.
322    static final int GC_MIN_INTERVAL = 60*1000;
323
324    // The minimum amount of time between successive PSS requests for a process.
325    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
326
327    // The minimum amount of time between successive PSS requests for a process
328    // when the request is due to the memory state being lowered.
329    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
330
331    // The rate at which we check for apps using excessive power -- 15 mins.
332    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
333
334    // The minimum sample duration we will allow before deciding we have
335    // enough data on wake locks to start killing things.
336    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
337
338    // The minimum sample duration we will allow before deciding we have
339    // enough data on CPU usage to start killing things.
340    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
341
342    // How long we allow a receiver to run before giving up on it.
343    static final int BROADCAST_FG_TIMEOUT = 10*1000;
344    static final int BROADCAST_BG_TIMEOUT = 60*1000;
345
346    // How long we wait until we timeout on key dispatching.
347    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
348
349    // How long we wait until we timeout on key dispatching during instrumentation.
350    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
351
352    // Amount of time we wait for observers to handle a user switch before
353    // giving up on them and unfreezing the screen.
354    static final int USER_SWITCH_TIMEOUT = 2*1000;
355
356    // Maximum number of users we allow to be running at a time.
357    static final int MAX_RUNNING_USERS = 3;
358
359    // How long to wait in getAssistContextExtras for the activity and foreground services
360    // to respond with the result.
361    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
362
363    // How long top wait when going through the modern assist (which doesn't need to block
364    // on getting this result before starting to launch its UI).
365    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
366
367    // Maximum number of persisted Uri grants a package is allowed
368    static final int MAX_PERSISTED_URI_GRANTS = 128;
369
370    static final int MY_PID = Process.myPid();
371
372    static final String[] EMPTY_STRING_ARRAY = new String[0];
373
374    // How many bytes to write into the dropbox log before truncating
375    static final int DROPBOX_MAX_SIZE = 256 * 1024;
376
377    // Access modes for handleIncomingUser.
378    static final int ALLOW_NON_FULL = 0;
379    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
380    static final int ALLOW_FULL_ONLY = 2;
381
382    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
383
384    // Delay in notifying task stack change listeners (in millis)
385    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
386
387    // Necessary ApplicationInfo flags to mark an app as persistent
388    private static final int PERSISTENT_MASK =
389            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
390
391    /** All system services */
392    SystemServiceManager mSystemServiceManager;
393
394    private Installer mInstaller;
395
396    /** Run all ActivityStacks through this */
397    ActivityStackSupervisor mStackSupervisor;
398
399    /** Task stack change listeners. */
400    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
401            new RemoteCallbackList<ITaskStackListener>();
402
403    public IntentFirewall mIntentFirewall;
404
405    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
406    // default actuion automatically.  Important for devices without direct input
407    // devices.
408    private boolean mShowDialogs = true;
409
410    BroadcastQueue mFgBroadcastQueue;
411    BroadcastQueue mBgBroadcastQueue;
412    // Convenient for easy iteration over the queues. Foreground is first
413    // so that dispatch of foreground broadcasts gets precedence.
414    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
415
416    BroadcastQueue broadcastQueueForIntent(Intent intent) {
417        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
418        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
419                "Broadcast intent " + intent + " on "
420                + (isFg ? "foreground" : "background") + " queue");
421        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
422    }
423
424    /**
425     * Activity we have told the window manager to have key focus.
426     */
427    ActivityRecord mFocusedActivity = null;
428
429    /**
430     * User id of the last activity mFocusedActivity was set to.
431     */
432    private int mLastFocusedUserId;
433
434    /**
435     * If non-null, we are tracking the time the user spends in the currently focused app.
436     */
437    private AppTimeTracker mCurAppTimeTracker;
438
439    /**
440     * List of intents that were used to start the most recent tasks.
441     */
442    private final RecentTasks mRecentTasks;
443
444    /**
445     * For addAppTask: cached of the last activity component that was added.
446     */
447    ComponentName mLastAddedTaskComponent;
448
449    /**
450     * For addAppTask: cached of the last activity uid that was added.
451     */
452    int mLastAddedTaskUid;
453
454    /**
455     * For addAppTask: cached of the last ActivityInfo that was added.
456     */
457    ActivityInfo mLastAddedTaskActivity;
458
459    /**
460     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
461     */
462    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
463
464    /**
465     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
466     */
467    String mDeviceOwnerName;
468
469    /**
470     * Preferred activities to start on boot/user switch, as set by DevicePolicyManager. Indexed
471     * by userId.
472     */
473    SparseArray<ComponentName> mPreferredSetupActivities = new SparseArray<>();
474
475    public class PendingAssistExtras extends Binder implements Runnable {
476        public final ActivityRecord activity;
477        public final Bundle extras;
478        public final Intent intent;
479        public final String hint;
480        public final IResultReceiver receiver;
481        public final int userHandle;
482        public boolean haveResult = false;
483        public Bundle result = null;
484        public AssistStructure structure = null;
485        public AssistContent content = null;
486        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
487                String _hint, IResultReceiver _receiver, int _userHandle) {
488            activity = _activity;
489            extras = _extras;
490            intent = _intent;
491            hint = _hint;
492            receiver = _receiver;
493            userHandle = _userHandle;
494        }
495        @Override
496        public void run() {
497            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
498            synchronized (ActivityManagerService.this) {
499                synchronized (this) {
500                    haveResult = true;
501                    notifyAll();
502                }
503                pendingAssistExtrasTimedOutLocked(this);
504            }
505        }
506    }
507
508    final ArrayList<PendingAssistExtras> mPendingAssistExtras
509            = new ArrayList<PendingAssistExtras>();
510
511    /**
512     * Process management.
513     */
514    final ProcessList mProcessList = new ProcessList();
515
516    /**
517     * All of the applications we currently have running organized by name.
518     * The keys are strings of the application package name (as
519     * returned by the package manager), and the keys are ApplicationRecord
520     * objects.
521     */
522    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
523
524    /**
525     * Tracking long-term execution of processes to look for abuse and other
526     * bad app behavior.
527     */
528    final ProcessStatsService mProcessStats;
529
530    /**
531     * The currently running isolated processes.
532     */
533    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
534
535    /**
536     * Counter for assigning isolated process uids, to avoid frequently reusing the
537     * same ones.
538     */
539    int mNextIsolatedProcessUid = 0;
540
541    /**
542     * The currently running heavy-weight process, if any.
543     */
544    ProcessRecord mHeavyWeightProcess = null;
545
546    /**
547     * The last time that various processes have crashed.
548     */
549    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
550
551    /**
552     * Information about a process that is currently marked as bad.
553     */
554    static final class BadProcessInfo {
555        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
556            this.time = time;
557            this.shortMsg = shortMsg;
558            this.longMsg = longMsg;
559            this.stack = stack;
560        }
561
562        final long time;
563        final String shortMsg;
564        final String longMsg;
565        final String stack;
566    }
567
568    /**
569     * Set of applications that we consider to be bad, and will reject
570     * incoming broadcasts from (which the user has no control over).
571     * Processes are added to this set when they have crashed twice within
572     * a minimum amount of time; they are removed from it when they are
573     * later restarted (hopefully due to some user action).  The value is the
574     * time it was added to the list.
575     */
576    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
577
578    /**
579     * All of the processes we currently have running organized by pid.
580     * The keys are the pid running the application.
581     *
582     * <p>NOTE: This object is protected by its own lock, NOT the global
583     * activity manager lock!
584     */
585    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
586
587    /**
588     * All of the processes that have been forced to be foreground.  The key
589     * is the pid of the caller who requested it (we hold a death
590     * link on it).
591     */
592    abstract class ForegroundToken implements IBinder.DeathRecipient {
593        int pid;
594        IBinder token;
595    }
596    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
597
598    /**
599     * List of records for processes that someone had tried to start before the
600     * system was ready.  We don't start them at that point, but ensure they
601     * are started by the time booting is complete.
602     */
603    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
604
605    /**
606     * List of persistent applications that are in the process
607     * of being started.
608     */
609    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
610
611    /**
612     * Processes that are being forcibly torn down.
613     */
614    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
615
616    /**
617     * List of running applications, sorted by recent usage.
618     * The first entry in the list is the least recently used.
619     */
620    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
621
622    /**
623     * Where in mLruProcesses that the processes hosting activities start.
624     */
625    int mLruProcessActivityStart = 0;
626
627    /**
628     * Where in mLruProcesses that the processes hosting services start.
629     * This is after (lower index) than mLruProcessesActivityStart.
630     */
631    int mLruProcessServiceStart = 0;
632
633    /**
634     * List of processes that should gc as soon as things are idle.
635     */
636    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
637
638    /**
639     * Processes we want to collect PSS data from.
640     */
641    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
642
643    /**
644     * Last time we requested PSS data of all processes.
645     */
646    long mLastFullPssTime = SystemClock.uptimeMillis();
647
648    /**
649     * If set, the next time we collect PSS data we should do a full collection
650     * with data from native processes and the kernel.
651     */
652    boolean mFullPssPending = false;
653
654    /**
655     * This is the process holding what we currently consider to be
656     * the "home" activity.
657     */
658    ProcessRecord mHomeProcess;
659
660    /**
661     * This is the process holding the activity the user last visited that
662     * is in a different process from the one they are currently in.
663     */
664    ProcessRecord mPreviousProcess;
665
666    /**
667     * The time at which the previous process was last visible.
668     */
669    long mPreviousProcessVisibleTime;
670
671    /**
672     * Track all uids that have actively running processes.
673     */
674    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
675
676    /**
677     * Which uses have been started, so are allowed to run code.
678     */
679    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
680
681    /**
682     * LRU list of history of current users.  Most recently current is at the end.
683     */
684    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
685
686    /**
687     * Constant array of the users that are currently started.
688     */
689    int[] mStartedUserArray = new int[] { 0 };
690
691    /**
692     * Registered observers of the user switching mechanics.
693     */
694    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
695            = new RemoteCallbackList<IUserSwitchObserver>();
696
697    /**
698     * Currently active user switch.
699     */
700    Object mCurUserSwitchCallback;
701
702    /**
703     * Packages that the user has asked to have run in screen size
704     * compatibility mode instead of filling the screen.
705     */
706    final CompatModePackages mCompatModePackages;
707
708    /**
709     * Set of IntentSenderRecord objects that are currently active.
710     */
711    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
712            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
713
714    /**
715     * Fingerprints (hashCode()) of stack traces that we've
716     * already logged DropBox entries for.  Guarded by itself.  If
717     * something (rogue user app) forces this over
718     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
719     */
720    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
721    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
722
723    /**
724     * Strict Mode background batched logging state.
725     *
726     * The string buffer is guarded by itself, and its lock is also
727     * used to determine if another batched write is already
728     * in-flight.
729     */
730    private final StringBuilder mStrictModeBuffer = new StringBuilder();
731
732    /**
733     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
734     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
735     */
736    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
737
738    /**
739     * Resolver for broadcast intents to registered receivers.
740     * Holds BroadcastFilter (subclass of IntentFilter).
741     */
742    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
743            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
744        @Override
745        protected boolean allowFilterResult(
746                BroadcastFilter filter, List<BroadcastFilter> dest) {
747            IBinder target = filter.receiverList.receiver.asBinder();
748            for (int i = dest.size() - 1; i >= 0; i--) {
749                if (dest.get(i).receiverList.receiver.asBinder() == target) {
750                    return false;
751                }
752            }
753            return true;
754        }
755
756        @Override
757        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
758            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
759                    || userId == filter.owningUserId) {
760                return super.newResult(filter, match, userId);
761            }
762            return null;
763        }
764
765        @Override
766        protected BroadcastFilter[] newArray(int size) {
767            return new BroadcastFilter[size];
768        }
769
770        @Override
771        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
772            return packageName.equals(filter.packageName);
773        }
774    };
775
776    /**
777     * State of all active sticky broadcasts per user.  Keys are the action of the
778     * sticky Intent, values are an ArrayList of all broadcasted intents with
779     * that action (which should usually be one).  The SparseArray is keyed
780     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
781     * for stickies that are sent to all users.
782     */
783    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
784            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
785
786    final ActiveServices mServices;
787
788    final static class Association {
789        final int mSourceUid;
790        final String mSourceProcess;
791        final int mTargetUid;
792        final ComponentName mTargetComponent;
793        final String mTargetProcess;
794
795        int mCount;
796        long mTime;
797
798        int mNesting;
799        long mStartTime;
800
801        Association(int sourceUid, String sourceProcess, int targetUid,
802                ComponentName targetComponent, String targetProcess) {
803            mSourceUid = sourceUid;
804            mSourceProcess = sourceProcess;
805            mTargetUid = targetUid;
806            mTargetComponent = targetComponent;
807            mTargetProcess = targetProcess;
808        }
809    }
810
811    /**
812     * When service association tracking is enabled, this is all of the associations we
813     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
814     * -> association data.
815     */
816    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
817            mAssociations = new SparseArray<>();
818    boolean mTrackingAssociations;
819
820    /**
821     * Backup/restore process management
822     */
823    String mBackupAppName = null;
824    BackupRecord mBackupTarget = null;
825
826    final ProviderMap mProviderMap;
827
828    /**
829     * List of content providers who have clients waiting for them.  The
830     * application is currently being launched and the provider will be
831     * removed from this list once it is published.
832     */
833    final ArrayList<ContentProviderRecord> mLaunchingProviders
834            = new ArrayList<ContentProviderRecord>();
835
836    /**
837     * File storing persisted {@link #mGrantedUriPermissions}.
838     */
839    private final AtomicFile mGrantFile;
840
841    /** XML constants used in {@link #mGrantFile} */
842    private static final String TAG_URI_GRANTS = "uri-grants";
843    private static final String TAG_URI_GRANT = "uri-grant";
844    private static final String ATTR_USER_HANDLE = "userHandle";
845    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
846    private static final String ATTR_TARGET_USER_ID = "targetUserId";
847    private static final String ATTR_SOURCE_PKG = "sourcePkg";
848    private static final String ATTR_TARGET_PKG = "targetPkg";
849    private static final String ATTR_URI = "uri";
850    private static final String ATTR_MODE_FLAGS = "modeFlags";
851    private static final String ATTR_CREATED_TIME = "createdTime";
852    private static final String ATTR_PREFIX = "prefix";
853
854    /**
855     * Global set of specific {@link Uri} permissions that have been granted.
856     * This optimized lookup structure maps from {@link UriPermission#targetUid}
857     * to {@link UriPermission#uri} to {@link UriPermission}.
858     */
859    @GuardedBy("this")
860    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
861            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
862
863    public static class GrantUri {
864        public final int sourceUserId;
865        public final Uri uri;
866        public boolean prefix;
867
868        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
869            this.sourceUserId = sourceUserId;
870            this.uri = uri;
871            this.prefix = prefix;
872        }
873
874        @Override
875        public int hashCode() {
876            int hashCode = 1;
877            hashCode = 31 * hashCode + sourceUserId;
878            hashCode = 31 * hashCode + uri.hashCode();
879            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
880            return hashCode;
881        }
882
883        @Override
884        public boolean equals(Object o) {
885            if (o instanceof GrantUri) {
886                GrantUri other = (GrantUri) o;
887                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
888                        && prefix == other.prefix;
889            }
890            return false;
891        }
892
893        @Override
894        public String toString() {
895            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
896            if (prefix) result += " [prefix]";
897            return result;
898        }
899
900        public String toSafeString() {
901            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
902            if (prefix) result += " [prefix]";
903            return result;
904        }
905
906        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
907            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
908                    ContentProvider.getUriWithoutUserId(uri), false);
909        }
910    }
911
912    CoreSettingsObserver mCoreSettingsObserver;
913
914    /**
915     * Thread-local storage used to carry caller permissions over through
916     * indirect content-provider access.
917     */
918    private class Identity {
919        public final IBinder token;
920        public final int pid;
921        public final int uid;
922
923        Identity(IBinder _token, int _pid, int _uid) {
924            token = _token;
925            pid = _pid;
926            uid = _uid;
927        }
928    }
929
930    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
931
932    /**
933     * All information we have collected about the runtime performance of
934     * any user id that can impact battery performance.
935     */
936    final BatteryStatsService mBatteryStatsService;
937
938    /**
939     * Information about component usage
940     */
941    UsageStatsManagerInternal mUsageStatsService;
942
943    /**
944     * Information about and control over application operations
945     */
946    final AppOpsService mAppOpsService;
947
948    /**
949     * Save recent tasks information across reboots.
950     */
951    final TaskPersister mTaskPersister;
952
953    /**
954     * Current configuration information.  HistoryRecord objects are given
955     * a reference to this object to indicate which configuration they are
956     * currently running in, so this object must be kept immutable.
957     */
958    Configuration mConfiguration = new Configuration();
959
960    /**
961     * Current sequencing integer of the configuration, for skipping old
962     * configurations.
963     */
964    int mConfigurationSeq = 0;
965
966    /**
967     * Hardware-reported OpenGLES version.
968     */
969    final int GL_ES_VERSION;
970
971    /**
972     * List of initialization arguments to pass to all processes when binding applications to them.
973     * For example, references to the commonly used services.
974     */
975    HashMap<String, IBinder> mAppBindArgs;
976
977    /**
978     * Temporary to avoid allocations.  Protected by main lock.
979     */
980    final StringBuilder mStringBuilder = new StringBuilder(256);
981
982    /**
983     * Used to control how we initialize the service.
984     */
985    ComponentName mTopComponent;
986    String mTopAction = Intent.ACTION_MAIN;
987    String mTopData;
988    boolean mProcessesReady = false;
989    boolean mSystemReady = false;
990    boolean mBooting = false;
991    boolean mCallFinishBooting = false;
992    boolean mBootAnimationComplete = false;
993    boolean mWaitingUpdate = false;
994    boolean mDidUpdate = false;
995    boolean mOnBattery = false;
996    boolean mLaunchWarningShown = false;
997
998    Context mContext;
999
1000    int mFactoryTest;
1001
1002    boolean mCheckedForSetup;
1003
1004    /**
1005     * The time at which we will allow normal application switches again,
1006     * after a call to {@link #stopAppSwitches()}.
1007     */
1008    long mAppSwitchesAllowedTime;
1009
1010    /**
1011     * This is set to true after the first switch after mAppSwitchesAllowedTime
1012     * is set; any switches after that will clear the time.
1013     */
1014    boolean mDidAppSwitch;
1015
1016    /**
1017     * Last time (in realtime) at which we checked for power usage.
1018     */
1019    long mLastPowerCheckRealtime;
1020
1021    /**
1022     * Last time (in uptime) at which we checked for power usage.
1023     */
1024    long mLastPowerCheckUptime;
1025
1026    /**
1027     * Set while we are wanting to sleep, to prevent any
1028     * activities from being started/resumed.
1029     */
1030    private boolean mSleeping = false;
1031
1032    /**
1033     * The process state used for processes that are running the top activities.
1034     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1035     */
1036    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1037
1038    /**
1039     * Set while we are running a voice interaction.  This overrides
1040     * sleeping while it is active.
1041     */
1042    private IVoiceInteractionSession mRunningVoice;
1043
1044    /**
1045     * For some direct access we need to power manager.
1046     */
1047    PowerManagerInternal mLocalPowerManager;
1048
1049    /**
1050     * We want to hold a wake lock while running a voice interaction session, since
1051     * this may happen with the screen off and we need to keep the CPU running to
1052     * be able to continue to interact with the user.
1053     */
1054    PowerManager.WakeLock mVoiceWakeLock;
1055
1056    /**
1057     * State of external calls telling us if the device is awake or asleep.
1058     */
1059    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1060
1061    /**
1062     * A list of tokens that cause the top activity to be put to sleep.
1063     * They are used by components that may hide and block interaction with underlying
1064     * activities.
1065     */
1066    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1067
1068    static final int LOCK_SCREEN_HIDDEN = 0;
1069    static final int LOCK_SCREEN_LEAVING = 1;
1070    static final int LOCK_SCREEN_SHOWN = 2;
1071    /**
1072     * State of external call telling us if the lock screen is shown.
1073     */
1074    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1075
1076    /**
1077     * Set if we are shutting down the system, similar to sleeping.
1078     */
1079    boolean mShuttingDown = false;
1080
1081    /**
1082     * Current sequence id for oom_adj computation traversal.
1083     */
1084    int mAdjSeq = 0;
1085
1086    /**
1087     * Current sequence id for process LRU updating.
1088     */
1089    int mLruSeq = 0;
1090
1091    /**
1092     * Keep track of the non-cached/empty process we last found, to help
1093     * determine how to distribute cached/empty processes next time.
1094     */
1095    int mNumNonCachedProcs = 0;
1096
1097    /**
1098     * Keep track of the number of cached hidden procs, to balance oom adj
1099     * distribution between those and empty procs.
1100     */
1101    int mNumCachedHiddenProcs = 0;
1102
1103    /**
1104     * Keep track of the number of service processes we last found, to
1105     * determine on the next iteration which should be B services.
1106     */
1107    int mNumServiceProcs = 0;
1108    int mNewNumAServiceProcs = 0;
1109    int mNewNumServiceProcs = 0;
1110
1111    /**
1112     * Allow the current computed overall memory level of the system to go down?
1113     * This is set to false when we are killing processes for reasons other than
1114     * memory management, so that the now smaller process list will not be taken as
1115     * an indication that memory is tighter.
1116     */
1117    boolean mAllowLowerMemLevel = false;
1118
1119    /**
1120     * The last computed memory level, for holding when we are in a state that
1121     * processes are going away for other reasons.
1122     */
1123    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1124
1125    /**
1126     * The last total number of process we have, to determine if changes actually look
1127     * like a shrinking number of process due to lower RAM.
1128     */
1129    int mLastNumProcesses;
1130
1131    /**
1132     * The uptime of the last time we performed idle maintenance.
1133     */
1134    long mLastIdleTime = SystemClock.uptimeMillis();
1135
1136    /**
1137     * Total time spent with RAM that has been added in the past since the last idle time.
1138     */
1139    long mLowRamTimeSinceLastIdle = 0;
1140
1141    /**
1142     * If RAM is currently low, when that horrible situation started.
1143     */
1144    long mLowRamStartTime = 0;
1145
1146    /**
1147     * For reporting to battery stats the current top application.
1148     */
1149    private String mCurResumedPackage = null;
1150    private int mCurResumedUid = -1;
1151
1152    /**
1153     * For reporting to battery stats the apps currently running foreground
1154     * service.  The ProcessMap is package/uid tuples; each of these contain
1155     * an array of the currently foreground processes.
1156     */
1157    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1158            = new ProcessMap<ArrayList<ProcessRecord>>();
1159
1160    /**
1161     * This is set if we had to do a delayed dexopt of an app before launching
1162     * it, to increase the ANR timeouts in that case.
1163     */
1164    boolean mDidDexOpt;
1165
1166    /**
1167     * Set if the systemServer made a call to enterSafeMode.
1168     */
1169    boolean mSafeMode;
1170
1171    /**
1172     * If true, we are running under a test environment so will sample PSS from processes
1173     * much more rapidly to try to collect better data when the tests are rapidly
1174     * running through apps.
1175     */
1176    boolean mTestPssMode = false;
1177
1178    String mDebugApp = null;
1179    boolean mWaitForDebugger = false;
1180    boolean mDebugTransient = false;
1181    String mOrigDebugApp = null;
1182    boolean mOrigWaitForDebugger = false;
1183    boolean mAlwaysFinishActivities = false;
1184    IActivityController mController = null;
1185    String mProfileApp = null;
1186    ProcessRecord mProfileProc = null;
1187    String mProfileFile;
1188    ParcelFileDescriptor mProfileFd;
1189    int mSamplingInterval = 0;
1190    boolean mAutoStopProfiler = false;
1191    int mProfileType = 0;
1192    String mOpenGlTraceApp = null;
1193    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1194    String mMemWatchDumpProcName;
1195    String mMemWatchDumpFile;
1196    int mMemWatchDumpPid;
1197    int mMemWatchDumpUid;
1198
1199    final long[] mTmpLong = new long[1];
1200
1201    static final class ProcessChangeItem {
1202        static final int CHANGE_ACTIVITIES = 1<<0;
1203        static final int CHANGE_PROCESS_STATE = 1<<1;
1204        int changes;
1205        int uid;
1206        int pid;
1207        int processState;
1208        boolean foregroundActivities;
1209    }
1210
1211    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1212    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1213
1214    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1215    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1216
1217    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1218    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1219
1220    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1221    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1222
1223    /**
1224     * Runtime CPU use collection thread.  This object's lock is used to
1225     * perform synchronization with the thread (notifying it to run).
1226     */
1227    final Thread mProcessCpuThread;
1228
1229    /**
1230     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1231     * Must acquire this object's lock when accessing it.
1232     * NOTE: this lock will be held while doing long operations (trawling
1233     * through all processes in /proc), so it should never be acquired by
1234     * any critical paths such as when holding the main activity manager lock.
1235     */
1236    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1237            MONITOR_THREAD_CPU_USAGE);
1238    final AtomicLong mLastCpuTime = new AtomicLong(0);
1239    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1240
1241    long mLastWriteTime = 0;
1242
1243    /**
1244     * Used to retain an update lock when the foreground activity is in
1245     * immersive mode.
1246     */
1247    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1248
1249    /**
1250     * Set to true after the system has finished booting.
1251     */
1252    boolean mBooted = false;
1253
1254    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1255    int mProcessLimitOverride = -1;
1256
1257    WindowManagerService mWindowManager;
1258
1259    final ActivityThread mSystemThread;
1260
1261    // Holds the current foreground user's id
1262    int mCurrentUserId = 0;
1263    // Holds the target user's id during a user switch
1264    int mTargetUserId = UserHandle.USER_NULL;
1265    // If there are multiple profiles for the current user, their ids are here
1266    // Currently only the primary user can have managed profiles
1267    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1268
1269    /**
1270     * Mapping from each known user ID to the profile group ID it is associated with.
1271     */
1272    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1273
1274    private UserManagerService mUserManager;
1275
1276    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1277        final ProcessRecord mApp;
1278        final int mPid;
1279        final IApplicationThread mAppThread;
1280
1281        AppDeathRecipient(ProcessRecord app, int pid,
1282                IApplicationThread thread) {
1283            if (DEBUG_ALL) Slog.v(
1284                TAG, "New death recipient " + this
1285                + " for thread " + thread.asBinder());
1286            mApp = app;
1287            mPid = pid;
1288            mAppThread = thread;
1289        }
1290
1291        @Override
1292        public void binderDied() {
1293            if (DEBUG_ALL) Slog.v(
1294                TAG, "Death received in " + this
1295                + " for thread " + mAppThread.asBinder());
1296            synchronized(ActivityManagerService.this) {
1297                appDiedLocked(mApp, mPid, mAppThread, true);
1298            }
1299        }
1300    }
1301
1302    static final int SHOW_ERROR_MSG = 1;
1303    static final int SHOW_NOT_RESPONDING_MSG = 2;
1304    static final int SHOW_FACTORY_ERROR_MSG = 3;
1305    static final int UPDATE_CONFIGURATION_MSG = 4;
1306    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1307    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1308    static final int SERVICE_TIMEOUT_MSG = 12;
1309    static final int UPDATE_TIME_ZONE = 13;
1310    static final int SHOW_UID_ERROR_MSG = 14;
1311    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1312    static final int PROC_START_TIMEOUT_MSG = 20;
1313    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1314    static final int KILL_APPLICATION_MSG = 22;
1315    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1316    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1317    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1318    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1319    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1320    static final int CLEAR_DNS_CACHE_MSG = 28;
1321    static final int UPDATE_HTTP_PROXY_MSG = 29;
1322    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1323    static final int DISPATCH_PROCESSES_CHANGED = 31;
1324    static final int DISPATCH_PROCESS_DIED = 32;
1325    static final int REPORT_MEM_USAGE_MSG = 33;
1326    static final int REPORT_USER_SWITCH_MSG = 34;
1327    static final int CONTINUE_USER_SWITCH_MSG = 35;
1328    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1329    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1330    static final int PERSIST_URI_GRANTS_MSG = 38;
1331    static final int REQUEST_ALL_PSS_MSG = 39;
1332    static final int START_PROFILES_MSG = 40;
1333    static final int UPDATE_TIME = 41;
1334    static final int SYSTEM_USER_START_MSG = 42;
1335    static final int SYSTEM_USER_CURRENT_MSG = 43;
1336    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1337    static final int FINISH_BOOTING_MSG = 45;
1338    static final int START_USER_SWITCH_MSG = 46;
1339    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1340    static final int DISMISS_DIALOG_MSG = 48;
1341    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1342    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1343    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1344    static final int DELETE_DUMPHEAP_MSG = 52;
1345    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1346    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1347    static final int REPORT_TIME_TRACKER_MSG = 55;
1348
1349    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1350    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1351    static final int FIRST_COMPAT_MODE_MSG = 300;
1352    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1353
1354    CompatModeDialog mCompatModeDialog;
1355    long mLastMemUsageReportTime = 0;
1356
1357    /**
1358     * Flag whether the current user is a "monkey", i.e. whether
1359     * the UI is driven by a UI automation tool.
1360     */
1361    private boolean mUserIsMonkey;
1362
1363    /** Flag whether the device has a Recents UI */
1364    boolean mHasRecents;
1365
1366    /** The dimensions of the thumbnails in the Recents UI. */
1367    int mThumbnailWidth;
1368    int mThumbnailHeight;
1369
1370    final ServiceThread mHandlerThread;
1371    final MainHandler mHandler;
1372    final UiHandler mUiHandler;
1373
1374    final class UiHandler extends Handler {
1375        public UiHandler() {
1376            super(com.android.server.UiThread.get().getLooper(), null, true);
1377        }
1378
1379        @Override
1380        public void handleMessage(Message msg) {
1381            switch (msg.what) {
1382            case SHOW_ERROR_MSG: {
1383                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1384                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1385                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1386                synchronized (ActivityManagerService.this) {
1387                    ProcessRecord proc = (ProcessRecord)data.get("app");
1388                    AppErrorResult res = (AppErrorResult) data.get("result");
1389                    if (proc != null && proc.crashDialog != null) {
1390                        Slog.e(TAG, "App already has crash dialog: " + proc);
1391                        if (res != null) {
1392                            res.set(0);
1393                        }
1394                        return;
1395                    }
1396                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1397                            >= Process.FIRST_APPLICATION_UID
1398                            && proc.pid != MY_PID);
1399                    for (int userId : mCurrentProfileIds) {
1400                        isBackground &= (proc.userId != userId);
1401                    }
1402                    if (isBackground && !showBackground) {
1403                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1404                        if (res != null) {
1405                            res.set(0);
1406                        }
1407                        return;
1408                    }
1409                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1410                        Dialog d = new AppErrorDialog(mContext,
1411                                ActivityManagerService.this, res, proc);
1412                        d.show();
1413                        proc.crashDialog = d;
1414                    } else {
1415                        // The device is asleep, so just pretend that the user
1416                        // saw a crash dialog and hit "force quit".
1417                        if (res != null) {
1418                            res.set(0);
1419                        }
1420                    }
1421                }
1422
1423                ensureBootCompleted();
1424            } break;
1425            case SHOW_NOT_RESPONDING_MSG: {
1426                synchronized (ActivityManagerService.this) {
1427                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1428                    ProcessRecord proc = (ProcessRecord)data.get("app");
1429                    if (proc != null && proc.anrDialog != null) {
1430                        Slog.e(TAG, "App already has anr dialog: " + proc);
1431                        return;
1432                    }
1433
1434                    Intent intent = new Intent("android.intent.action.ANR");
1435                    if (!mProcessesReady) {
1436                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1437                                | Intent.FLAG_RECEIVER_FOREGROUND);
1438                    }
1439                    broadcastIntentLocked(null, null, intent,
1440                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1441                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1442
1443                    if (mShowDialogs) {
1444                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1445                                mContext, proc, (ActivityRecord)data.get("activity"),
1446                                msg.arg1 != 0);
1447                        d.show();
1448                        proc.anrDialog = d;
1449                    } else {
1450                        // Just kill the app if there is no dialog to be shown.
1451                        killAppAtUsersRequest(proc, null);
1452                    }
1453                }
1454
1455                ensureBootCompleted();
1456            } break;
1457            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1458                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1459                synchronized (ActivityManagerService.this) {
1460                    ProcessRecord proc = (ProcessRecord) data.get("app");
1461                    if (proc == null) {
1462                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1463                        break;
1464                    }
1465                    if (proc.crashDialog != null) {
1466                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1467                        return;
1468                    }
1469                    AppErrorResult res = (AppErrorResult) data.get("result");
1470                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1471                        Dialog d = new StrictModeViolationDialog(mContext,
1472                                ActivityManagerService.this, res, proc);
1473                        d.show();
1474                        proc.crashDialog = d;
1475                    } else {
1476                        // The device is asleep, so just pretend that the user
1477                        // saw a crash dialog and hit "force quit".
1478                        res.set(0);
1479                    }
1480                }
1481                ensureBootCompleted();
1482            } break;
1483            case SHOW_FACTORY_ERROR_MSG: {
1484                Dialog d = new FactoryErrorDialog(
1485                    mContext, msg.getData().getCharSequence("msg"));
1486                d.show();
1487                ensureBootCompleted();
1488            } break;
1489            case WAIT_FOR_DEBUGGER_MSG: {
1490                synchronized (ActivityManagerService.this) {
1491                    ProcessRecord app = (ProcessRecord)msg.obj;
1492                    if (msg.arg1 != 0) {
1493                        if (!app.waitedForDebugger) {
1494                            Dialog d = new AppWaitingForDebuggerDialog(
1495                                    ActivityManagerService.this,
1496                                    mContext, app);
1497                            app.waitDialog = d;
1498                            app.waitedForDebugger = true;
1499                            d.show();
1500                        }
1501                    } else {
1502                        if (app.waitDialog != null) {
1503                            app.waitDialog.dismiss();
1504                            app.waitDialog = null;
1505                        }
1506                    }
1507                }
1508            } break;
1509            case SHOW_UID_ERROR_MSG: {
1510                if (mShowDialogs) {
1511                    AlertDialog d = new BaseErrorDialog(mContext);
1512                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1513                    d.setCancelable(false);
1514                    d.setTitle(mContext.getText(R.string.android_system_label));
1515                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1516                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1517                            obtainMessage(DISMISS_DIALOG_MSG, d));
1518                    d.show();
1519                }
1520            } break;
1521            case SHOW_FINGERPRINT_ERROR_MSG: {
1522                if (mShowDialogs) {
1523                    AlertDialog d = new BaseErrorDialog(mContext);
1524                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1525                    d.setCancelable(false);
1526                    d.setTitle(mContext.getText(R.string.android_system_label));
1527                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1528                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1529                            obtainMessage(DISMISS_DIALOG_MSG, d));
1530                    d.show();
1531                }
1532            } break;
1533            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1534                synchronized (ActivityManagerService.this) {
1535                    ActivityRecord ar = (ActivityRecord) msg.obj;
1536                    if (mCompatModeDialog != null) {
1537                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1538                                ar.info.applicationInfo.packageName)) {
1539                            return;
1540                        }
1541                        mCompatModeDialog.dismiss();
1542                        mCompatModeDialog = null;
1543                    }
1544                    if (ar != null && false) {
1545                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1546                                ar.packageName)) {
1547                            int mode = mCompatModePackages.computeCompatModeLocked(
1548                                    ar.info.applicationInfo);
1549                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1550                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1551                                mCompatModeDialog = new CompatModeDialog(
1552                                        ActivityManagerService.this, mContext,
1553                                        ar.info.applicationInfo);
1554                                mCompatModeDialog.show();
1555                            }
1556                        }
1557                    }
1558                }
1559                break;
1560            }
1561            case START_USER_SWITCH_MSG: {
1562                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1563                break;
1564            }
1565            case DISMISS_DIALOG_MSG: {
1566                final Dialog d = (Dialog) msg.obj;
1567                d.dismiss();
1568                break;
1569            }
1570            case DISPATCH_PROCESSES_CHANGED: {
1571                dispatchProcessesChanged();
1572                break;
1573            }
1574            case DISPATCH_PROCESS_DIED: {
1575                final int pid = msg.arg1;
1576                final int uid = msg.arg2;
1577                dispatchProcessDied(pid, uid);
1578                break;
1579            }
1580            case DISPATCH_UIDS_CHANGED_MSG: {
1581                dispatchUidsChanged();
1582            } break;
1583            }
1584        }
1585    }
1586
1587    final class MainHandler extends Handler {
1588        public MainHandler(Looper looper) {
1589            super(looper, null, true);
1590        }
1591
1592        @Override
1593        public void handleMessage(Message msg) {
1594            switch (msg.what) {
1595            case UPDATE_CONFIGURATION_MSG: {
1596                final ContentResolver resolver = mContext.getContentResolver();
1597                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1598            } break;
1599            case GC_BACKGROUND_PROCESSES_MSG: {
1600                synchronized (ActivityManagerService.this) {
1601                    performAppGcsIfAppropriateLocked();
1602                }
1603            } break;
1604            case SERVICE_TIMEOUT_MSG: {
1605                if (mDidDexOpt) {
1606                    mDidDexOpt = false;
1607                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1608                    nmsg.obj = msg.obj;
1609                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1610                    return;
1611                }
1612                mServices.serviceTimeout((ProcessRecord)msg.obj);
1613            } break;
1614            case UPDATE_TIME_ZONE: {
1615                synchronized (ActivityManagerService.this) {
1616                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1617                        ProcessRecord r = mLruProcesses.get(i);
1618                        if (r.thread != null) {
1619                            try {
1620                                r.thread.updateTimeZone();
1621                            } catch (RemoteException ex) {
1622                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1623                            }
1624                        }
1625                    }
1626                }
1627            } break;
1628            case CLEAR_DNS_CACHE_MSG: {
1629                synchronized (ActivityManagerService.this) {
1630                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1631                        ProcessRecord r = mLruProcesses.get(i);
1632                        if (r.thread != null) {
1633                            try {
1634                                r.thread.clearDnsCache();
1635                            } catch (RemoteException ex) {
1636                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1637                            }
1638                        }
1639                    }
1640                }
1641            } break;
1642            case UPDATE_HTTP_PROXY_MSG: {
1643                ProxyInfo proxy = (ProxyInfo)msg.obj;
1644                String host = "";
1645                String port = "";
1646                String exclList = "";
1647                Uri pacFileUrl = Uri.EMPTY;
1648                if (proxy != null) {
1649                    host = proxy.getHost();
1650                    port = Integer.toString(proxy.getPort());
1651                    exclList = proxy.getExclusionListAsString();
1652                    pacFileUrl = proxy.getPacFileUrl();
1653                }
1654                synchronized (ActivityManagerService.this) {
1655                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1656                        ProcessRecord r = mLruProcesses.get(i);
1657                        if (r.thread != null) {
1658                            try {
1659                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1660                            } catch (RemoteException ex) {
1661                                Slog.w(TAG, "Failed to update http proxy for: " +
1662                                        r.info.processName);
1663                            }
1664                        }
1665                    }
1666                }
1667            } break;
1668            case PROC_START_TIMEOUT_MSG: {
1669                if (mDidDexOpt) {
1670                    mDidDexOpt = false;
1671                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1672                    nmsg.obj = msg.obj;
1673                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1674                    return;
1675                }
1676                ProcessRecord app = (ProcessRecord)msg.obj;
1677                synchronized (ActivityManagerService.this) {
1678                    processStartTimedOutLocked(app);
1679                }
1680            } break;
1681            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1684                }
1685            } break;
1686            case KILL_APPLICATION_MSG: {
1687                synchronized (ActivityManagerService.this) {
1688                    int appid = msg.arg1;
1689                    boolean restart = (msg.arg2 == 1);
1690                    Bundle bundle = (Bundle)msg.obj;
1691                    String pkg = bundle.getString("pkg");
1692                    String reason = bundle.getString("reason");
1693                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1694                            false, UserHandle.USER_ALL, reason);
1695                }
1696            } break;
1697            case FINALIZE_PENDING_INTENT_MSG: {
1698                ((PendingIntentRecord)msg.obj).completeFinalize();
1699            } break;
1700            case POST_HEAVY_NOTIFICATION_MSG: {
1701                INotificationManager inm = NotificationManager.getService();
1702                if (inm == null) {
1703                    return;
1704                }
1705
1706                ActivityRecord root = (ActivityRecord)msg.obj;
1707                ProcessRecord process = root.app;
1708                if (process == null) {
1709                    return;
1710                }
1711
1712                try {
1713                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1714                    String text = mContext.getString(R.string.heavy_weight_notification,
1715                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1716                    Notification notification = new Notification();
1717                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1718                    notification.when = 0;
1719                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1720                    notification.tickerText = text;
1721                    notification.defaults = 0; // please be quiet
1722                    notification.sound = null;
1723                    notification.vibrate = null;
1724                    notification.color = mContext.getColor(
1725                            com.android.internal.R.color.system_notification_accent_color);
1726                    notification.setLatestEventInfo(context, text,
1727                            mContext.getText(R.string.heavy_weight_notification_detail),
1728                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1729                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1730                                    new UserHandle(root.userId)));
1731
1732                    try {
1733                        int[] outId = new int[1];
1734                        inm.enqueueNotificationWithTag("android", "android", null,
1735                                R.string.heavy_weight_notification,
1736                                notification, outId, root.userId);
1737                    } catch (RuntimeException e) {
1738                        Slog.w(ActivityManagerService.TAG,
1739                                "Error showing notification for heavy-weight app", e);
1740                    } catch (RemoteException e) {
1741                    }
1742                } catch (NameNotFoundException e) {
1743                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1744                }
1745            } break;
1746            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1747                INotificationManager inm = NotificationManager.getService();
1748                if (inm == null) {
1749                    return;
1750                }
1751                try {
1752                    inm.cancelNotificationWithTag("android", null,
1753                            R.string.heavy_weight_notification,  msg.arg1);
1754                } catch (RuntimeException e) {
1755                    Slog.w(ActivityManagerService.TAG,
1756                            "Error canceling notification for service", e);
1757                } catch (RemoteException e) {
1758                }
1759            } break;
1760            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    checkExcessivePowerUsageLocked(true);
1763                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1764                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1765                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1766                }
1767            } break;
1768            case REPORT_MEM_USAGE_MSG: {
1769                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1770                Thread thread = new Thread() {
1771                    @Override public void run() {
1772                        reportMemUsage(memInfos);
1773                    }
1774                };
1775                thread.start();
1776                break;
1777            }
1778            case REPORT_USER_SWITCH_MSG: {
1779                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1780                break;
1781            }
1782            case CONTINUE_USER_SWITCH_MSG: {
1783                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1784                break;
1785            }
1786            case USER_SWITCH_TIMEOUT_MSG: {
1787                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1788                break;
1789            }
1790            case IMMERSIVE_MODE_LOCK_MSG: {
1791                final boolean nextState = (msg.arg1 != 0);
1792                if (mUpdateLock.isHeld() != nextState) {
1793                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1794                            "Applying new update lock state '" + nextState
1795                            + "' for " + (ActivityRecord)msg.obj);
1796                    if (nextState) {
1797                        mUpdateLock.acquire();
1798                    } else {
1799                        mUpdateLock.release();
1800                    }
1801                }
1802                break;
1803            }
1804            case PERSIST_URI_GRANTS_MSG: {
1805                writeGrantedUriPermissions();
1806                break;
1807            }
1808            case REQUEST_ALL_PSS_MSG: {
1809                synchronized (ActivityManagerService.this) {
1810                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1811                }
1812                break;
1813            }
1814            case START_PROFILES_MSG: {
1815                synchronized (ActivityManagerService.this) {
1816                    startProfilesLocked();
1817                }
1818                break;
1819            }
1820            case UPDATE_TIME: {
1821                synchronized (ActivityManagerService.this) {
1822                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1823                        ProcessRecord r = mLruProcesses.get(i);
1824                        if (r.thread != null) {
1825                            try {
1826                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1827                            } catch (RemoteException ex) {
1828                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1829                            }
1830                        }
1831                    }
1832                }
1833                break;
1834            }
1835            case SYSTEM_USER_START_MSG: {
1836                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1837                        Integer.toString(msg.arg1), msg.arg1);
1838                mSystemServiceManager.startUser(msg.arg1);
1839                break;
1840            }
1841            case SYSTEM_USER_CURRENT_MSG: {
1842                mBatteryStatsService.noteEvent(
1843                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1844                        Integer.toString(msg.arg2), msg.arg2);
1845                mBatteryStatsService.noteEvent(
1846                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.switchUser(msg.arg1);
1849                break;
1850            }
1851            case ENTER_ANIMATION_COMPLETE_MSG: {
1852                synchronized (ActivityManagerService.this) {
1853                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1854                    if (r != null && r.app != null && r.app.thread != null) {
1855                        try {
1856                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1857                        } catch (RemoteException e) {
1858                        }
1859                    }
1860                }
1861                break;
1862            }
1863            case FINISH_BOOTING_MSG: {
1864                if (msg.arg1 != 0) {
1865                    finishBooting();
1866                }
1867                if (msg.arg2 != 0) {
1868                    enableScreenAfterBoot();
1869                }
1870                break;
1871            }
1872            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1873                try {
1874                    Locale l = (Locale) msg.obj;
1875                    IBinder service = ServiceManager.getService("mount");
1876                    IMountService mountService = IMountService.Stub.asInterface(service);
1877                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1878                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1879                } catch (RemoteException e) {
1880                    Log.e(TAG, "Error storing locale for decryption UI", e);
1881                }
1882                break;
1883            }
1884            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1885                synchronized (ActivityManagerService.this) {
1886                    int i = mTaskStackListeners.beginBroadcast();
1887                    while (i > 0) {
1888                        i--;
1889                        try {
1890                            // Make a one-way callback to the listener
1891                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1892                        } catch (RemoteException e){
1893                            // Handled by the RemoteCallbackList
1894                        }
1895                    }
1896                    mTaskStackListeners.finishBroadcast();
1897                }
1898                break;
1899            }
1900            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1901                final int uid = msg.arg1;
1902                final byte[] firstPacket = (byte[]) msg.obj;
1903
1904                synchronized (mPidsSelfLocked) {
1905                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1906                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1907                        if (p.uid == uid) {
1908                            try {
1909                                p.thread.notifyCleartextNetwork(firstPacket);
1910                            } catch (RemoteException ignored) {
1911                            }
1912                        }
1913                    }
1914                }
1915                break;
1916            }
1917            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1918                final String procName;
1919                final int uid;
1920                final long memLimit;
1921                final String reportPackage;
1922                synchronized (ActivityManagerService.this) {
1923                    procName = mMemWatchDumpProcName;
1924                    uid = mMemWatchDumpUid;
1925                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1926                    if (val == null) {
1927                        val = mMemWatchProcesses.get(procName, 0);
1928                    }
1929                    if (val != null) {
1930                        memLimit = val.first;
1931                        reportPackage = val.second;
1932                    } else {
1933                        memLimit = 0;
1934                        reportPackage = null;
1935                    }
1936                }
1937                if (procName == null) {
1938                    return;
1939                }
1940
1941                if (DEBUG_PSS) Slog.d(TAG_PSS,
1942                        "Showing dump heap notification from " + procName + "/" + uid);
1943
1944                INotificationManager inm = NotificationManager.getService();
1945                if (inm == null) {
1946                    return;
1947                }
1948
1949                String text = mContext.getString(R.string.dump_heap_notification, procName);
1950                Notification notification = new Notification();
1951                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1952                notification.when = 0;
1953                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1954                notification.tickerText = text;
1955                notification.defaults = 0; // please be quiet
1956                notification.sound = null;
1957                notification.vibrate = null;
1958                notification.color = mContext.getColor(
1959                        com.android.internal.R.color.system_notification_accent_color);
1960                Intent deleteIntent = new Intent();
1961                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1962                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1963                        deleteIntent, 0, UserHandle.OWNER);
1964                Intent intent = new Intent();
1965                intent.setClassName("android", DumpHeapActivity.class.getName());
1966                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1967                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1968                if (reportPackage != null) {
1969                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1970                }
1971                int userId = UserHandle.getUserId(uid);
1972                notification.setLatestEventInfo(mContext, text,
1973                        mContext.getText(R.string.dump_heap_notification_detail),
1974                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1975                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1976                                new UserHandle(userId)));
1977
1978                try {
1979                    int[] outId = new int[1];
1980                    inm.enqueueNotificationWithTag("android", "android", null,
1981                            R.string.dump_heap_notification,
1982                            notification, outId, userId);
1983                } catch (RuntimeException e) {
1984                    Slog.w(ActivityManagerService.TAG,
1985                            "Error showing notification for dump heap", e);
1986                } catch (RemoteException e) {
1987                }
1988            } break;
1989            case DELETE_DUMPHEAP_MSG: {
1990                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1991                        DumpHeapActivity.JAVA_URI,
1992                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1993                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1994                        UserHandle.myUserId());
1995                synchronized (ActivityManagerService.this) {
1996                    mMemWatchDumpFile = null;
1997                    mMemWatchDumpProcName = null;
1998                    mMemWatchDumpPid = -1;
1999                    mMemWatchDumpUid = -1;
2000                }
2001            } break;
2002            case FOREGROUND_PROFILE_CHANGED_MSG: {
2003                dispatchForegroundProfileChanged(msg.arg1);
2004            } break;
2005            case REPORT_TIME_TRACKER_MSG: {
2006                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2007                tracker.deliverResult(mContext);
2008            } break;
2009            }
2010        }
2011    };
2012
2013    static final int COLLECT_PSS_BG_MSG = 1;
2014
2015    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2016        @Override
2017        public void handleMessage(Message msg) {
2018            switch (msg.what) {
2019            case COLLECT_PSS_BG_MSG: {
2020                long start = SystemClock.uptimeMillis();
2021                MemInfoReader memInfo = null;
2022                synchronized (ActivityManagerService.this) {
2023                    if (mFullPssPending) {
2024                        mFullPssPending = false;
2025                        memInfo = new MemInfoReader();
2026                    }
2027                }
2028                if (memInfo != null) {
2029                    updateCpuStatsNow();
2030                    long nativeTotalPss = 0;
2031                    synchronized (mProcessCpuTracker) {
2032                        final int N = mProcessCpuTracker.countStats();
2033                        for (int j=0; j<N; j++) {
2034                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2035                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2036                                // This is definitely an application process; skip it.
2037                                continue;
2038                            }
2039                            synchronized (mPidsSelfLocked) {
2040                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2041                                    // This is one of our own processes; skip it.
2042                                    continue;
2043                                }
2044                            }
2045                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2046                        }
2047                    }
2048                    memInfo.readMemInfo();
2049                    synchronized (ActivityManagerService.this) {
2050                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2051                                + (SystemClock.uptimeMillis()-start) + "ms");
2052                        final long cachedKb = memInfo.getCachedSizeKb();
2053                        final long freeKb = memInfo.getFreeSizeKb();
2054                        final long zramKb = memInfo.getZramTotalSizeKb();
2055                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2056                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2057                                kernelKb*1024, nativeTotalPss*1024);
2058                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2059                                nativeTotalPss);
2060                    }
2061                }
2062
2063                int num = 0;
2064                long[] tmp = new long[1];
2065                do {
2066                    ProcessRecord proc;
2067                    int procState;
2068                    int pid;
2069                    long lastPssTime;
2070                    synchronized (ActivityManagerService.this) {
2071                        if (mPendingPssProcesses.size() <= 0) {
2072                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2073                                    "Collected PSS of " + num + " processes in "
2074                                    + (SystemClock.uptimeMillis() - start) + "ms");
2075                            mPendingPssProcesses.clear();
2076                            return;
2077                        }
2078                        proc = mPendingPssProcesses.remove(0);
2079                        procState = proc.pssProcState;
2080                        lastPssTime = proc.lastPssTime;
2081                        if (proc.thread != null && procState == proc.setProcState
2082                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2083                                        < SystemClock.uptimeMillis()) {
2084                            pid = proc.pid;
2085                        } else {
2086                            proc = null;
2087                            pid = 0;
2088                        }
2089                    }
2090                    if (proc != null) {
2091                        long pss = Debug.getPss(pid, tmp, null);
2092                        synchronized (ActivityManagerService.this) {
2093                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2094                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2095                                num++;
2096                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2097                                        SystemClock.uptimeMillis());
2098                            }
2099                        }
2100                    }
2101                } while (true);
2102            }
2103            }
2104        }
2105    };
2106
2107    public void setSystemProcess() {
2108        try {
2109            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2110            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2111            ServiceManager.addService("meminfo", new MemBinder(this));
2112            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2113            ServiceManager.addService("dbinfo", new DbBinder(this));
2114            if (MONITOR_CPU_USAGE) {
2115                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2116            }
2117            ServiceManager.addService("permission", new PermissionController(this));
2118            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2119
2120            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2121                    "android", STOCK_PM_FLAGS);
2122            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2123
2124            synchronized (this) {
2125                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2126                app.persistent = true;
2127                app.pid = MY_PID;
2128                app.maxAdj = ProcessList.SYSTEM_ADJ;
2129                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2130                synchronized (mPidsSelfLocked) {
2131                    mPidsSelfLocked.put(app.pid, app);
2132                }
2133                updateLruProcessLocked(app, false, null);
2134                updateOomAdjLocked();
2135            }
2136        } catch (PackageManager.NameNotFoundException e) {
2137            throw new RuntimeException(
2138                    "Unable to find android system package", e);
2139        }
2140    }
2141
2142    public void setWindowManager(WindowManagerService wm) {
2143        mWindowManager = wm;
2144        mStackSupervisor.setWindowManager(wm);
2145    }
2146
2147    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2148        mUsageStatsService = usageStatsManager;
2149    }
2150
2151    public void startObservingNativeCrashes() {
2152        final NativeCrashListener ncl = new NativeCrashListener(this);
2153        ncl.start();
2154    }
2155
2156    public IAppOpsService getAppOpsService() {
2157        return mAppOpsService;
2158    }
2159
2160    static class MemBinder extends Binder {
2161        ActivityManagerService mActivityManagerService;
2162        MemBinder(ActivityManagerService activityManagerService) {
2163            mActivityManagerService = activityManagerService;
2164        }
2165
2166        @Override
2167        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2168            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2169                    != PackageManager.PERMISSION_GRANTED) {
2170                pw.println("Permission Denial: can't dump meminfo from from pid="
2171                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2172                        + " without permission " + android.Manifest.permission.DUMP);
2173                return;
2174            }
2175
2176            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2177        }
2178    }
2179
2180    static class GraphicsBinder extends Binder {
2181        ActivityManagerService mActivityManagerService;
2182        GraphicsBinder(ActivityManagerService activityManagerService) {
2183            mActivityManagerService = activityManagerService;
2184        }
2185
2186        @Override
2187        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2188            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2189                    != PackageManager.PERMISSION_GRANTED) {
2190                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2191                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2192                        + " without permission " + android.Manifest.permission.DUMP);
2193                return;
2194            }
2195
2196            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2197        }
2198    }
2199
2200    static class DbBinder extends Binder {
2201        ActivityManagerService mActivityManagerService;
2202        DbBinder(ActivityManagerService activityManagerService) {
2203            mActivityManagerService = activityManagerService;
2204        }
2205
2206        @Override
2207        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2208            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2209                    != PackageManager.PERMISSION_GRANTED) {
2210                pw.println("Permission Denial: can't dump dbinfo from from pid="
2211                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2212                        + " without permission " + android.Manifest.permission.DUMP);
2213                return;
2214            }
2215
2216            mActivityManagerService.dumpDbInfo(fd, pw, args);
2217        }
2218    }
2219
2220    static class CpuBinder extends Binder {
2221        ActivityManagerService mActivityManagerService;
2222        CpuBinder(ActivityManagerService activityManagerService) {
2223            mActivityManagerService = activityManagerService;
2224        }
2225
2226        @Override
2227        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2228            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2229                    != PackageManager.PERMISSION_GRANTED) {
2230                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2231                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2232                        + " without permission " + android.Manifest.permission.DUMP);
2233                return;
2234            }
2235
2236            synchronized (mActivityManagerService.mProcessCpuTracker) {
2237                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2238                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2239                        SystemClock.uptimeMillis()));
2240            }
2241        }
2242    }
2243
2244    public static final class Lifecycle extends SystemService {
2245        private final ActivityManagerService mService;
2246
2247        public Lifecycle(Context context) {
2248            super(context);
2249            mService = new ActivityManagerService(context);
2250        }
2251
2252        @Override
2253        public void onStart() {
2254            mService.start();
2255        }
2256
2257        public ActivityManagerService getService() {
2258            return mService;
2259        }
2260    }
2261
2262    // Note: This method is invoked on the main thread but may need to attach various
2263    // handlers to other threads.  So take care to be explicit about the looper.
2264    public ActivityManagerService(Context systemContext) {
2265        mContext = systemContext;
2266        mFactoryTest = FactoryTest.getMode();
2267        mSystemThread = ActivityThread.currentActivityThread();
2268
2269        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2270
2271        mHandlerThread = new ServiceThread(TAG,
2272                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2273        mHandlerThread.start();
2274        mHandler = new MainHandler(mHandlerThread.getLooper());
2275        mUiHandler = new UiHandler();
2276
2277        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2278                "foreground", BROADCAST_FG_TIMEOUT, false);
2279        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2280                "background", BROADCAST_BG_TIMEOUT, true);
2281        mBroadcastQueues[0] = mFgBroadcastQueue;
2282        mBroadcastQueues[1] = mBgBroadcastQueue;
2283
2284        mServices = new ActiveServices(this);
2285        mProviderMap = new ProviderMap(this);
2286
2287        // TODO: Move creation of battery stats service outside of activity manager service.
2288        File dataDir = Environment.getDataDirectory();
2289        File systemDir = new File(dataDir, "system");
2290        systemDir.mkdirs();
2291        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2292        mBatteryStatsService.getActiveStatistics().readLocked();
2293        mBatteryStatsService.scheduleWriteToDisk();
2294        mOnBattery = DEBUG_POWER ? true
2295                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2296        mBatteryStatsService.getActiveStatistics().setCallback(this);
2297
2298        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2299
2300        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2301
2302        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2303
2304        // User 0 is the first and only user that runs at boot.
2305        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2306        mUserLru.add(UserHandle.USER_OWNER);
2307        updateStartedUserArrayLocked();
2308
2309        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2310            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2311
2312        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2313
2314        mConfiguration.setToDefaults();
2315        mConfiguration.setLocale(Locale.getDefault());
2316
2317        mConfigurationSeq = mConfiguration.seq = 1;
2318        mProcessCpuTracker.init();
2319
2320        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2321        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2322        mRecentTasks = new RecentTasks(this);
2323        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2324        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2325
2326        mProcessCpuThread = new Thread("CpuTracker") {
2327            @Override
2328            public void run() {
2329                while (true) {
2330                    try {
2331                        try {
2332                            synchronized(this) {
2333                                final long now = SystemClock.uptimeMillis();
2334                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2335                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2336                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2337                                //        + ", write delay=" + nextWriteDelay);
2338                                if (nextWriteDelay < nextCpuDelay) {
2339                                    nextCpuDelay = nextWriteDelay;
2340                                }
2341                                if (nextCpuDelay > 0) {
2342                                    mProcessCpuMutexFree.set(true);
2343                                    this.wait(nextCpuDelay);
2344                                }
2345                            }
2346                        } catch (InterruptedException e) {
2347                        }
2348                        updateCpuStatsNow();
2349                    } catch (Exception e) {
2350                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2351                    }
2352                }
2353            }
2354        };
2355
2356        Watchdog.getInstance().addMonitor(this);
2357        Watchdog.getInstance().addThread(mHandler);
2358    }
2359
2360    public void setSystemServiceManager(SystemServiceManager mgr) {
2361        mSystemServiceManager = mgr;
2362    }
2363
2364    public void setInstaller(Installer installer) {
2365        mInstaller = installer;
2366    }
2367
2368    private void start() {
2369        Process.removeAllProcessGroups();
2370        mProcessCpuThread.start();
2371
2372        mBatteryStatsService.publish(mContext);
2373        mAppOpsService.publish(mContext);
2374        Slog.d("AppOps", "AppOpsService published");
2375        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2376    }
2377
2378    public void initPowerManagement() {
2379        mStackSupervisor.initPowerManagement();
2380        mBatteryStatsService.initPowerManagement();
2381        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2382        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2383        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2384        mVoiceWakeLock.setReferenceCounted(false);
2385    }
2386
2387    @Override
2388    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2389            throws RemoteException {
2390        if (code == SYSPROPS_TRANSACTION) {
2391            // We need to tell all apps about the system property change.
2392            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2393            synchronized(this) {
2394                final int NP = mProcessNames.getMap().size();
2395                for (int ip=0; ip<NP; ip++) {
2396                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2397                    final int NA = apps.size();
2398                    for (int ia=0; ia<NA; ia++) {
2399                        ProcessRecord app = apps.valueAt(ia);
2400                        if (app.thread != null) {
2401                            procs.add(app.thread.asBinder());
2402                        }
2403                    }
2404                }
2405            }
2406
2407            int N = procs.size();
2408            for (int i=0; i<N; i++) {
2409                Parcel data2 = Parcel.obtain();
2410                try {
2411                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2412                } catch (RemoteException e) {
2413                }
2414                data2.recycle();
2415            }
2416        }
2417        try {
2418            return super.onTransact(code, data, reply, flags);
2419        } catch (RuntimeException e) {
2420            // The activity manager only throws security exceptions, so let's
2421            // log all others.
2422            if (!(e instanceof SecurityException)) {
2423                Slog.wtf(TAG, "Activity Manager Crash", e);
2424            }
2425            throw e;
2426        }
2427    }
2428
2429    void updateCpuStats() {
2430        final long now = SystemClock.uptimeMillis();
2431        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2432            return;
2433        }
2434        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2435            synchronized (mProcessCpuThread) {
2436                mProcessCpuThread.notify();
2437            }
2438        }
2439    }
2440
2441    void updateCpuStatsNow() {
2442        synchronized (mProcessCpuTracker) {
2443            mProcessCpuMutexFree.set(false);
2444            final long now = SystemClock.uptimeMillis();
2445            boolean haveNewCpuStats = false;
2446
2447            if (MONITOR_CPU_USAGE &&
2448                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2449                mLastCpuTime.set(now);
2450                mProcessCpuTracker.update();
2451                if (mProcessCpuTracker.hasGoodLastStats()) {
2452                    haveNewCpuStats = true;
2453                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2454                    //Slog.i(TAG, "Total CPU usage: "
2455                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2456
2457                    // Slog the cpu usage if the property is set.
2458                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2459                        int user = mProcessCpuTracker.getLastUserTime();
2460                        int system = mProcessCpuTracker.getLastSystemTime();
2461                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2462                        int irq = mProcessCpuTracker.getLastIrqTime();
2463                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2464                        int idle = mProcessCpuTracker.getLastIdleTime();
2465
2466                        int total = user + system + iowait + irq + softIrq + idle;
2467                        if (total == 0) total = 1;
2468
2469                        EventLog.writeEvent(EventLogTags.CPU,
2470                                ((user+system+iowait+irq+softIrq) * 100) / total,
2471                                (user * 100) / total,
2472                                (system * 100) / total,
2473                                (iowait * 100) / total,
2474                                (irq * 100) / total,
2475                                (softIrq * 100) / total);
2476                    }
2477                }
2478            }
2479
2480            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2481            synchronized(bstats) {
2482                synchronized(mPidsSelfLocked) {
2483                    if (haveNewCpuStats) {
2484                        final int perc = bstats.startAddingCpuLocked();
2485                        if (perc >= 0) {
2486                            int remainUTime = 0;
2487                            int remainSTime = 0;
2488                            int totalUTime = 0;
2489                            int totalSTime = 0;
2490                            final int N = mProcessCpuTracker.countStats();
2491                            for (int i=0; i<N; i++) {
2492                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2493                                if (!st.working) {
2494                                    continue;
2495                                }
2496                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2497                                int otherUTime = (st.rel_utime*perc)/100;
2498                                int otherSTime = (st.rel_stime*perc)/100;
2499                                remainUTime += otherUTime;
2500                                remainSTime += otherSTime;
2501                                totalUTime += st.rel_utime;
2502                                totalSTime += st.rel_stime;
2503                                if (pr != null) {
2504                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2505                                    if (ps == null || !ps.isActive()) {
2506                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2507                                                pr.info.uid, pr.processName);
2508                                    }
2509                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2510                                            st.rel_stime - otherSTime);
2511                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2512                                } else {
2513                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2514                                    if (ps == null || !ps.isActive()) {
2515                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2516                                                bstats.mapUid(st.uid), st.name);
2517                                    }
2518                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2519                                            st.rel_stime - otherSTime);
2520                                }
2521                            }
2522                            final int userTime = mProcessCpuTracker.getLastUserTime();
2523                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2524                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2525                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2526                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2527                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2528                            bstats.finishAddingCpuLocked(perc, remainUTime,
2529                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2530                                    iowaitTime, irqTime, softIrqTime, idleTime);
2531                        }
2532                    }
2533                }
2534
2535                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2536                    mLastWriteTime = now;
2537                    mBatteryStatsService.scheduleWriteToDisk();
2538                }
2539            }
2540        }
2541    }
2542
2543    @Override
2544    public void batteryNeedsCpuUpdate() {
2545        updateCpuStatsNow();
2546    }
2547
2548    @Override
2549    public void batteryPowerChanged(boolean onBattery) {
2550        // When plugging in, update the CPU stats first before changing
2551        // the plug state.
2552        updateCpuStatsNow();
2553        synchronized (this) {
2554            synchronized(mPidsSelfLocked) {
2555                mOnBattery = DEBUG_POWER ? true : onBattery;
2556            }
2557        }
2558    }
2559
2560    @Override
2561    public void batterySendBroadcast(Intent intent) {
2562        broadcastIntentLocked(null, null, intent, null,
2563                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
2564                Process.SYSTEM_UID, UserHandle.USER_ALL);
2565    }
2566
2567    /**
2568     * Initialize the application bind args. These are passed to each
2569     * process when the bindApplication() IPC is sent to the process. They're
2570     * lazily setup to make sure the services are running when they're asked for.
2571     */
2572    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2573        if (mAppBindArgs == null) {
2574            mAppBindArgs = new HashMap<>();
2575
2576            // Isolated processes won't get this optimization, so that we don't
2577            // violate the rules about which services they have access to.
2578            if (!isolated) {
2579                // Setup the application init args
2580                mAppBindArgs.put("package", ServiceManager.getService("package"));
2581                mAppBindArgs.put("window", ServiceManager.getService("window"));
2582                mAppBindArgs.put(Context.ALARM_SERVICE,
2583                        ServiceManager.getService(Context.ALARM_SERVICE));
2584            }
2585        }
2586        return mAppBindArgs;
2587    }
2588
2589    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2590        if (r != null && mFocusedActivity != r) {
2591            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2592            ActivityRecord last = mFocusedActivity;
2593            mFocusedActivity = r;
2594            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2595                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2596                if (mCurAppTimeTracker != r.appTimeTracker) {
2597                    // We are switching app tracking.  Complete the current one.
2598                    if (mCurAppTimeTracker != null) {
2599                        mCurAppTimeTracker.stop();
2600                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2601                                mCurAppTimeTracker).sendToTarget();
2602                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2603                        mCurAppTimeTracker = null;
2604                    }
2605                    if (r.appTimeTracker != null) {
2606                        mCurAppTimeTracker = r.appTimeTracker;
2607                        startTimeTrackingFocusedActivityLocked();
2608                    }
2609                } else {
2610                    startTimeTrackingFocusedActivityLocked();
2611                }
2612            } else {
2613                r.appTimeTracker = null;
2614            }
2615            if (r.task != null && r.task.voiceInteractor != null) {
2616                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2617            } else {
2618                finishRunningVoiceLocked();
2619                if (last != null && last.task.voiceSession != null) {
2620                    // We had been in a voice interaction session, but now focused has
2621                    // move to something different.  Just finish the session, we can't
2622                    // return to it and retain the proper state and synchronization with
2623                    // the voice interaction service.
2624                    finishVoiceTask(last.task.voiceSession);
2625                }
2626            }
2627            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2628                mWindowManager.setFocusedApp(r.appToken, true);
2629            }
2630            applyUpdateLockStateLocked(r);
2631            if (mFocusedActivity.userId != mLastFocusedUserId) {
2632                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2633                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2634                        mFocusedActivity.userId, 0));
2635                mLastFocusedUserId = mFocusedActivity.userId;
2636            }
2637        }
2638        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2639                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2640                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2641    }
2642
2643    final void clearFocusedActivity(ActivityRecord r) {
2644        if (mFocusedActivity == r) {
2645            ActivityStack stack = mStackSupervisor.getFocusedStack();
2646            if (stack != null) {
2647                ActivityRecord top = stack.topActivity();
2648                if (top != null && top.userId != mLastFocusedUserId) {
2649                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2650                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2651                                    top.userId, 0));
2652                    mLastFocusedUserId = top.userId;
2653                }
2654            }
2655            mFocusedActivity = null;
2656            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2657        }
2658    }
2659
2660    @Override
2661    public void setFocusedStack(int stackId) {
2662        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2663        synchronized (ActivityManagerService.this) {
2664            ActivityStack stack = mStackSupervisor.getStack(stackId);
2665            if (stack != null) {
2666                ActivityRecord r = stack.topRunningActivityLocked(null);
2667                if (r != null) {
2668                    setFocusedActivityLocked(r, "setFocusedStack");
2669                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2670                }
2671            }
2672        }
2673    }
2674
2675    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2676    @Override
2677    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2678        synchronized (ActivityManagerService.this) {
2679            if (listener != null) {
2680                mTaskStackListeners.register(listener);
2681            }
2682        }
2683    }
2684
2685    @Override
2686    public void notifyActivityDrawn(IBinder token) {
2687        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2688        synchronized (this) {
2689            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2690            if (r != null) {
2691                r.task.stack.notifyActivityDrawnLocked(r);
2692            }
2693        }
2694    }
2695
2696    final void applyUpdateLockStateLocked(ActivityRecord r) {
2697        // Modifications to the UpdateLock state are done on our handler, outside
2698        // the activity manager's locks.  The new state is determined based on the
2699        // state *now* of the relevant activity record.  The object is passed to
2700        // the handler solely for logging detail, not to be consulted/modified.
2701        final boolean nextState = r != null && r.immersive;
2702        mHandler.sendMessage(
2703                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2704    }
2705
2706    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2707        Message msg = Message.obtain();
2708        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2709        msg.obj = r.task.askedCompatMode ? null : r;
2710        mUiHandler.sendMessage(msg);
2711    }
2712
2713    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2714            String what, Object obj, ProcessRecord srcApp) {
2715        app.lastActivityTime = now;
2716
2717        if (app.activities.size() > 0) {
2718            // Don't want to touch dependent processes that are hosting activities.
2719            return index;
2720        }
2721
2722        int lrui = mLruProcesses.lastIndexOf(app);
2723        if (lrui < 0) {
2724            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2725                    + what + " " + obj + " from " + srcApp);
2726            return index;
2727        }
2728
2729        if (lrui >= index) {
2730            // Don't want to cause this to move dependent processes *back* in the
2731            // list as if they were less frequently used.
2732            return index;
2733        }
2734
2735        if (lrui >= mLruProcessActivityStart) {
2736            // Don't want to touch dependent processes that are hosting activities.
2737            return index;
2738        }
2739
2740        mLruProcesses.remove(lrui);
2741        if (index > 0) {
2742            index--;
2743        }
2744        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2745                + " in LRU list: " + app);
2746        mLruProcesses.add(index, app);
2747        return index;
2748    }
2749
2750    final void removeLruProcessLocked(ProcessRecord app) {
2751        int lrui = mLruProcesses.lastIndexOf(app);
2752        if (lrui >= 0) {
2753            if (!app.killed) {
2754                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2755                Process.killProcessQuiet(app.pid);
2756                Process.killProcessGroup(app.info.uid, app.pid);
2757            }
2758            if (lrui <= mLruProcessActivityStart) {
2759                mLruProcessActivityStart--;
2760            }
2761            if (lrui <= mLruProcessServiceStart) {
2762                mLruProcessServiceStart--;
2763            }
2764            mLruProcesses.remove(lrui);
2765        }
2766    }
2767
2768    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2769            ProcessRecord client) {
2770        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2771                || app.treatLikeActivity;
2772        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2773        if (!activityChange && hasActivity) {
2774            // The process has activities, so we are only allowing activity-based adjustments
2775            // to move it.  It should be kept in the front of the list with other
2776            // processes that have activities, and we don't want those to change their
2777            // order except due to activity operations.
2778            return;
2779        }
2780
2781        mLruSeq++;
2782        final long now = SystemClock.uptimeMillis();
2783        app.lastActivityTime = now;
2784
2785        // First a quick reject: if the app is already at the position we will
2786        // put it, then there is nothing to do.
2787        if (hasActivity) {
2788            final int N = mLruProcesses.size();
2789            if (N > 0 && mLruProcesses.get(N-1) == app) {
2790                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2791                return;
2792            }
2793        } else {
2794            if (mLruProcessServiceStart > 0
2795                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2796                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2797                return;
2798            }
2799        }
2800
2801        int lrui = mLruProcesses.lastIndexOf(app);
2802
2803        if (app.persistent && lrui >= 0) {
2804            // We don't care about the position of persistent processes, as long as
2805            // they are in the list.
2806            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2807            return;
2808        }
2809
2810        /* In progress: compute new position first, so we can avoid doing work
2811           if the process is not actually going to move.  Not yet working.
2812        int addIndex;
2813        int nextIndex;
2814        boolean inActivity = false, inService = false;
2815        if (hasActivity) {
2816            // Process has activities, put it at the very tipsy-top.
2817            addIndex = mLruProcesses.size();
2818            nextIndex = mLruProcessServiceStart;
2819            inActivity = true;
2820        } else if (hasService) {
2821            // Process has services, put it at the top of the service list.
2822            addIndex = mLruProcessActivityStart;
2823            nextIndex = mLruProcessServiceStart;
2824            inActivity = true;
2825            inService = true;
2826        } else  {
2827            // Process not otherwise of interest, it goes to the top of the non-service area.
2828            addIndex = mLruProcessServiceStart;
2829            if (client != null) {
2830                int clientIndex = mLruProcesses.lastIndexOf(client);
2831                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2832                        + app);
2833                if (clientIndex >= 0 && addIndex > clientIndex) {
2834                    addIndex = clientIndex;
2835                }
2836            }
2837            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2838        }
2839
2840        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2841                + mLruProcessActivityStart + "): " + app);
2842        */
2843
2844        if (lrui >= 0) {
2845            if (lrui < mLruProcessActivityStart) {
2846                mLruProcessActivityStart--;
2847            }
2848            if (lrui < mLruProcessServiceStart) {
2849                mLruProcessServiceStart--;
2850            }
2851            /*
2852            if (addIndex > lrui) {
2853                addIndex--;
2854            }
2855            if (nextIndex > lrui) {
2856                nextIndex--;
2857            }
2858            */
2859            mLruProcesses.remove(lrui);
2860        }
2861
2862        /*
2863        mLruProcesses.add(addIndex, app);
2864        if (inActivity) {
2865            mLruProcessActivityStart++;
2866        }
2867        if (inService) {
2868            mLruProcessActivityStart++;
2869        }
2870        */
2871
2872        int nextIndex;
2873        if (hasActivity) {
2874            final int N = mLruProcesses.size();
2875            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2876                // Process doesn't have activities, but has clients with
2877                // activities...  move it up, but one below the top (the top
2878                // should always have a real activity).
2879                if (DEBUG_LRU) Slog.d(TAG_LRU,
2880                        "Adding to second-top of LRU activity list: " + app);
2881                mLruProcesses.add(N - 1, app);
2882                // To keep it from spamming the LRU list (by making a bunch of clients),
2883                // we will push down any other entries owned by the app.
2884                final int uid = app.info.uid;
2885                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2886                    ProcessRecord subProc = mLruProcesses.get(i);
2887                    if (subProc.info.uid == uid) {
2888                        // We want to push this one down the list.  If the process after
2889                        // it is for the same uid, however, don't do so, because we don't
2890                        // want them internally to be re-ordered.
2891                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2892                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2893                                    "Pushing uid " + uid + " swapping at " + i + ": "
2894                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2895                            ProcessRecord tmp = mLruProcesses.get(i);
2896                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2897                            mLruProcesses.set(i - 1, tmp);
2898                            i--;
2899                        }
2900                    } else {
2901                        // A gap, we can stop here.
2902                        break;
2903                    }
2904                }
2905            } else {
2906                // Process has activities, put it at the very tipsy-top.
2907                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2908                mLruProcesses.add(app);
2909            }
2910            nextIndex = mLruProcessServiceStart;
2911        } else if (hasService) {
2912            // Process has services, put it at the top of the service list.
2913            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2914            mLruProcesses.add(mLruProcessActivityStart, app);
2915            nextIndex = mLruProcessServiceStart;
2916            mLruProcessActivityStart++;
2917        } else  {
2918            // Process not otherwise of interest, it goes to the top of the non-service area.
2919            int index = mLruProcessServiceStart;
2920            if (client != null) {
2921                // If there is a client, don't allow the process to be moved up higher
2922                // in the list than that client.
2923                int clientIndex = mLruProcesses.lastIndexOf(client);
2924                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2925                        + " when updating " + app);
2926                if (clientIndex <= lrui) {
2927                    // Don't allow the client index restriction to push it down farther in the
2928                    // list than it already is.
2929                    clientIndex = lrui;
2930                }
2931                if (clientIndex >= 0 && index > clientIndex) {
2932                    index = clientIndex;
2933                }
2934            }
2935            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2936            mLruProcesses.add(index, app);
2937            nextIndex = index-1;
2938            mLruProcessActivityStart++;
2939            mLruProcessServiceStart++;
2940        }
2941
2942        // If the app is currently using a content provider or service,
2943        // bump those processes as well.
2944        for (int j=app.connections.size()-1; j>=0; j--) {
2945            ConnectionRecord cr = app.connections.valueAt(j);
2946            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2947                    && cr.binding.service.app != null
2948                    && cr.binding.service.app.lruSeq != mLruSeq
2949                    && !cr.binding.service.app.persistent) {
2950                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2951                        "service connection", cr, app);
2952            }
2953        }
2954        for (int j=app.conProviders.size()-1; j>=0; j--) {
2955            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2956            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2957                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2958                        "provider reference", cpr, app);
2959            }
2960        }
2961    }
2962
2963    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2964        if (uid == Process.SYSTEM_UID) {
2965            // The system gets to run in any process.  If there are multiple
2966            // processes with the same uid, just pick the first (this
2967            // should never happen).
2968            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2969            if (procs == null) return null;
2970            final int N = procs.size();
2971            for (int i = 0; i < N; i++) {
2972                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2973            }
2974        }
2975        ProcessRecord proc = mProcessNames.get(processName, uid);
2976        if (false && proc != null && !keepIfLarge
2977                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2978                && proc.lastCachedPss >= 4000) {
2979            // Turn this condition on to cause killing to happen regularly, for testing.
2980            if (proc.baseProcessTracker != null) {
2981                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2982            }
2983            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2984        } else if (proc != null && !keepIfLarge
2985                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2986                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2987            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2988            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2989                if (proc.baseProcessTracker != null) {
2990                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2991                }
2992                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2993            }
2994        }
2995        return proc;
2996    }
2997
2998    void ensurePackageDexOpt(String packageName) {
2999        IPackageManager pm = AppGlobals.getPackageManager();
3000        try {
3001            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3002                mDidDexOpt = true;
3003            }
3004        } catch (RemoteException e) {
3005        }
3006    }
3007
3008    boolean isNextTransitionForward() {
3009        int transit = mWindowManager.getPendingAppTransition();
3010        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3011                || transit == AppTransition.TRANSIT_TASK_OPEN
3012                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3013    }
3014
3015    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3016            String processName, String abiOverride, int uid, Runnable crashHandler) {
3017        synchronized(this) {
3018            ApplicationInfo info = new ApplicationInfo();
3019            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3020            // For isolated processes, the former contains the parent's uid and the latter the
3021            // actual uid of the isolated process.
3022            // In the special case introduced by this method (which is, starting an isolated
3023            // process directly from the SystemServer without an actual parent app process) the
3024            // closest thing to a parent's uid is SYSTEM_UID.
3025            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3026            // the |isolated| logic in the ProcessRecord constructor.
3027            info.uid = Process.SYSTEM_UID;
3028            info.processName = processName;
3029            info.className = entryPoint;
3030            info.packageName = "android";
3031            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3032                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3033                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3034                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3035                    crashHandler);
3036            return proc != null ? proc.pid : 0;
3037        }
3038    }
3039
3040    final ProcessRecord startProcessLocked(String processName,
3041            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3042            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3043            boolean isolated, boolean keepIfLarge) {
3044        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3045                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3046                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3047                null /* crashHandler */);
3048    }
3049
3050    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3051            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3052            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3053            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3054        long startTime = SystemClock.elapsedRealtime();
3055        ProcessRecord app;
3056        if (!isolated) {
3057            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3058            checkTime(startTime, "startProcess: after getProcessRecord");
3059
3060            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3061                // If we are in the background, then check to see if this process
3062                // is bad.  If so, we will just silently fail.
3063                if (mBadProcesses.get(info.processName, info.uid) != null) {
3064                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3065                            + "/" + info.processName);
3066                    return null;
3067                }
3068            } else {
3069                // When the user is explicitly starting a process, then clear its
3070                // crash count so that we won't make it bad until they see at
3071                // least one crash dialog again, and make the process good again
3072                // if it had been bad.
3073                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3074                        + "/" + info.processName);
3075                mProcessCrashTimes.remove(info.processName, info.uid);
3076                if (mBadProcesses.get(info.processName, info.uid) != null) {
3077                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3078                            UserHandle.getUserId(info.uid), info.uid,
3079                            info.processName);
3080                    mBadProcesses.remove(info.processName, info.uid);
3081                    if (app != null) {
3082                        app.bad = false;
3083                    }
3084                }
3085            }
3086        } else {
3087            // If this is an isolated process, it can't re-use an existing process.
3088            app = null;
3089        }
3090
3091        // We don't have to do anything more if:
3092        // (1) There is an existing application record; and
3093        // (2) The caller doesn't think it is dead, OR there is no thread
3094        //     object attached to it so we know it couldn't have crashed; and
3095        // (3) There is a pid assigned to it, so it is either starting or
3096        //     already running.
3097        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3098                + " app=" + app + " knownToBeDead=" + knownToBeDead
3099                + " thread=" + (app != null ? app.thread : null)
3100                + " pid=" + (app != null ? app.pid : -1));
3101        if (app != null && app.pid > 0) {
3102            if (!knownToBeDead || app.thread == null) {
3103                // We already have the app running, or are waiting for it to
3104                // come up (we have a pid but not yet its thread), so keep it.
3105                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3106                // If this is a new package in the process, add the package to the list
3107                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3108                checkTime(startTime, "startProcess: done, added package to proc");
3109                return app;
3110            }
3111
3112            // An application record is attached to a previous process,
3113            // clean it up now.
3114            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3115            checkTime(startTime, "startProcess: bad proc running, killing");
3116            Process.killProcessGroup(app.info.uid, app.pid);
3117            handleAppDiedLocked(app, true, true);
3118            checkTime(startTime, "startProcess: done killing old proc");
3119        }
3120
3121        String hostingNameStr = hostingName != null
3122                ? hostingName.flattenToShortString() : null;
3123
3124        if (app == null) {
3125            checkTime(startTime, "startProcess: creating new process record");
3126            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3127            if (app == null) {
3128                Slog.w(TAG, "Failed making new process record for "
3129                        + processName + "/" + info.uid + " isolated=" + isolated);
3130                return null;
3131            }
3132            app.crashHandler = crashHandler;
3133            checkTime(startTime, "startProcess: done creating new process record");
3134        } else {
3135            // If this is a new package in the process, add the package to the list
3136            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3137            checkTime(startTime, "startProcess: added package to existing proc");
3138        }
3139
3140        // If the system is not ready yet, then hold off on starting this
3141        // process until it is.
3142        if (!mProcessesReady
3143                && !isAllowedWhileBooting(info)
3144                && !allowWhileBooting) {
3145            if (!mProcessesOnHold.contains(app)) {
3146                mProcessesOnHold.add(app);
3147            }
3148            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3149                    "System not ready, putting on hold: " + app);
3150            checkTime(startTime, "startProcess: returning with proc on hold");
3151            return app;
3152        }
3153
3154        checkTime(startTime, "startProcess: stepping in to startProcess");
3155        startProcessLocked(
3156                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3157        checkTime(startTime, "startProcess: done starting proc!");
3158        return (app.pid != 0) ? app : null;
3159    }
3160
3161    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3162        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3163    }
3164
3165    private final void startProcessLocked(ProcessRecord app,
3166            String hostingType, String hostingNameStr) {
3167        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3168                null /* entryPoint */, null /* entryPointArgs */);
3169    }
3170
3171    private final void startProcessLocked(ProcessRecord app, String hostingType,
3172            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3173        long startTime = SystemClock.elapsedRealtime();
3174        if (app.pid > 0 && app.pid != MY_PID) {
3175            checkTime(startTime, "startProcess: removing from pids map");
3176            synchronized (mPidsSelfLocked) {
3177                mPidsSelfLocked.remove(app.pid);
3178                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3179            }
3180            checkTime(startTime, "startProcess: done removing from pids map");
3181            app.setPid(0);
3182        }
3183
3184        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3185                "startProcessLocked removing on hold: " + app);
3186        mProcessesOnHold.remove(app);
3187
3188        checkTime(startTime, "startProcess: starting to update cpu stats");
3189        updateCpuStats();
3190        checkTime(startTime, "startProcess: done updating cpu stats");
3191
3192        try {
3193            try {
3194                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3195                    // This is caught below as if we had failed to fork zygote
3196                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3197                }
3198            } catch (RemoteException e) {
3199                throw e.rethrowAsRuntimeException();
3200            }
3201
3202            int uid = app.uid;
3203            int[] gids = null;
3204            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3205            if (!app.isolated) {
3206                int[] permGids = null;
3207                try {
3208                    checkTime(startTime, "startProcess: getting gids from package manager");
3209                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3210                            app.userId);
3211                } catch (RemoteException e) {
3212                    throw e.rethrowAsRuntimeException();
3213                }
3214
3215                /*
3216                 * Add shared application and profile GIDs so applications can share some
3217                 * resources like shared libraries and access user-wide resources
3218                 */
3219                if (ArrayUtils.isEmpty(permGids)) {
3220                    gids = new int[2];
3221                } else {
3222                    gids = new int[permGids.length + 2];
3223                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3224                }
3225                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3226                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3227            }
3228            checkTime(startTime, "startProcess: building args");
3229            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3230                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3231                        && mTopComponent != null
3232                        && app.processName.equals(mTopComponent.getPackageName())) {
3233                    uid = 0;
3234                }
3235                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3236                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3237                    uid = 0;
3238                }
3239            }
3240            int debugFlags = 0;
3241            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3242                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3243                // Also turn on CheckJNI for debuggable apps. It's quite
3244                // awkward to turn on otherwise.
3245                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3246            }
3247            // Run the app in safe mode if its manifest requests so or the
3248            // system is booted in safe mode.
3249            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3250                mSafeMode == true) {
3251                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3252            }
3253            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3254                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3255            }
3256            String jitDebugProperty = SystemProperties.get("debug.usejit");
3257            if ("true".equals(jitDebugProperty)) {
3258                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3259            } else if (!"false".equals(jitDebugProperty)) {
3260                // If we didn't force disable by setting false, defer to the dalvik vm options.
3261                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3262                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3263                }
3264            }
3265            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
3266            if ("true".equals(genCFIDebugProperty)) {
3267                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
3268            }
3269            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3270                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3271            }
3272            if ("1".equals(SystemProperties.get("debug.assert"))) {
3273                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3274            }
3275
3276            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3277            if (requiredAbi == null) {
3278                requiredAbi = Build.SUPPORTED_ABIS[0];
3279            }
3280
3281            String instructionSet = null;
3282            if (app.info.primaryCpuAbi != null) {
3283                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3284            }
3285
3286            app.gids = gids;
3287            app.requiredAbi = requiredAbi;
3288            app.instructionSet = instructionSet;
3289
3290            // Start the process.  It will either succeed and return a result containing
3291            // the PID of the new process, or else throw a RuntimeException.
3292            boolean isActivityProcess = (entryPoint == null);
3293            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3294            checkTime(startTime, "startProcess: asking zygote to start proc");
3295            Process.ProcessStartResult startResult = Process.start(entryPoint,
3296                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3297                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3298                    app.info.dataDir, entryPointArgs);
3299            checkTime(startTime, "startProcess: returned from zygote!");
3300
3301            if (app.isolated) {
3302                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3303            }
3304            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3305            checkTime(startTime, "startProcess: done updating battery stats");
3306
3307            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3308                    UserHandle.getUserId(uid), startResult.pid, uid,
3309                    app.processName, hostingType,
3310                    hostingNameStr != null ? hostingNameStr : "");
3311
3312            if (app.persistent) {
3313                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3314            }
3315
3316            checkTime(startTime, "startProcess: building log message");
3317            StringBuilder buf = mStringBuilder;
3318            buf.setLength(0);
3319            buf.append("Start proc ");
3320            buf.append(startResult.pid);
3321            buf.append(':');
3322            buf.append(app.processName);
3323            buf.append('/');
3324            UserHandle.formatUid(buf, uid);
3325            if (!isActivityProcess) {
3326                buf.append(" [");
3327                buf.append(entryPoint);
3328                buf.append("]");
3329            }
3330            buf.append(" for ");
3331            buf.append(hostingType);
3332            if (hostingNameStr != null) {
3333                buf.append(" ");
3334                buf.append(hostingNameStr);
3335            }
3336            Slog.i(TAG, buf.toString());
3337            app.setPid(startResult.pid);
3338            app.usingWrapper = startResult.usingWrapper;
3339            app.removed = false;
3340            app.killed = false;
3341            app.killedByAm = false;
3342            checkTime(startTime, "startProcess: starting to update pids map");
3343            synchronized (mPidsSelfLocked) {
3344                this.mPidsSelfLocked.put(startResult.pid, app);
3345                if (isActivityProcess) {
3346                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3347                    msg.obj = app;
3348                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3349                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3350                }
3351            }
3352            checkTime(startTime, "startProcess: done updating pids map");
3353        } catch (RuntimeException e) {
3354            // XXX do better error recovery.
3355            app.setPid(0);
3356            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3357            if (app.isolated) {
3358                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3359            }
3360            Slog.e(TAG, "Failure starting process " + app.processName, e);
3361        }
3362    }
3363
3364    void updateUsageStats(ActivityRecord component, boolean resumed) {
3365        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3366                "updateUsageStats: comp=" + component + "res=" + resumed);
3367        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3368        if (resumed) {
3369            if (mUsageStatsService != null) {
3370                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3371                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3372            }
3373            synchronized (stats) {
3374                stats.noteActivityResumedLocked(component.app.uid);
3375            }
3376        } else {
3377            if (mUsageStatsService != null) {
3378                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3379                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3380            }
3381            synchronized (stats) {
3382                stats.noteActivityPausedLocked(component.app.uid);
3383            }
3384        }
3385    }
3386
3387    Intent getHomeIntent() {
3388        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3389        intent.setComponent(mTopComponent);
3390        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3391            intent.addCategory(Intent.CATEGORY_HOME);
3392        }
3393        return intent;
3394    }
3395
3396    boolean startHomeActivityLocked(int userId, String reason) {
3397        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3398                && mTopAction == null) {
3399            // We are running in factory test mode, but unable to find
3400            // the factory test app, so just sit around displaying the
3401            // error message and don't try to start anything.
3402            return false;
3403        }
3404        Intent intent = getHomeIntent();
3405        ActivityInfo aInfo =
3406            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3407        if (aInfo != null) {
3408            intent.setComponent(new ComponentName(
3409                    aInfo.applicationInfo.packageName, aInfo.name));
3410            // Don't do this if the home app is currently being
3411            // instrumented.
3412            aInfo = new ActivityInfo(aInfo);
3413            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3414            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3415                    aInfo.applicationInfo.uid, true);
3416            if (app == null || app.instrumentationClass == null) {
3417                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3418                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3419            }
3420        }
3421
3422        return true;
3423    }
3424
3425    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3426        ActivityInfo ai = null;
3427        ComponentName comp = intent.getComponent();
3428        try {
3429            if (comp != null) {
3430                // Factory test.
3431                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3432            } else {
3433                ComponentName preferredComponent = mPreferredSetupActivities.get(userId);
3434                if (preferredComponent != null) {
3435                    ai = AppGlobals.getPackageManager().getActivityInfo(
3436                            preferredComponent, flags, userId);
3437                } else {
3438                    ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3439                            intent,
3440                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3441                                flags, userId);
3442
3443                    if (info != null) {
3444                        ai = info.activityInfo;
3445                    }
3446                }
3447            }
3448        } catch (RemoteException e) {
3449            // ignore
3450        }
3451
3452        return ai;
3453    }
3454
3455    /**
3456     * Starts the "new version setup screen" if appropriate.
3457     */
3458    void startSetupActivityLocked() {
3459        // Only do this once per boot.
3460        if (mCheckedForSetup) {
3461            return;
3462        }
3463
3464        // We will show this screen if the current one is a different
3465        // version than the last one shown, and we are not running in
3466        // low-level factory test mode.
3467        final ContentResolver resolver = mContext.getContentResolver();
3468        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3469                Settings.Global.getInt(resolver,
3470                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3471            mCheckedForSetup = true;
3472
3473            // See if we should be showing the platform update setup UI.
3474            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3475            List<ResolveInfo> ris = mContext.getPackageManager()
3476                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3477
3478            // We don't allow third party apps to replace this.
3479            ResolveInfo ri = null;
3480            for (int i=0; ris != null && i<ris.size(); i++) {
3481                if ((ris.get(i).activityInfo.applicationInfo.flags
3482                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3483                    ri = ris.get(i);
3484                    break;
3485                }
3486            }
3487
3488            if (ri != null) {
3489                String vers = ri.activityInfo.metaData != null
3490                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3491                        : null;
3492                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3493                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3494                            Intent.METADATA_SETUP_VERSION);
3495                }
3496                String lastVers = Settings.Secure.getString(
3497                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3498                if (vers != null && !vers.equals(lastVers)) {
3499                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3500                    intent.setComponent(new ComponentName(
3501                            ri.activityInfo.packageName, ri.activityInfo.name));
3502                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3503                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3504                            null);
3505                }
3506            }
3507        }
3508    }
3509
3510    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3511        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3512    }
3513
3514    void enforceNotIsolatedCaller(String caller) {
3515        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3516            throw new SecurityException("Isolated process not allowed to call " + caller);
3517        }
3518    }
3519
3520    void enforceShellRestriction(String restriction, int userHandle) {
3521        if (Binder.getCallingUid() == Process.SHELL_UID) {
3522            if (userHandle < 0
3523                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3524                throw new SecurityException("Shell does not have permission to access user "
3525                        + userHandle);
3526            }
3527        }
3528    }
3529
3530    @Override
3531    public int getFrontActivityScreenCompatMode() {
3532        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3533        synchronized (this) {
3534            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3535        }
3536    }
3537
3538    @Override
3539    public void setFrontActivityScreenCompatMode(int mode) {
3540        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3541                "setFrontActivityScreenCompatMode");
3542        synchronized (this) {
3543            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3544        }
3545    }
3546
3547    @Override
3548    public int getPackageScreenCompatMode(String packageName) {
3549        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3550        synchronized (this) {
3551            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3552        }
3553    }
3554
3555    @Override
3556    public void setPackageScreenCompatMode(String packageName, int mode) {
3557        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3558                "setPackageScreenCompatMode");
3559        synchronized (this) {
3560            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3561        }
3562    }
3563
3564    @Override
3565    public boolean getPackageAskScreenCompat(String packageName) {
3566        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3567        synchronized (this) {
3568            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3569        }
3570    }
3571
3572    @Override
3573    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3574        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3575                "setPackageAskScreenCompat");
3576        synchronized (this) {
3577            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3578        }
3579    }
3580
3581    @Override
3582    public int getPackageProcessState(String packageName) {
3583        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3584        synchronized (this) {
3585            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3586                final ProcessRecord proc = mLruProcesses.get(i);
3587                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3588                        || procState > proc.setProcState) {
3589                    boolean found = false;
3590                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3591                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3592                            procState = proc.setProcState;
3593                            found = true;
3594                        }
3595                    }
3596                    if (proc.pkgDeps != null && !found) {
3597                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3598                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3599                                procState = proc.setProcState;
3600                                break;
3601                            }
3602                        }
3603                    }
3604                }
3605            }
3606        }
3607        return procState;
3608    }
3609
3610    private void dispatchProcessesChanged() {
3611        int N;
3612        synchronized (this) {
3613            N = mPendingProcessChanges.size();
3614            if (mActiveProcessChanges.length < N) {
3615                mActiveProcessChanges = new ProcessChangeItem[N];
3616            }
3617            mPendingProcessChanges.toArray(mActiveProcessChanges);
3618            mPendingProcessChanges.clear();
3619            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3620                    "*** Delivering " + N + " process changes");
3621        }
3622
3623        int i = mProcessObservers.beginBroadcast();
3624        while (i > 0) {
3625            i--;
3626            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3627            if (observer != null) {
3628                try {
3629                    for (int j=0; j<N; j++) {
3630                        ProcessChangeItem item = mActiveProcessChanges[j];
3631                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3632                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3633                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3634                                    + item.uid + ": " + item.foregroundActivities);
3635                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3636                                    item.foregroundActivities);
3637                        }
3638                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3639                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3640                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3641                                    + ": " + item.processState);
3642                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3643                        }
3644                    }
3645                } catch (RemoteException e) {
3646                }
3647            }
3648        }
3649        mProcessObservers.finishBroadcast();
3650
3651        synchronized (this) {
3652            for (int j=0; j<N; j++) {
3653                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3654            }
3655        }
3656    }
3657
3658    private void dispatchProcessDied(int pid, int uid) {
3659        int i = mProcessObservers.beginBroadcast();
3660        while (i > 0) {
3661            i--;
3662            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3663            if (observer != null) {
3664                try {
3665                    observer.onProcessDied(pid, uid);
3666                } catch (RemoteException e) {
3667                }
3668            }
3669        }
3670        mProcessObservers.finishBroadcast();
3671    }
3672
3673    private void dispatchUidsChanged() {
3674        int N;
3675        synchronized (this) {
3676            N = mPendingUidChanges.size();
3677            if (mActiveUidChanges.length < N) {
3678                mActiveUidChanges = new UidRecord.ChangeItem[N];
3679            }
3680            for (int i=0; i<N; i++) {
3681                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3682                mActiveUidChanges[i] = change;
3683                change.uidRecord.pendingChange = null;
3684                change.uidRecord = null;
3685            }
3686            mPendingUidChanges.clear();
3687            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3688                    "*** Delivering " + N + " uid changes");
3689        }
3690
3691        if (mLocalPowerManager != null) {
3692            for (int j=0; j<N; j++) {
3693                UidRecord.ChangeItem item = mActiveUidChanges[j];
3694                if (item.gone) {
3695                    mLocalPowerManager.uidGone(item.uid);
3696                } else {
3697                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3698                }
3699            }
3700        }
3701
3702        int i = mUidObservers.beginBroadcast();
3703        while (i > 0) {
3704            i--;
3705            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3706            if (observer != null) {
3707                try {
3708                    for (int j=0; j<N; j++) {
3709                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3710                        if (item.gone) {
3711                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3712                                    "UID gone uid=" + item.uid);
3713                            observer.onUidGone(item.uid);
3714                        } else {
3715                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3716                                    "UID CHANGED uid=" + item.uid
3717                                    + ": " + item.processState);
3718                            observer.onUidStateChanged(item.uid, item.processState);
3719                        }
3720                    }
3721                } catch (RemoteException e) {
3722                }
3723            }
3724        }
3725        mUidObservers.finishBroadcast();
3726
3727        synchronized (this) {
3728            for (int j=0; j<N; j++) {
3729                mAvailUidChanges.add(mActiveUidChanges[j]);
3730            }
3731        }
3732    }
3733
3734    @Override
3735    public final int startActivity(IApplicationThread caller, String callingPackage,
3736            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3737            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3738        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3739            resultWho, requestCode, startFlags, profilerInfo, options,
3740            UserHandle.getCallingUserId());
3741    }
3742
3743    @Override
3744    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3745            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3746            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3747        enforceNotIsolatedCaller("startActivity");
3748        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3749                false, ALLOW_FULL_ONLY, "startActivity", null);
3750        // TODO: Switch to user app stacks here.
3751        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3752                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3753                profilerInfo, null, null, options, userId, null, null);
3754    }
3755
3756    @Override
3757    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3758            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3759            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3760
3761        // This is very dangerous -- it allows you to perform a start activity (including
3762        // permission grants) as any app that may launch one of your own activities.  So
3763        // we will only allow this to be done from activities that are part of the core framework,
3764        // and then only when they are running as the system.
3765        final ActivityRecord sourceRecord;
3766        final int targetUid;
3767        final String targetPackage;
3768        synchronized (this) {
3769            if (resultTo == null) {
3770                throw new SecurityException("Must be called from an activity");
3771            }
3772            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3773            if (sourceRecord == null) {
3774                throw new SecurityException("Called with bad activity token: " + resultTo);
3775            }
3776            if (!sourceRecord.info.packageName.equals("android")) {
3777                throw new SecurityException(
3778                        "Must be called from an activity that is declared in the android package");
3779            }
3780            if (sourceRecord.app == null) {
3781                throw new SecurityException("Called without a process attached to activity");
3782            }
3783            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3784                // This is still okay, as long as this activity is running under the
3785                // uid of the original calling activity.
3786                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3787                    throw new SecurityException(
3788                            "Calling activity in uid " + sourceRecord.app.uid
3789                                    + " must be system uid or original calling uid "
3790                                    + sourceRecord.launchedFromUid);
3791                }
3792            }
3793            targetUid = sourceRecord.launchedFromUid;
3794            targetPackage = sourceRecord.launchedFromPackage;
3795        }
3796
3797        if (userId == UserHandle.USER_NULL) {
3798            userId = UserHandle.getUserId(sourceRecord.app.uid);
3799        }
3800
3801        // TODO: Switch to user app stacks here.
3802        try {
3803            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3804                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3805                    null, null, options, userId, null, null);
3806            return ret;
3807        } catch (SecurityException e) {
3808            // XXX need to figure out how to propagate to original app.
3809            // A SecurityException here is generally actually a fault of the original
3810            // calling activity (such as a fairly granting permissions), so propagate it
3811            // back to them.
3812            /*
3813            StringBuilder msg = new StringBuilder();
3814            msg.append("While launching");
3815            msg.append(intent.toString());
3816            msg.append(": ");
3817            msg.append(e.getMessage());
3818            */
3819            throw e;
3820        }
3821    }
3822
3823    @Override
3824    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3825            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3826            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3827        enforceNotIsolatedCaller("startActivityAndWait");
3828        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3829                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3830        WaitResult res = new WaitResult();
3831        // TODO: Switch to user app stacks here.
3832        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3833                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3834                options, userId, null, null);
3835        return res;
3836    }
3837
3838    @Override
3839    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3840            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3841            int startFlags, Configuration config, Bundle options, int userId) {
3842        enforceNotIsolatedCaller("startActivityWithConfig");
3843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3844                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3845        // TODO: Switch to user app stacks here.
3846        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3847                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3848                null, null, config, options, userId, null, null);
3849        return ret;
3850    }
3851
3852    @Override
3853    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3854            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3855            int requestCode, int flagsMask, int flagsValues, Bundle options)
3856            throws TransactionTooLargeException {
3857        enforceNotIsolatedCaller("startActivityIntentSender");
3858        // Refuse possible leaked file descriptors
3859        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3860            throw new IllegalArgumentException("File descriptors passed in Intent");
3861        }
3862
3863        IIntentSender sender = intent.getTarget();
3864        if (!(sender instanceof PendingIntentRecord)) {
3865            throw new IllegalArgumentException("Bad PendingIntent object");
3866        }
3867
3868        PendingIntentRecord pir = (PendingIntentRecord)sender;
3869
3870        synchronized (this) {
3871            // If this is coming from the currently resumed activity, it is
3872            // effectively saying that app switches are allowed at this point.
3873            final ActivityStack stack = getFocusedStack();
3874            if (stack.mResumedActivity != null &&
3875                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3876                mAppSwitchesAllowedTime = 0;
3877            }
3878        }
3879        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3880                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3881        return ret;
3882    }
3883
3884    @Override
3885    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3886            Intent intent, String resolvedType, IVoiceInteractionSession session,
3887            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3888            Bundle options, int userId) {
3889        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3890                != PackageManager.PERMISSION_GRANTED) {
3891            String msg = "Permission Denial: startVoiceActivity() from pid="
3892                    + Binder.getCallingPid()
3893                    + ", uid=" + Binder.getCallingUid()
3894                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3895            Slog.w(TAG, msg);
3896            throw new SecurityException(msg);
3897        }
3898        if (session == null || interactor == null) {
3899            throw new NullPointerException("null session or interactor");
3900        }
3901        userId = handleIncomingUser(callingPid, callingUid, userId,
3902                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3903        // TODO: Switch to user app stacks here.
3904        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3905                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3906                null, options, userId, null, null);
3907    }
3908
3909    @Override
3910    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3911        synchronized (this) {
3912            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3913                if (keepAwake) {
3914                    mVoiceWakeLock.acquire();
3915                } else {
3916                    mVoiceWakeLock.release();
3917                }
3918            }
3919        }
3920    }
3921
3922    @Override
3923    public boolean startNextMatchingActivity(IBinder callingActivity,
3924            Intent intent, Bundle options) {
3925        // Refuse possible leaked file descriptors
3926        if (intent != null && intent.hasFileDescriptors() == true) {
3927            throw new IllegalArgumentException("File descriptors passed in Intent");
3928        }
3929
3930        synchronized (this) {
3931            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3932            if (r == null) {
3933                ActivityOptions.abort(options);
3934                return false;
3935            }
3936            if (r.app == null || r.app.thread == null) {
3937                // The caller is not running...  d'oh!
3938                ActivityOptions.abort(options);
3939                return false;
3940            }
3941            intent = new Intent(intent);
3942            // The caller is not allowed to change the data.
3943            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3944            // And we are resetting to find the next component...
3945            intent.setComponent(null);
3946
3947            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3948
3949            ActivityInfo aInfo = null;
3950            try {
3951                List<ResolveInfo> resolves =
3952                    AppGlobals.getPackageManager().queryIntentActivities(
3953                            intent, r.resolvedType,
3954                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3955                            UserHandle.getCallingUserId());
3956
3957                // Look for the original activity in the list...
3958                final int N = resolves != null ? resolves.size() : 0;
3959                for (int i=0; i<N; i++) {
3960                    ResolveInfo rInfo = resolves.get(i);
3961                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3962                            && rInfo.activityInfo.name.equals(r.info.name)) {
3963                        // We found the current one...  the next matching is
3964                        // after it.
3965                        i++;
3966                        if (i<N) {
3967                            aInfo = resolves.get(i).activityInfo;
3968                        }
3969                        if (debug) {
3970                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3971                                    + "/" + r.info.name);
3972                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3973                                    + "/" + aInfo.name);
3974                        }
3975                        break;
3976                    }
3977                }
3978            } catch (RemoteException e) {
3979            }
3980
3981            if (aInfo == null) {
3982                // Nobody who is next!
3983                ActivityOptions.abort(options);
3984                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3985                return false;
3986            }
3987
3988            intent.setComponent(new ComponentName(
3989                    aInfo.applicationInfo.packageName, aInfo.name));
3990            intent.setFlags(intent.getFlags()&~(
3991                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3992                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3993                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3994                    Intent.FLAG_ACTIVITY_NEW_TASK));
3995
3996            // Okay now we need to start the new activity, replacing the
3997            // currently running activity.  This is a little tricky because
3998            // we want to start the new one as if the current one is finished,
3999            // but not finish the current one first so that there is no flicker.
4000            // And thus...
4001            final boolean wasFinishing = r.finishing;
4002            r.finishing = true;
4003
4004            // Propagate reply information over to the new activity.
4005            final ActivityRecord resultTo = r.resultTo;
4006            final String resultWho = r.resultWho;
4007            final int requestCode = r.requestCode;
4008            r.resultTo = null;
4009            if (resultTo != null) {
4010                resultTo.removeResultsLocked(r, resultWho, requestCode);
4011            }
4012
4013            final long origId = Binder.clearCallingIdentity();
4014            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4015                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4016                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4017                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4018            Binder.restoreCallingIdentity(origId);
4019
4020            r.finishing = wasFinishing;
4021            if (res != ActivityManager.START_SUCCESS) {
4022                return false;
4023            }
4024            return true;
4025        }
4026    }
4027
4028    @Override
4029    public final int startActivityFromRecents(int taskId, Bundle options) {
4030        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4031            String msg = "Permission Denial: startActivityFromRecents called without " +
4032                    START_TASKS_FROM_RECENTS;
4033            Slog.w(TAG, msg);
4034            throw new SecurityException(msg);
4035        }
4036        return startActivityFromRecentsInner(taskId, options);
4037    }
4038
4039    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4040        final TaskRecord task;
4041        final int callingUid;
4042        final String callingPackage;
4043        final Intent intent;
4044        final int userId;
4045        synchronized (this) {
4046            task = mRecentTasks.taskForIdLocked(taskId);
4047            if (task == null) {
4048                throw new IllegalArgumentException("Task " + taskId + " not found.");
4049            }
4050            if (task.getRootActivity() != null) {
4051                moveTaskToFrontLocked(task.taskId, 0, null);
4052                return ActivityManager.START_TASK_TO_FRONT;
4053            }
4054            callingUid = task.mCallingUid;
4055            callingPackage = task.mCallingPackage;
4056            intent = task.intent;
4057            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4058            userId = task.userId;
4059        }
4060        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4061                options, userId, null, task);
4062    }
4063
4064    final int startActivityInPackage(int uid, String callingPackage,
4065            Intent intent, String resolvedType, IBinder resultTo,
4066            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4067            IActivityContainer container, TaskRecord inTask) {
4068
4069        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4070                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4071
4072        // TODO: Switch to user app stacks here.
4073        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4074                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4075                null, null, null, options, userId, container, inTask);
4076        return ret;
4077    }
4078
4079    @Override
4080    public final int startActivities(IApplicationThread caller, String callingPackage,
4081            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4082            int userId) {
4083        enforceNotIsolatedCaller("startActivities");
4084        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4085                false, ALLOW_FULL_ONLY, "startActivity", null);
4086        // TODO: Switch to user app stacks here.
4087        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4088                resolvedTypes, resultTo, options, userId);
4089        return ret;
4090    }
4091
4092    final int startActivitiesInPackage(int uid, String callingPackage,
4093            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4094            Bundle options, int userId) {
4095
4096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4097                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4098        // TODO: Switch to user app stacks here.
4099        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4100                resultTo, options, userId);
4101        return ret;
4102    }
4103
4104    @Override
4105    public void reportActivityFullyDrawn(IBinder token) {
4106        synchronized (this) {
4107            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4108            if (r == null) {
4109                return;
4110            }
4111            r.reportFullyDrawnLocked();
4112        }
4113    }
4114
4115    @Override
4116    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4117        synchronized (this) {
4118            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4119            if (r == null) {
4120                return;
4121            }
4122            if (r.task != null && r.task.mResizeable) {
4123                // Fixed screen orientation isn't supported with resizeable activities.
4124                return;
4125            }
4126            final long origId = Binder.clearCallingIdentity();
4127            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4128            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4129                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4130            if (config != null) {
4131                r.frozenBeforeDestroy = true;
4132                if (!updateConfigurationLocked(config, r, false, false)) {
4133                    mStackSupervisor.resumeTopActivitiesLocked();
4134                }
4135            }
4136            Binder.restoreCallingIdentity(origId);
4137        }
4138    }
4139
4140    @Override
4141    public int getRequestedOrientation(IBinder token) {
4142        synchronized (this) {
4143            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4144            if (r == null) {
4145                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4146            }
4147            return mWindowManager.getAppOrientation(r.appToken);
4148        }
4149    }
4150
4151    /**
4152     * This is the internal entry point for handling Activity.finish().
4153     *
4154     * @param token The Binder token referencing the Activity we want to finish.
4155     * @param resultCode Result code, if any, from this Activity.
4156     * @param resultData Result data (Intent), if any, from this Activity.
4157     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4158     *            the root Activity in the task.
4159     *
4160     * @return Returns true if the activity successfully finished, or false if it is still running.
4161     */
4162    @Override
4163    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4164            boolean finishTask) {
4165        // Refuse possible leaked file descriptors
4166        if (resultData != null && resultData.hasFileDescriptors() == true) {
4167            throw new IllegalArgumentException("File descriptors passed in Intent");
4168        }
4169
4170        synchronized(this) {
4171            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4172            if (r == null) {
4173                return true;
4174            }
4175            // Keep track of the root activity of the task before we finish it
4176            TaskRecord tr = r.task;
4177            ActivityRecord rootR = tr.getRootActivity();
4178            if (rootR == null) {
4179                Slog.w(TAG, "Finishing task with all activities already finished");
4180            }
4181            // Do not allow task to finish if last task in lockTask mode. Launchable apps can
4182            // finish themselves.
4183            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r &&
4184                    mStackSupervisor.isLastLockedTask(tr)) {
4185                Slog.i(TAG, "Not finishing task in lock task mode");
4186                mStackSupervisor.showLockTaskToast();
4187                return false;
4188            }
4189            if (mController != null) {
4190                // Find the first activity that is not finishing.
4191                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4192                if (next != null) {
4193                    // ask watcher if this is allowed
4194                    boolean resumeOK = true;
4195                    try {
4196                        resumeOK = mController.activityResuming(next.packageName);
4197                    } catch (RemoteException e) {
4198                        mController = null;
4199                        Watchdog.getInstance().setActivityController(null);
4200                    }
4201
4202                    if (!resumeOK) {
4203                        Slog.i(TAG, "Not finishing activity because controller resumed");
4204                        return false;
4205                    }
4206                }
4207            }
4208            final long origId = Binder.clearCallingIdentity();
4209            try {
4210                boolean res;
4211                if (finishTask && r == rootR) {
4212                    // If requested, remove the task that is associated to this activity only if it
4213                    // was the root activity in the task. The result code and data is ignored
4214                    // because we don't support returning them across task boundaries.
4215                    res = removeTaskByIdLocked(tr.taskId, false);
4216                    if (!res) {
4217                        Slog.i(TAG, "Removing task failed to finish activity");
4218                    }
4219                } else {
4220                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4221                            resultData, "app-request", true);
4222                    if (!res) {
4223                        Slog.i(TAG, "Failed to finish by app-request");
4224                    }
4225                }
4226                return res;
4227            } finally {
4228                Binder.restoreCallingIdentity(origId);
4229            }
4230        }
4231    }
4232
4233    @Override
4234    public final void finishHeavyWeightApp() {
4235        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4236                != PackageManager.PERMISSION_GRANTED) {
4237            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4238                    + Binder.getCallingPid()
4239                    + ", uid=" + Binder.getCallingUid()
4240                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4241            Slog.w(TAG, msg);
4242            throw new SecurityException(msg);
4243        }
4244
4245        synchronized(this) {
4246            if (mHeavyWeightProcess == null) {
4247                return;
4248            }
4249
4250            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4251            for (int i = 0; i < activities.size(); i++) {
4252                ActivityRecord r = activities.get(i);
4253                if (!r.finishing && r.isInStackLocked()) {
4254                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4255                            null, "finish-heavy", true);
4256                }
4257            }
4258
4259            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4260                    mHeavyWeightProcess.userId, 0));
4261            mHeavyWeightProcess = null;
4262        }
4263    }
4264
4265    @Override
4266    public void crashApplication(int uid, int initialPid, String packageName,
4267            String message) {
4268        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4269                != PackageManager.PERMISSION_GRANTED) {
4270            String msg = "Permission Denial: crashApplication() from pid="
4271                    + Binder.getCallingPid()
4272                    + ", uid=" + Binder.getCallingUid()
4273                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4274            Slog.w(TAG, msg);
4275            throw new SecurityException(msg);
4276        }
4277
4278        synchronized(this) {
4279            ProcessRecord proc = null;
4280
4281            // Figure out which process to kill.  We don't trust that initialPid
4282            // still has any relation to current pids, so must scan through the
4283            // list.
4284            synchronized (mPidsSelfLocked) {
4285                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4286                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4287                    if (p.uid != uid) {
4288                        continue;
4289                    }
4290                    if (p.pid == initialPid) {
4291                        proc = p;
4292                        break;
4293                    }
4294                    if (p.pkgList.containsKey(packageName)) {
4295                        proc = p;
4296                    }
4297                }
4298            }
4299
4300            if (proc == null) {
4301                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4302                        + " initialPid=" + initialPid
4303                        + " packageName=" + packageName);
4304                return;
4305            }
4306
4307            if (proc.thread != null) {
4308                if (proc.pid == Process.myPid()) {
4309                    Log.w(TAG, "crashApplication: trying to crash self!");
4310                    return;
4311                }
4312                long ident = Binder.clearCallingIdentity();
4313                try {
4314                    proc.thread.scheduleCrash(message);
4315                } catch (RemoteException e) {
4316                }
4317                Binder.restoreCallingIdentity(ident);
4318            }
4319        }
4320    }
4321
4322    @Override
4323    public final void finishSubActivity(IBinder token, String resultWho,
4324            int requestCode) {
4325        synchronized(this) {
4326            final long origId = Binder.clearCallingIdentity();
4327            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4328            if (r != null) {
4329                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4330            }
4331            Binder.restoreCallingIdentity(origId);
4332        }
4333    }
4334
4335    @Override
4336    public boolean finishActivityAffinity(IBinder token) {
4337        synchronized(this) {
4338            final long origId = Binder.clearCallingIdentity();
4339            try {
4340                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4341                if (r == null) {
4342                    return false;
4343                }
4344
4345                // Do not allow the last non-launchable task to finish in Lock Task mode.
4346                final TaskRecord task = r.task;
4347                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE &&
4348                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4349                    mStackSupervisor.showLockTaskToast();
4350                    return false;
4351                }
4352                return task.stack.finishActivityAffinityLocked(r);
4353            } finally {
4354                Binder.restoreCallingIdentity(origId);
4355            }
4356        }
4357    }
4358
4359    @Override
4360    public void finishVoiceTask(IVoiceInteractionSession session) {
4361        synchronized(this) {
4362            final long origId = Binder.clearCallingIdentity();
4363            try {
4364                mStackSupervisor.finishVoiceTask(session);
4365            } finally {
4366                Binder.restoreCallingIdentity(origId);
4367            }
4368        }
4369
4370    }
4371
4372    @Override
4373    public boolean releaseActivityInstance(IBinder token) {
4374        synchronized(this) {
4375            final long origId = Binder.clearCallingIdentity();
4376            try {
4377                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4378                if (r == null) {
4379                    return false;
4380                }
4381                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4382            } finally {
4383                Binder.restoreCallingIdentity(origId);
4384            }
4385        }
4386    }
4387
4388    @Override
4389    public void releaseSomeActivities(IApplicationThread appInt) {
4390        synchronized(this) {
4391            final long origId = Binder.clearCallingIdentity();
4392            try {
4393                ProcessRecord app = getRecordForAppLocked(appInt);
4394                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4395            } finally {
4396                Binder.restoreCallingIdentity(origId);
4397            }
4398        }
4399    }
4400
4401    @Override
4402    public boolean willActivityBeVisible(IBinder token) {
4403        synchronized(this) {
4404            ActivityStack stack = ActivityRecord.getStackLocked(token);
4405            if (stack != null) {
4406                return stack.willActivityBeVisibleLocked(token);
4407            }
4408            return false;
4409        }
4410    }
4411
4412    @Override
4413    public void overridePendingTransition(IBinder token, String packageName,
4414            int enterAnim, int exitAnim) {
4415        synchronized(this) {
4416            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4417            if (self == null) {
4418                return;
4419            }
4420
4421            final long origId = Binder.clearCallingIdentity();
4422
4423            if (self.state == ActivityState.RESUMED
4424                    || self.state == ActivityState.PAUSING) {
4425                mWindowManager.overridePendingAppTransition(packageName,
4426                        enterAnim, exitAnim, null);
4427            }
4428
4429            Binder.restoreCallingIdentity(origId);
4430        }
4431    }
4432
4433    /**
4434     * Main function for removing an existing process from the activity manager
4435     * as a result of that process going away.  Clears out all connections
4436     * to the process.
4437     */
4438    private final void handleAppDiedLocked(ProcessRecord app,
4439            boolean restarting, boolean allowRestart) {
4440        int pid = app.pid;
4441        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4442        if (!kept && !restarting) {
4443            removeLruProcessLocked(app);
4444            if (pid > 0) {
4445                ProcessList.remove(pid);
4446            }
4447        }
4448
4449        if (mProfileProc == app) {
4450            clearProfilerLocked();
4451        }
4452
4453        // Remove this application's activities from active lists.
4454        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4455
4456        app.activities.clear();
4457
4458        if (app.instrumentationClass != null) {
4459            Slog.w(TAG, "Crash of app " + app.processName
4460                  + " running instrumentation " + app.instrumentationClass);
4461            Bundle info = new Bundle();
4462            info.putString("shortMsg", "Process crashed.");
4463            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4464        }
4465
4466        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4467            // If there was nothing to resume, and we are not already
4468            // restarting this process, but there is a visible activity that
4469            // is hosted by the process...  then make sure all visible
4470            // activities are running, taking care of restarting this
4471            // process.
4472            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4473        }
4474    }
4475
4476    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4477        IBinder threadBinder = thread.asBinder();
4478        // Find the application record.
4479        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4480            ProcessRecord rec = mLruProcesses.get(i);
4481            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4482                return i;
4483            }
4484        }
4485        return -1;
4486    }
4487
4488    final ProcessRecord getRecordForAppLocked(
4489            IApplicationThread thread) {
4490        if (thread == null) {
4491            return null;
4492        }
4493
4494        int appIndex = getLRURecordIndexForAppLocked(thread);
4495        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4496    }
4497
4498    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4499        // If there are no longer any background processes running,
4500        // and the app that died was not running instrumentation,
4501        // then tell everyone we are now low on memory.
4502        boolean haveBg = false;
4503        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4504            ProcessRecord rec = mLruProcesses.get(i);
4505            if (rec.thread != null
4506                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4507                haveBg = true;
4508                break;
4509            }
4510        }
4511
4512        if (!haveBg) {
4513            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4514            if (doReport) {
4515                long now = SystemClock.uptimeMillis();
4516                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4517                    doReport = false;
4518                } else {
4519                    mLastMemUsageReportTime = now;
4520                }
4521            }
4522            final ArrayList<ProcessMemInfo> memInfos
4523                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4524            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4525            long now = SystemClock.uptimeMillis();
4526            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4527                ProcessRecord rec = mLruProcesses.get(i);
4528                if (rec == dyingProc || rec.thread == null) {
4529                    continue;
4530                }
4531                if (doReport) {
4532                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4533                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4534                }
4535                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4536                    // The low memory report is overriding any current
4537                    // state for a GC request.  Make sure to do
4538                    // heavy/important/visible/foreground processes first.
4539                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4540                        rec.lastRequestedGc = 0;
4541                    } else {
4542                        rec.lastRequestedGc = rec.lastLowMemory;
4543                    }
4544                    rec.reportLowMemory = true;
4545                    rec.lastLowMemory = now;
4546                    mProcessesToGc.remove(rec);
4547                    addProcessToGcListLocked(rec);
4548                }
4549            }
4550            if (doReport) {
4551                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4552                mHandler.sendMessage(msg);
4553            }
4554            scheduleAppGcsLocked();
4555        }
4556    }
4557
4558    final void appDiedLocked(ProcessRecord app) {
4559       appDiedLocked(app, app.pid, app.thread, false);
4560    }
4561
4562    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4563            boolean fromBinderDied) {
4564        // First check if this ProcessRecord is actually active for the pid.
4565        synchronized (mPidsSelfLocked) {
4566            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4567            if (curProc != app) {
4568                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4569                return;
4570            }
4571        }
4572
4573        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4574        synchronized (stats) {
4575            stats.noteProcessDiedLocked(app.info.uid, pid);
4576        }
4577
4578        if (!app.killed) {
4579            if (!fromBinderDied) {
4580                Process.killProcessQuiet(pid);
4581            }
4582            Process.killProcessGroup(app.info.uid, pid);
4583            app.killed = true;
4584        }
4585
4586        // Clean up already done if the process has been re-started.
4587        if (app.pid == pid && app.thread != null &&
4588                app.thread.asBinder() == thread.asBinder()) {
4589            boolean doLowMem = app.instrumentationClass == null;
4590            boolean doOomAdj = doLowMem;
4591            if (!app.killedByAm) {
4592                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4593                        + ") has died");
4594                mAllowLowerMemLevel = true;
4595            } else {
4596                // Note that we always want to do oom adj to update our state with the
4597                // new number of procs.
4598                mAllowLowerMemLevel = false;
4599                doLowMem = false;
4600            }
4601            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4602            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4603                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4604            handleAppDiedLocked(app, false, true);
4605
4606            if (doOomAdj) {
4607                updateOomAdjLocked();
4608            }
4609            if (doLowMem) {
4610                doLowMemReportIfNeededLocked(app);
4611            }
4612        } else if (app.pid != pid) {
4613            // A new process has already been started.
4614            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4615                    + ") has died and restarted (pid " + app.pid + ").");
4616            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4617        } else if (DEBUG_PROCESSES) {
4618            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4619                    + thread.asBinder());
4620        }
4621    }
4622
4623    /**
4624     * If a stack trace dump file is configured, dump process stack traces.
4625     * @param clearTraces causes the dump file to be erased prior to the new
4626     *    traces being written, if true; when false, the new traces will be
4627     *    appended to any existing file content.
4628     * @param firstPids of dalvik VM processes to dump stack traces for first
4629     * @param lastPids of dalvik VM processes to dump stack traces for last
4630     * @param nativeProcs optional list of native process names to dump stack crawls
4631     * @return file containing stack traces, or null if no dump file is configured
4632     */
4633    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4634            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4635        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4636        if (tracesPath == null || tracesPath.length() == 0) {
4637            return null;
4638        }
4639
4640        File tracesFile = new File(tracesPath);
4641        try {
4642            File tracesDir = tracesFile.getParentFile();
4643            if (!tracesDir.exists()) {
4644                tracesDir.mkdirs();
4645                if (!SELinux.restorecon(tracesDir)) {
4646                    return null;
4647                }
4648            }
4649            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4650
4651            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4652            tracesFile.createNewFile();
4653            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4654        } catch (IOException e) {
4655            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4656            return null;
4657        }
4658
4659        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4660        return tracesFile;
4661    }
4662
4663    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4664            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4665        // Use a FileObserver to detect when traces finish writing.
4666        // The order of traces is considered important to maintain for legibility.
4667        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4668            @Override
4669            public synchronized void onEvent(int event, String path) { notify(); }
4670        };
4671
4672        try {
4673            observer.startWatching();
4674
4675            // First collect all of the stacks of the most important pids.
4676            if (firstPids != null) {
4677                try {
4678                    int num = firstPids.size();
4679                    for (int i = 0; i < num; i++) {
4680                        synchronized (observer) {
4681                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4682                            observer.wait(200);  // Wait for write-close, give up after 200msec
4683                        }
4684                    }
4685                } catch (InterruptedException e) {
4686                    Slog.wtf(TAG, e);
4687                }
4688            }
4689
4690            // Next collect the stacks of the native pids
4691            if (nativeProcs != null) {
4692                int[] pids = Process.getPidsForCommands(nativeProcs);
4693                if (pids != null) {
4694                    for (int pid : pids) {
4695                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4696                    }
4697                }
4698            }
4699
4700            // Lastly, measure CPU usage.
4701            if (processCpuTracker != null) {
4702                processCpuTracker.init();
4703                System.gc();
4704                processCpuTracker.update();
4705                try {
4706                    synchronized (processCpuTracker) {
4707                        processCpuTracker.wait(500); // measure over 1/2 second.
4708                    }
4709                } catch (InterruptedException e) {
4710                }
4711                processCpuTracker.update();
4712
4713                // We'll take the stack crawls of just the top apps using CPU.
4714                final int N = processCpuTracker.countWorkingStats();
4715                int numProcs = 0;
4716                for (int i=0; i<N && numProcs<5; i++) {
4717                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4718                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4719                        numProcs++;
4720                        try {
4721                            synchronized (observer) {
4722                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4723                                observer.wait(200);  // Wait for write-close, give up after 200msec
4724                            }
4725                        } catch (InterruptedException e) {
4726                            Slog.wtf(TAG, e);
4727                        }
4728
4729                    }
4730                }
4731            }
4732        } finally {
4733            observer.stopWatching();
4734        }
4735    }
4736
4737    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4738        if (true || IS_USER_BUILD) {
4739            return;
4740        }
4741        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4742        if (tracesPath == null || tracesPath.length() == 0) {
4743            return;
4744        }
4745
4746        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4747        StrictMode.allowThreadDiskWrites();
4748        try {
4749            final File tracesFile = new File(tracesPath);
4750            final File tracesDir = tracesFile.getParentFile();
4751            final File tracesTmp = new File(tracesDir, "__tmp__");
4752            try {
4753                if (!tracesDir.exists()) {
4754                    tracesDir.mkdirs();
4755                    if (!SELinux.restorecon(tracesDir.getPath())) {
4756                        return;
4757                    }
4758                }
4759                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4760
4761                if (tracesFile.exists()) {
4762                    tracesTmp.delete();
4763                    tracesFile.renameTo(tracesTmp);
4764                }
4765                StringBuilder sb = new StringBuilder();
4766                Time tobj = new Time();
4767                tobj.set(System.currentTimeMillis());
4768                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4769                sb.append(": ");
4770                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4771                sb.append(" since ");
4772                sb.append(msg);
4773                FileOutputStream fos = new FileOutputStream(tracesFile);
4774                fos.write(sb.toString().getBytes());
4775                if (app == null) {
4776                    fos.write("\n*** No application process!".getBytes());
4777                }
4778                fos.close();
4779                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4780            } catch (IOException e) {
4781                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4782                return;
4783            }
4784
4785            if (app != null) {
4786                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4787                firstPids.add(app.pid);
4788                dumpStackTraces(tracesPath, firstPids, null, null, null);
4789            }
4790
4791            File lastTracesFile = null;
4792            File curTracesFile = null;
4793            for (int i=9; i>=0; i--) {
4794                String name = String.format(Locale.US, "slow%02d.txt", i);
4795                curTracesFile = new File(tracesDir, name);
4796                if (curTracesFile.exists()) {
4797                    if (lastTracesFile != null) {
4798                        curTracesFile.renameTo(lastTracesFile);
4799                    } else {
4800                        curTracesFile.delete();
4801                    }
4802                }
4803                lastTracesFile = curTracesFile;
4804            }
4805            tracesFile.renameTo(curTracesFile);
4806            if (tracesTmp.exists()) {
4807                tracesTmp.renameTo(tracesFile);
4808            }
4809        } finally {
4810            StrictMode.setThreadPolicy(oldPolicy);
4811        }
4812    }
4813
4814    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4815            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4816        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4817        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4818
4819        if (mController != null) {
4820            try {
4821                // 0 == continue, -1 = kill process immediately
4822                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4823                if (res < 0 && app.pid != MY_PID) {
4824                    app.kill("anr", true);
4825                }
4826            } catch (RemoteException e) {
4827                mController = null;
4828                Watchdog.getInstance().setActivityController(null);
4829            }
4830        }
4831
4832        long anrTime = SystemClock.uptimeMillis();
4833        if (MONITOR_CPU_USAGE) {
4834            updateCpuStatsNow();
4835        }
4836
4837        synchronized (this) {
4838            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4839            if (mShuttingDown) {
4840                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4841                return;
4842            } else if (app.notResponding) {
4843                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4844                return;
4845            } else if (app.crashing) {
4846                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4847                return;
4848            }
4849
4850            // In case we come through here for the same app before completing
4851            // this one, mark as anring now so we will bail out.
4852            app.notResponding = true;
4853
4854            // Log the ANR to the event log.
4855            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4856                    app.processName, app.info.flags, annotation);
4857
4858            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4859            firstPids.add(app.pid);
4860
4861            int parentPid = app.pid;
4862            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4863            if (parentPid != app.pid) firstPids.add(parentPid);
4864
4865            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4866
4867            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4868                ProcessRecord r = mLruProcesses.get(i);
4869                if (r != null && r.thread != null) {
4870                    int pid = r.pid;
4871                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4872                        if (r.persistent) {
4873                            firstPids.add(pid);
4874                        } else {
4875                            lastPids.put(pid, Boolean.TRUE);
4876                        }
4877                    }
4878                }
4879            }
4880        }
4881
4882        // Log the ANR to the main log.
4883        StringBuilder info = new StringBuilder();
4884        info.setLength(0);
4885        info.append("ANR in ").append(app.processName);
4886        if (activity != null && activity.shortComponentName != null) {
4887            info.append(" (").append(activity.shortComponentName).append(")");
4888        }
4889        info.append("\n");
4890        info.append("PID: ").append(app.pid).append("\n");
4891        if (annotation != null) {
4892            info.append("Reason: ").append(annotation).append("\n");
4893        }
4894        if (parent != null && parent != activity) {
4895            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4896        }
4897
4898        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4899
4900        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4901                NATIVE_STACKS_OF_INTEREST);
4902
4903        String cpuInfo = null;
4904        if (MONITOR_CPU_USAGE) {
4905            updateCpuStatsNow();
4906            synchronized (mProcessCpuTracker) {
4907                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4908            }
4909            info.append(processCpuTracker.printCurrentLoad());
4910            info.append(cpuInfo);
4911        }
4912
4913        info.append(processCpuTracker.printCurrentState(anrTime));
4914
4915        Slog.e(TAG, info.toString());
4916        if (tracesFile == null) {
4917            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4918            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4919        }
4920
4921        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4922                cpuInfo, tracesFile, null);
4923
4924        if (mController != null) {
4925            try {
4926                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4927                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4928                if (res != 0) {
4929                    if (res < 0 && app.pid != MY_PID) {
4930                        app.kill("anr", true);
4931                    } else {
4932                        synchronized (this) {
4933                            mServices.scheduleServiceTimeoutLocked(app);
4934                        }
4935                    }
4936                    return;
4937                }
4938            } catch (RemoteException e) {
4939                mController = null;
4940                Watchdog.getInstance().setActivityController(null);
4941            }
4942        }
4943
4944        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4945        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4946                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4947
4948        synchronized (this) {
4949            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4950
4951            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4952                app.kill("bg anr", true);
4953                return;
4954            }
4955
4956            // Set the app's notResponding state, and look up the errorReportReceiver
4957            makeAppNotRespondingLocked(app,
4958                    activity != null ? activity.shortComponentName : null,
4959                    annotation != null ? "ANR " + annotation : "ANR",
4960                    info.toString());
4961
4962            // Bring up the infamous App Not Responding dialog
4963            Message msg = Message.obtain();
4964            HashMap<String, Object> map = new HashMap<String, Object>();
4965            msg.what = SHOW_NOT_RESPONDING_MSG;
4966            msg.obj = map;
4967            msg.arg1 = aboveSystem ? 1 : 0;
4968            map.put("app", app);
4969            if (activity != null) {
4970                map.put("activity", activity);
4971            }
4972
4973            mUiHandler.sendMessage(msg);
4974        }
4975    }
4976
4977    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4978        if (!mLaunchWarningShown) {
4979            mLaunchWarningShown = true;
4980            mUiHandler.post(new Runnable() {
4981                @Override
4982                public void run() {
4983                    synchronized (ActivityManagerService.this) {
4984                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4985                        d.show();
4986                        mUiHandler.postDelayed(new Runnable() {
4987                            @Override
4988                            public void run() {
4989                                synchronized (ActivityManagerService.this) {
4990                                    d.dismiss();
4991                                    mLaunchWarningShown = false;
4992                                }
4993                            }
4994                        }, 4000);
4995                    }
4996                }
4997            });
4998        }
4999    }
5000
5001    @Override
5002    public boolean clearApplicationUserData(final String packageName,
5003            final IPackageDataObserver observer, int userId) {
5004        enforceNotIsolatedCaller("clearApplicationUserData");
5005        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5006            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5007        }
5008        int uid = Binder.getCallingUid();
5009        int pid = Binder.getCallingPid();
5010        userId = handleIncomingUser(pid, uid,
5011                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5012        long callingId = Binder.clearCallingIdentity();
5013        try {
5014            IPackageManager pm = AppGlobals.getPackageManager();
5015            int pkgUid = -1;
5016            synchronized(this) {
5017                try {
5018                    pkgUid = pm.getPackageUid(packageName, userId);
5019                } catch (RemoteException e) {
5020                }
5021                if (pkgUid == -1) {
5022                    Slog.w(TAG, "Invalid packageName: " + packageName);
5023                    if (observer != null) {
5024                        try {
5025                            observer.onRemoveCompleted(packageName, false);
5026                        } catch (RemoteException e) {
5027                            Slog.i(TAG, "Observer no longer exists.");
5028                        }
5029                    }
5030                    return false;
5031                }
5032                if (uid == pkgUid || checkComponentPermission(
5033                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5034                        pid, uid, -1, true)
5035                        == PackageManager.PERMISSION_GRANTED) {
5036                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5037                } else {
5038                    throw new SecurityException("PID " + pid + " does not have permission "
5039                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5040                                    + " of package " + packageName);
5041                }
5042
5043                // Remove all tasks match the cleared application package and user
5044                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5045                    final TaskRecord tr = mRecentTasks.get(i);
5046                    final String taskPackageName =
5047                            tr.getBaseIntent().getComponent().getPackageName();
5048                    if (tr.userId != userId) continue;
5049                    if (!taskPackageName.equals(packageName)) continue;
5050                    removeTaskByIdLocked(tr.taskId, false);
5051                }
5052            }
5053
5054            try {
5055                // Clear application user data
5056                pm.clearApplicationUserData(packageName, observer, userId);
5057
5058                synchronized(this) {
5059                    // Remove all permissions granted from/to this package
5060                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5061                }
5062
5063                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5064                        Uri.fromParts("package", packageName, null));
5065                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5066                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5067                        null, null, 0, null, null, null, false, false, userId);
5068            } catch (RemoteException e) {
5069            }
5070        } finally {
5071            Binder.restoreCallingIdentity(callingId);
5072        }
5073        return true;
5074    }
5075
5076    @Override
5077    public void killBackgroundProcesses(final String packageName, int userId) {
5078        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5079                != PackageManager.PERMISSION_GRANTED &&
5080                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5081                        != PackageManager.PERMISSION_GRANTED) {
5082            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5083                    + Binder.getCallingPid()
5084                    + ", uid=" + Binder.getCallingUid()
5085                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5086            Slog.w(TAG, msg);
5087            throw new SecurityException(msg);
5088        }
5089
5090        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5091                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5092        long callingId = Binder.clearCallingIdentity();
5093        try {
5094            IPackageManager pm = AppGlobals.getPackageManager();
5095            synchronized(this) {
5096                int appId = -1;
5097                try {
5098                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5099                } catch (RemoteException e) {
5100                }
5101                if (appId == -1) {
5102                    Slog.w(TAG, "Invalid packageName: " + packageName);
5103                    return;
5104                }
5105                killPackageProcessesLocked(packageName, appId, userId,
5106                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5107            }
5108        } finally {
5109            Binder.restoreCallingIdentity(callingId);
5110        }
5111    }
5112
5113    @Override
5114    public void killAllBackgroundProcesses() {
5115        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5116                != PackageManager.PERMISSION_GRANTED) {
5117            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5118                    + Binder.getCallingPid()
5119                    + ", uid=" + Binder.getCallingUid()
5120                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5121            Slog.w(TAG, msg);
5122            throw new SecurityException(msg);
5123        }
5124
5125        long callingId = Binder.clearCallingIdentity();
5126        try {
5127            synchronized(this) {
5128                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5129                final int NP = mProcessNames.getMap().size();
5130                for (int ip=0; ip<NP; ip++) {
5131                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5132                    final int NA = apps.size();
5133                    for (int ia=0; ia<NA; ia++) {
5134                        ProcessRecord app = apps.valueAt(ia);
5135                        if (app.persistent) {
5136                            // we don't kill persistent processes
5137                            continue;
5138                        }
5139                        if (app.removed) {
5140                            procs.add(app);
5141                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5142                            app.removed = true;
5143                            procs.add(app);
5144                        }
5145                    }
5146                }
5147
5148                int N = procs.size();
5149                for (int i=0; i<N; i++) {
5150                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5151                }
5152                mAllowLowerMemLevel = true;
5153                updateOomAdjLocked();
5154                doLowMemReportIfNeededLocked(null);
5155            }
5156        } finally {
5157            Binder.restoreCallingIdentity(callingId);
5158        }
5159    }
5160
5161    @Override
5162    public void forceStopPackage(final String packageName, int userId) {
5163        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5164                != PackageManager.PERMISSION_GRANTED) {
5165            String msg = "Permission Denial: forceStopPackage() from pid="
5166                    + Binder.getCallingPid()
5167                    + ", uid=" + Binder.getCallingUid()
5168                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5169            Slog.w(TAG, msg);
5170            throw new SecurityException(msg);
5171        }
5172        final int callingPid = Binder.getCallingPid();
5173        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5174                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5175        long callingId = Binder.clearCallingIdentity();
5176        try {
5177            IPackageManager pm = AppGlobals.getPackageManager();
5178            synchronized(this) {
5179                int[] users = userId == UserHandle.USER_ALL
5180                        ? getUsersLocked() : new int[] { userId };
5181                for (int user : users) {
5182                    int pkgUid = -1;
5183                    try {
5184                        pkgUid = pm.getPackageUid(packageName, user);
5185                    } catch (RemoteException e) {
5186                    }
5187                    if (pkgUid == -1) {
5188                        Slog.w(TAG, "Invalid packageName: " + packageName);
5189                        continue;
5190                    }
5191                    try {
5192                        pm.setPackageStoppedState(packageName, true, user);
5193                    } catch (RemoteException e) {
5194                    } catch (IllegalArgumentException e) {
5195                        Slog.w(TAG, "Failed trying to unstop package "
5196                                + packageName + ": " + e);
5197                    }
5198                    if (isUserRunningLocked(user, false)) {
5199                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5200                    }
5201                }
5202            }
5203        } finally {
5204            Binder.restoreCallingIdentity(callingId);
5205        }
5206    }
5207
5208    @Override
5209    public void addPackageDependency(String packageName) {
5210        synchronized (this) {
5211            int callingPid = Binder.getCallingPid();
5212            if (callingPid == Process.myPid()) {
5213                //  Yeah, um, no.
5214                return;
5215            }
5216            ProcessRecord proc;
5217            synchronized (mPidsSelfLocked) {
5218                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5219            }
5220            if (proc != null) {
5221                if (proc.pkgDeps == null) {
5222                    proc.pkgDeps = new ArraySet<String>(1);
5223                }
5224                proc.pkgDeps.add(packageName);
5225            }
5226        }
5227    }
5228
5229    /*
5230     * The pkg name and app id have to be specified.
5231     */
5232    @Override
5233    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5234        if (pkg == null) {
5235            return;
5236        }
5237        // Make sure the uid is valid.
5238        if (appid < 0) {
5239            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5240            return;
5241        }
5242        int callerUid = Binder.getCallingUid();
5243        // Only the system server can kill an application
5244        if (callerUid == Process.SYSTEM_UID) {
5245            // Post an aysnc message to kill the application
5246            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5247            msg.arg1 = appid;
5248            msg.arg2 = 0;
5249            Bundle bundle = new Bundle();
5250            bundle.putString("pkg", pkg);
5251            bundle.putString("reason", reason);
5252            msg.obj = bundle;
5253            mHandler.sendMessage(msg);
5254        } else {
5255            throw new SecurityException(callerUid + " cannot kill pkg: " +
5256                    pkg);
5257        }
5258    }
5259
5260    @Override
5261    public void closeSystemDialogs(String reason) {
5262        enforceNotIsolatedCaller("closeSystemDialogs");
5263
5264        final int pid = Binder.getCallingPid();
5265        final int uid = Binder.getCallingUid();
5266        final long origId = Binder.clearCallingIdentity();
5267        try {
5268            synchronized (this) {
5269                // Only allow this from foreground processes, so that background
5270                // applications can't abuse it to prevent system UI from being shown.
5271                if (uid >= Process.FIRST_APPLICATION_UID) {
5272                    ProcessRecord proc;
5273                    synchronized (mPidsSelfLocked) {
5274                        proc = mPidsSelfLocked.get(pid);
5275                    }
5276                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5277                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5278                                + " from background process " + proc);
5279                        return;
5280                    }
5281                }
5282                closeSystemDialogsLocked(reason);
5283            }
5284        } finally {
5285            Binder.restoreCallingIdentity(origId);
5286        }
5287    }
5288
5289    void closeSystemDialogsLocked(String reason) {
5290        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5291        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5292                | Intent.FLAG_RECEIVER_FOREGROUND);
5293        if (reason != null) {
5294            intent.putExtra("reason", reason);
5295        }
5296        mWindowManager.closeSystemDialogs(reason);
5297
5298        mStackSupervisor.closeSystemDialogsLocked();
5299
5300        broadcastIntentLocked(null, null, intent, null,
5301                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5302                Process.SYSTEM_UID, UserHandle.USER_ALL);
5303    }
5304
5305    @Override
5306    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5307        enforceNotIsolatedCaller("getProcessMemoryInfo");
5308        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5309        for (int i=pids.length-1; i>=0; i--) {
5310            ProcessRecord proc;
5311            int oomAdj;
5312            synchronized (this) {
5313                synchronized (mPidsSelfLocked) {
5314                    proc = mPidsSelfLocked.get(pids[i]);
5315                    oomAdj = proc != null ? proc.setAdj : 0;
5316                }
5317            }
5318            infos[i] = new Debug.MemoryInfo();
5319            Debug.getMemoryInfo(pids[i], infos[i]);
5320            if (proc != null) {
5321                synchronized (this) {
5322                    if (proc.thread != null && proc.setAdj == oomAdj) {
5323                        // Record this for posterity if the process has been stable.
5324                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5325                                infos[i].getTotalUss(), false, proc.pkgList);
5326                    }
5327                }
5328            }
5329        }
5330        return infos;
5331    }
5332
5333    @Override
5334    public long[] getProcessPss(int[] pids) {
5335        enforceNotIsolatedCaller("getProcessPss");
5336        long[] pss = new long[pids.length];
5337        for (int i=pids.length-1; i>=0; i--) {
5338            ProcessRecord proc;
5339            int oomAdj;
5340            synchronized (this) {
5341                synchronized (mPidsSelfLocked) {
5342                    proc = mPidsSelfLocked.get(pids[i]);
5343                    oomAdj = proc != null ? proc.setAdj : 0;
5344                }
5345            }
5346            long[] tmpUss = new long[1];
5347            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5348            if (proc != null) {
5349                synchronized (this) {
5350                    if (proc.thread != null && proc.setAdj == oomAdj) {
5351                        // Record this for posterity if the process has been stable.
5352                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5353                    }
5354                }
5355            }
5356        }
5357        return pss;
5358    }
5359
5360    @Override
5361    public void killApplicationProcess(String processName, int uid) {
5362        if (processName == null) {
5363            return;
5364        }
5365
5366        int callerUid = Binder.getCallingUid();
5367        // Only the system server can kill an application
5368        if (callerUid == Process.SYSTEM_UID) {
5369            synchronized (this) {
5370                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5371                if (app != null && app.thread != null) {
5372                    try {
5373                        app.thread.scheduleSuicide();
5374                    } catch (RemoteException e) {
5375                        // If the other end already died, then our work here is done.
5376                    }
5377                } else {
5378                    Slog.w(TAG, "Process/uid not found attempting kill of "
5379                            + processName + " / " + uid);
5380                }
5381            }
5382        } else {
5383            throw new SecurityException(callerUid + " cannot kill app process: " +
5384                    processName);
5385        }
5386    }
5387
5388    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5389        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5390                false, true, false, false, UserHandle.getUserId(uid), reason);
5391        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5392                Uri.fromParts("package", packageName, null));
5393        if (!mProcessesReady) {
5394            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5395                    | Intent.FLAG_RECEIVER_FOREGROUND);
5396        }
5397        intent.putExtra(Intent.EXTRA_UID, uid);
5398        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5399        broadcastIntentLocked(null, null, intent,
5400                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5401                false, false,
5402                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5403    }
5404
5405    private void forceStopUserLocked(int userId, String reason) {
5406        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5407        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5408        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5409                | Intent.FLAG_RECEIVER_FOREGROUND);
5410        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5411        broadcastIntentLocked(null, null, intent,
5412                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5413                false, false,
5414                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5415    }
5416
5417    private final boolean killPackageProcessesLocked(String packageName, int appId,
5418            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5419            boolean doit, boolean evenPersistent, String reason) {
5420        ArrayList<ProcessRecord> procs = new ArrayList<>();
5421
5422        // Remove all processes this package may have touched: all with the
5423        // same UID (except for the system or root user), and all whose name
5424        // matches the package name.
5425        final int NP = mProcessNames.getMap().size();
5426        for (int ip=0; ip<NP; ip++) {
5427            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5428            final int NA = apps.size();
5429            for (int ia=0; ia<NA; ia++) {
5430                ProcessRecord app = apps.valueAt(ia);
5431                if (app.persistent && !evenPersistent) {
5432                    // we don't kill persistent processes
5433                    continue;
5434                }
5435                if (app.removed) {
5436                    if (doit) {
5437                        procs.add(app);
5438                    }
5439                    continue;
5440                }
5441
5442                // Skip process if it doesn't meet our oom adj requirement.
5443                if (app.setAdj < minOomAdj) {
5444                    continue;
5445                }
5446
5447                // If no package is specified, we call all processes under the
5448                // give user id.
5449                if (packageName == null) {
5450                    if (app.userId != userId) {
5451                        continue;
5452                    }
5453                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5454                        continue;
5455                    }
5456                // Package has been specified, we want to hit all processes
5457                // that match it.  We need to qualify this by the processes
5458                // that are running under the specified app and user ID.
5459                } else {
5460                    final boolean isDep = app.pkgDeps != null
5461                            && app.pkgDeps.contains(packageName);
5462                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5463                        continue;
5464                    }
5465                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5466                        continue;
5467                    }
5468                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5469                        continue;
5470                    }
5471                }
5472
5473                // Process has passed all conditions, kill it!
5474                if (!doit) {
5475                    return true;
5476                }
5477                app.removed = true;
5478                procs.add(app);
5479            }
5480        }
5481
5482        int N = procs.size();
5483        for (int i=0; i<N; i++) {
5484            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5485        }
5486        updateOomAdjLocked();
5487        return N > 0;
5488    }
5489
5490    private void cleanupDisabledPackageComponentsLocked(
5491            String packageName, int userId, String[] changedClasses) {
5492
5493        Set<String> disabledClasses = null;
5494        boolean packageDisabled = false;
5495        IPackageManager pm = AppGlobals.getPackageManager();
5496
5497        if (changedClasses == null) {
5498            // Nothing changed...
5499            return;
5500        }
5501
5502        // Determine enable/disable state of the package and its components.
5503        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5504        for (int i = changedClasses.length - 1; i >= 0; i--) {
5505            final String changedClass = changedClasses[i];
5506
5507            if (changedClass.equals(packageName)) {
5508                try {
5509                    // Entire package setting changed
5510                    enabled = pm.getApplicationEnabledSetting(packageName,
5511                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5512                } catch (RemoteException e) {
5513                    // Can't happen...
5514                }
5515                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5516                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5517                if (packageDisabled) {
5518                    // Entire package is disabled.
5519                    // No need to continue to check component states.
5520                    disabledClasses = null;
5521                    break;
5522                }
5523            } else {
5524                try {
5525                    enabled = pm.getComponentEnabledSetting(
5526                            new ComponentName(packageName, changedClass),
5527                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5528                } catch (RemoteException e) {
5529                    // Can't happen...
5530                }
5531                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5532                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5533                    if (disabledClasses == null) {
5534                        disabledClasses = new ArraySet<>(changedClasses.length);
5535                    }
5536                    disabledClasses.add(changedClass);
5537                }
5538            }
5539        }
5540
5541        if (!packageDisabled && disabledClasses == null) {
5542            // Nothing to do here...
5543            return;
5544        }
5545
5546        // Clean-up disabled activities.
5547        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5548                packageName, disabledClasses, true, false, userId) && mBooted) {
5549            mStackSupervisor.resumeTopActivitiesLocked();
5550            mStackSupervisor.scheduleIdleLocked();
5551        }
5552
5553        // Clean-up disabled tasks
5554        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5555
5556        // Clean-up disabled services.
5557        mServices.bringDownDisabledPackageServicesLocked(
5558                packageName, disabledClasses, userId, false, true);
5559
5560        // Clean-up disabled providers.
5561        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5562        mProviderMap.collectPackageProvidersLocked(
5563                packageName, disabledClasses, true, false, userId, providers);
5564        for (int i = providers.size() - 1; i >= 0; i--) {
5565            removeDyingProviderLocked(null, providers.get(i), true);
5566        }
5567
5568        // Clean-up disabled broadcast receivers.
5569        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5570            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5571                    packageName, disabledClasses, userId, true);
5572        }
5573
5574    }
5575
5576    private final boolean forceStopPackageLocked(String packageName, int appId,
5577            boolean callerWillRestart, boolean purgeCache, boolean doit,
5578            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5579        int i;
5580
5581        if (userId == UserHandle.USER_ALL && packageName == null) {
5582            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5583        }
5584
5585        if (appId < 0 && packageName != null) {
5586            try {
5587                appId = UserHandle.getAppId(
5588                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5589            } catch (RemoteException e) {
5590            }
5591        }
5592
5593        if (doit) {
5594            if (packageName != null) {
5595                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5596                        + " user=" + userId + ": " + reason);
5597            } else {
5598                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5599            }
5600
5601            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5602            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5603                SparseArray<Long> ba = pmap.valueAt(ip);
5604                for (i = ba.size() - 1; i >= 0; i--) {
5605                    boolean remove = false;
5606                    final int entUid = ba.keyAt(i);
5607                    if (packageName != null) {
5608                        if (userId == UserHandle.USER_ALL) {
5609                            if (UserHandle.getAppId(entUid) == appId) {
5610                                remove = true;
5611                            }
5612                        } else {
5613                            if (entUid == UserHandle.getUid(userId, appId)) {
5614                                remove = true;
5615                            }
5616                        }
5617                    } else if (UserHandle.getUserId(entUid) == userId) {
5618                        remove = true;
5619                    }
5620                    if (remove) {
5621                        ba.removeAt(i);
5622                    }
5623                }
5624                if (ba.size() == 0) {
5625                    pmap.removeAt(ip);
5626                }
5627            }
5628        }
5629
5630        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5631                -100, callerWillRestart, true, doit, evenPersistent,
5632                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5633
5634        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5635                packageName, null, doit, evenPersistent, userId)) {
5636            if (!doit) {
5637                return true;
5638            }
5639            didSomething = true;
5640        }
5641
5642        if (mServices.bringDownDisabledPackageServicesLocked(
5643                packageName, null, userId, evenPersistent, doit)) {
5644            if (!doit) {
5645                return true;
5646            }
5647            didSomething = true;
5648        }
5649
5650        if (packageName == null) {
5651            // Remove all sticky broadcasts from this user.
5652            mStickyBroadcasts.remove(userId);
5653        }
5654
5655        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5656        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5657                userId, providers)) {
5658            if (!doit) {
5659                return true;
5660            }
5661            didSomething = true;
5662        }
5663        for (i = providers.size() - 1; i >= 0; i--) {
5664            removeDyingProviderLocked(null, providers.get(i), true);
5665        }
5666
5667        // Remove transient permissions granted from/to this package/user
5668        removeUriPermissionsForPackageLocked(packageName, userId, false);
5669
5670        if (doit) {
5671            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5672                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5673                        packageName, null, userId, doit);
5674            }
5675        }
5676
5677        if (packageName == null || uninstalling) {
5678            // Remove pending intents.  For now we only do this when force
5679            // stopping users, because we have some problems when doing this
5680            // for packages -- app widgets are not currently cleaned up for
5681            // such packages, so they can be left with bad pending intents.
5682            if (mIntentSenderRecords.size() > 0) {
5683                Iterator<WeakReference<PendingIntentRecord>> it
5684                        = mIntentSenderRecords.values().iterator();
5685                while (it.hasNext()) {
5686                    WeakReference<PendingIntentRecord> wpir = it.next();
5687                    if (wpir == null) {
5688                        it.remove();
5689                        continue;
5690                    }
5691                    PendingIntentRecord pir = wpir.get();
5692                    if (pir == null) {
5693                        it.remove();
5694                        continue;
5695                    }
5696                    if (packageName == null) {
5697                        // Stopping user, remove all objects for the user.
5698                        if (pir.key.userId != userId) {
5699                            // Not the same user, skip it.
5700                            continue;
5701                        }
5702                    } else {
5703                        if (UserHandle.getAppId(pir.uid) != appId) {
5704                            // Different app id, skip it.
5705                            continue;
5706                        }
5707                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5708                            // Different user, skip it.
5709                            continue;
5710                        }
5711                        if (!pir.key.packageName.equals(packageName)) {
5712                            // Different package, skip it.
5713                            continue;
5714                        }
5715                    }
5716                    if (!doit) {
5717                        return true;
5718                    }
5719                    didSomething = true;
5720                    it.remove();
5721                    pir.canceled = true;
5722                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5723                        pir.key.activity.pendingResults.remove(pir.ref);
5724                    }
5725                }
5726            }
5727        }
5728
5729        if (doit) {
5730            if (purgeCache && packageName != null) {
5731                AttributeCache ac = AttributeCache.instance();
5732                if (ac != null) {
5733                    ac.removePackage(packageName);
5734                }
5735            }
5736            if (mBooted) {
5737                mStackSupervisor.resumeTopActivitiesLocked();
5738                mStackSupervisor.scheduleIdleLocked();
5739            }
5740        }
5741
5742        return didSomething;
5743    }
5744
5745    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5746        ProcessRecord old = mProcessNames.remove(name, uid);
5747        if (old != null) {
5748            old.uidRecord.numProcs--;
5749            if (old.uidRecord.numProcs == 0) {
5750                // No more processes using this uid, tell clients it is gone.
5751                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5752                        "No more processes in " + old.uidRecord);
5753                enqueueUidChangeLocked(old.uidRecord, true);
5754                mActiveUids.remove(uid);
5755            }
5756            old.uidRecord = null;
5757        }
5758        mIsolatedProcesses.remove(uid);
5759        return old;
5760    }
5761
5762    private final void addProcessNameLocked(ProcessRecord proc) {
5763        // We shouldn't already have a process under this name, but just in case we
5764        // need to clean up whatever may be there now.
5765        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5766        if (old != null) {
5767            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5768        }
5769        UidRecord uidRec = mActiveUids.get(proc.uid);
5770        if (uidRec == null) {
5771            uidRec = new UidRecord(proc.uid);
5772            // This is the first appearance of the uid, report it now!
5773            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5774                    "Creating new process uid: " + uidRec);
5775            mActiveUids.put(proc.uid, uidRec);
5776            enqueueUidChangeLocked(uidRec, false);
5777        }
5778        proc.uidRecord = uidRec;
5779        uidRec.numProcs++;
5780        mProcessNames.put(proc.processName, proc.uid, proc);
5781        if (proc.isolated) {
5782            mIsolatedProcesses.put(proc.uid, proc);
5783        }
5784    }
5785
5786    private final boolean removeProcessLocked(ProcessRecord app,
5787            boolean callerWillRestart, boolean allowRestart, String reason) {
5788        final String name = app.processName;
5789        final int uid = app.uid;
5790        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5791            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5792
5793        removeProcessNameLocked(name, uid);
5794        if (mHeavyWeightProcess == app) {
5795            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5796                    mHeavyWeightProcess.userId, 0));
5797            mHeavyWeightProcess = null;
5798        }
5799        boolean needRestart = false;
5800        if (app.pid > 0 && app.pid != MY_PID) {
5801            int pid = app.pid;
5802            synchronized (mPidsSelfLocked) {
5803                mPidsSelfLocked.remove(pid);
5804                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5805            }
5806            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5807            if (app.isolated) {
5808                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5809            }
5810            boolean willRestart = false;
5811            if (app.persistent && !app.isolated) {
5812                if (!callerWillRestart) {
5813                    willRestart = true;
5814                } else {
5815                    needRestart = true;
5816                }
5817            }
5818            app.kill(reason, true);
5819            handleAppDiedLocked(app, willRestart, allowRestart);
5820            if (willRestart) {
5821                removeLruProcessLocked(app);
5822                addAppLocked(app.info, false, null /* ABI override */);
5823            }
5824        } else {
5825            mRemovedProcesses.add(app);
5826        }
5827
5828        return needRestart;
5829    }
5830
5831    private final void processStartTimedOutLocked(ProcessRecord app) {
5832        final int pid = app.pid;
5833        boolean gone = false;
5834        synchronized (mPidsSelfLocked) {
5835            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5836            if (knownApp != null && knownApp.thread == null) {
5837                mPidsSelfLocked.remove(pid);
5838                gone = true;
5839            }
5840        }
5841
5842        if (gone) {
5843            Slog.w(TAG, "Process " + app + " failed to attach");
5844            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5845                    pid, app.uid, app.processName);
5846            removeProcessNameLocked(app.processName, app.uid);
5847            if (mHeavyWeightProcess == app) {
5848                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5849                        mHeavyWeightProcess.userId, 0));
5850                mHeavyWeightProcess = null;
5851            }
5852            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5853            if (app.isolated) {
5854                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5855            }
5856            // Take care of any launching providers waiting for this process.
5857            checkAppInLaunchingProvidersLocked(app, true);
5858            // Take care of any services that are waiting for the process.
5859            mServices.processStartTimedOutLocked(app);
5860            app.kill("start timeout", true);
5861            removeLruProcessLocked(app);
5862            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5863                Slog.w(TAG, "Unattached app died before backup, skipping");
5864                try {
5865                    IBackupManager bm = IBackupManager.Stub.asInterface(
5866                            ServiceManager.getService(Context.BACKUP_SERVICE));
5867                    bm.agentDisconnected(app.info.packageName);
5868                } catch (RemoteException e) {
5869                    // Can't happen; the backup manager is local
5870                }
5871            }
5872            if (isPendingBroadcastProcessLocked(pid)) {
5873                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5874                skipPendingBroadcastLocked(pid);
5875            }
5876        } else {
5877            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5878        }
5879    }
5880
5881    private final boolean attachApplicationLocked(IApplicationThread thread,
5882            int pid) {
5883
5884        // Find the application record that is being attached...  either via
5885        // the pid if we are running in multiple processes, or just pull the
5886        // next app record if we are emulating process with anonymous threads.
5887        ProcessRecord app;
5888        if (pid != MY_PID && pid >= 0) {
5889            synchronized (mPidsSelfLocked) {
5890                app = mPidsSelfLocked.get(pid);
5891            }
5892        } else {
5893            app = null;
5894        }
5895
5896        if (app == null) {
5897            Slog.w(TAG, "No pending application record for pid " + pid
5898                    + " (IApplicationThread " + thread + "); dropping process");
5899            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5900            if (pid > 0 && pid != MY_PID) {
5901                Process.killProcessQuiet(pid);
5902                //TODO: Process.killProcessGroup(app.info.uid, pid);
5903            } else {
5904                try {
5905                    thread.scheduleExit();
5906                } catch (Exception e) {
5907                    // Ignore exceptions.
5908                }
5909            }
5910            return false;
5911        }
5912
5913        // If this application record is still attached to a previous
5914        // process, clean it up now.
5915        if (app.thread != null) {
5916            handleAppDiedLocked(app, true, true);
5917        }
5918
5919        // Tell the process all about itself.
5920
5921        if (DEBUG_ALL) Slog.v(
5922                TAG, "Binding process pid " + pid + " to record " + app);
5923
5924        final String processName = app.processName;
5925        try {
5926            AppDeathRecipient adr = new AppDeathRecipient(
5927                    app, pid, thread);
5928            thread.asBinder().linkToDeath(adr, 0);
5929            app.deathRecipient = adr;
5930        } catch (RemoteException e) {
5931            app.resetPackageList(mProcessStats);
5932            startProcessLocked(app, "link fail", processName);
5933            return false;
5934        }
5935
5936        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5937
5938        app.makeActive(thread, mProcessStats);
5939        app.curAdj = app.setAdj = -100;
5940        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5941        app.forcingToForeground = null;
5942        updateProcessForegroundLocked(app, false, false);
5943        app.hasShownUi = false;
5944        app.debugging = false;
5945        app.cached = false;
5946        app.killedByAm = false;
5947
5948        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5949
5950        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5951        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5952
5953        if (!normalMode) {
5954            Slog.i(TAG, "Launching preboot mode app: " + app);
5955        }
5956
5957        if (DEBUG_ALL) Slog.v(
5958            TAG, "New app record " + app
5959            + " thread=" + thread.asBinder() + " pid=" + pid);
5960        try {
5961            int testMode = IApplicationThread.DEBUG_OFF;
5962            if (mDebugApp != null && mDebugApp.equals(processName)) {
5963                testMode = mWaitForDebugger
5964                    ? IApplicationThread.DEBUG_WAIT
5965                    : IApplicationThread.DEBUG_ON;
5966                app.debugging = true;
5967                if (mDebugTransient) {
5968                    mDebugApp = mOrigDebugApp;
5969                    mWaitForDebugger = mOrigWaitForDebugger;
5970                }
5971            }
5972            String profileFile = app.instrumentationProfileFile;
5973            ParcelFileDescriptor profileFd = null;
5974            int samplingInterval = 0;
5975            boolean profileAutoStop = false;
5976            if (mProfileApp != null && mProfileApp.equals(processName)) {
5977                mProfileProc = app;
5978                profileFile = mProfileFile;
5979                profileFd = mProfileFd;
5980                samplingInterval = mSamplingInterval;
5981                profileAutoStop = mAutoStopProfiler;
5982            }
5983            boolean enableOpenGlTrace = false;
5984            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5985                enableOpenGlTrace = true;
5986                mOpenGlTraceApp = null;
5987            }
5988
5989            // If the app is being launched for restore or full backup, set it up specially
5990            boolean isRestrictedBackupMode = false;
5991            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5992                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5993                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5994                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5995            }
5996
5997            ensurePackageDexOpt(app.instrumentationInfo != null
5998                    ? app.instrumentationInfo.packageName
5999                    : app.info.packageName);
6000            if (app.instrumentationClass != null) {
6001                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6002            }
6003            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6004                    + processName + " with config " + mConfiguration);
6005            ApplicationInfo appInfo = app.instrumentationInfo != null
6006                    ? app.instrumentationInfo : app.info;
6007            app.compat = compatibilityInfoForPackageLocked(appInfo);
6008            if (profileFd != null) {
6009                profileFd = profileFd.dup();
6010            }
6011            ProfilerInfo profilerInfo = profileFile == null ? null
6012                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6013            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6014                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6015                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6016                    isRestrictedBackupMode || !normalMode, app.persistent,
6017                    new Configuration(mConfiguration), app.compat,
6018                    getCommonServicesLocked(app.isolated),
6019                    mCoreSettingsObserver.getCoreSettingsLocked());
6020            updateLruProcessLocked(app, false, null);
6021            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6022        } catch (Exception e) {
6023            // todo: Yikes!  What should we do?  For now we will try to
6024            // start another process, but that could easily get us in
6025            // an infinite loop of restarting processes...
6026            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6027
6028            app.resetPackageList(mProcessStats);
6029            app.unlinkDeathRecipient();
6030            startProcessLocked(app, "bind fail", processName);
6031            return false;
6032        }
6033
6034        // Remove this record from the list of starting applications.
6035        mPersistentStartingProcesses.remove(app);
6036        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6037                "Attach application locked removing on hold: " + app);
6038        mProcessesOnHold.remove(app);
6039
6040        boolean badApp = false;
6041        boolean didSomething = false;
6042
6043        // See if the top visible activity is waiting to run in this process...
6044        if (normalMode) {
6045            try {
6046                if (mStackSupervisor.attachApplicationLocked(app)) {
6047                    didSomething = true;
6048                }
6049            } catch (Exception e) {
6050                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6051                badApp = true;
6052            }
6053        }
6054
6055        // Find any services that should be running in this process...
6056        if (!badApp) {
6057            try {
6058                didSomething |= mServices.attachApplicationLocked(app, processName);
6059            } catch (Exception e) {
6060                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6061                badApp = true;
6062            }
6063        }
6064
6065        // Check if a next-broadcast receiver is in this process...
6066        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6067            try {
6068                didSomething |= sendPendingBroadcastsLocked(app);
6069            } catch (Exception e) {
6070                // If the app died trying to launch the receiver we declare it 'bad'
6071                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6072                badApp = true;
6073            }
6074        }
6075
6076        // Check whether the next backup agent is in this process...
6077        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6078            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6079                    "New app is backup target, launching agent for " + app);
6080            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6081            try {
6082                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6083                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6084                        mBackupTarget.backupMode);
6085            } catch (Exception e) {
6086                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6087                badApp = true;
6088            }
6089        }
6090
6091        if (badApp) {
6092            app.kill("error during init", true);
6093            handleAppDiedLocked(app, false, true);
6094            return false;
6095        }
6096
6097        if (!didSomething) {
6098            updateOomAdjLocked();
6099        }
6100
6101        return true;
6102    }
6103
6104    @Override
6105    public final void attachApplication(IApplicationThread thread) {
6106        synchronized (this) {
6107            int callingPid = Binder.getCallingPid();
6108            final long origId = Binder.clearCallingIdentity();
6109            attachApplicationLocked(thread, callingPid);
6110            Binder.restoreCallingIdentity(origId);
6111        }
6112    }
6113
6114    @Override
6115    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6116        final long origId = Binder.clearCallingIdentity();
6117        synchronized (this) {
6118            ActivityStack stack = ActivityRecord.getStackLocked(token);
6119            if (stack != null) {
6120                ActivityRecord r =
6121                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6122                if (stopProfiling) {
6123                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6124                        try {
6125                            mProfileFd.close();
6126                        } catch (IOException e) {
6127                        }
6128                        clearProfilerLocked();
6129                    }
6130                }
6131            }
6132        }
6133        Binder.restoreCallingIdentity(origId);
6134    }
6135
6136    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6137        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6138                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6139    }
6140
6141    void enableScreenAfterBoot() {
6142        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6143                SystemClock.uptimeMillis());
6144        mWindowManager.enableScreenAfterBoot();
6145
6146        synchronized (this) {
6147            updateEventDispatchingLocked();
6148        }
6149    }
6150
6151    @Override
6152    public void showBootMessage(final CharSequence msg, final boolean always) {
6153        if (Binder.getCallingUid() != Process.myUid()) {
6154            // These days only the core system can call this, so apps can't get in
6155            // the way of what we show about running them.
6156        }
6157        mWindowManager.showBootMessage(msg, always);
6158    }
6159
6160    @Override
6161    public void keyguardWaitingForActivityDrawn() {
6162        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6163        final long token = Binder.clearCallingIdentity();
6164        try {
6165            synchronized (this) {
6166                if (DEBUG_LOCKSCREEN) logLockScreen("");
6167                mWindowManager.keyguardWaitingForActivityDrawn();
6168                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6169                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6170                    updateSleepIfNeededLocked();
6171                }
6172            }
6173        } finally {
6174            Binder.restoreCallingIdentity(token);
6175        }
6176    }
6177
6178    @Override
6179    public void keyguardGoingAway(boolean disableWindowAnimations,
6180            boolean keyguardGoingToNotificationShade) {
6181        enforceNotIsolatedCaller("keyguardGoingAway");
6182        final long token = Binder.clearCallingIdentity();
6183        try {
6184            synchronized (this) {
6185                if (DEBUG_LOCKSCREEN) logLockScreen("");
6186                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6187                        keyguardGoingToNotificationShade);
6188                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6189                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6190                    updateSleepIfNeededLocked();
6191                }
6192            }
6193        } finally {
6194            Binder.restoreCallingIdentity(token);
6195        }
6196    }
6197
6198    final void finishBooting() {
6199        synchronized (this) {
6200            if (!mBootAnimationComplete) {
6201                mCallFinishBooting = true;
6202                return;
6203            }
6204            mCallFinishBooting = false;
6205        }
6206
6207        ArraySet<String> completedIsas = new ArraySet<String>();
6208        for (String abi : Build.SUPPORTED_ABIS) {
6209            Process.establishZygoteConnectionForAbi(abi);
6210            final String instructionSet = VMRuntime.getInstructionSet(abi);
6211            if (!completedIsas.contains(instructionSet)) {
6212                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6213                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6214                }
6215                completedIsas.add(instructionSet);
6216            }
6217        }
6218
6219        IntentFilter pkgFilter = new IntentFilter();
6220        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6221        pkgFilter.addDataScheme("package");
6222        mContext.registerReceiver(new BroadcastReceiver() {
6223            @Override
6224            public void onReceive(Context context, Intent intent) {
6225                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6226                if (pkgs != null) {
6227                    for (String pkg : pkgs) {
6228                        synchronized (ActivityManagerService.this) {
6229                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6230                                    0, "query restart")) {
6231                                setResultCode(Activity.RESULT_OK);
6232                                return;
6233                            }
6234                        }
6235                    }
6236                }
6237            }
6238        }, pkgFilter);
6239
6240        IntentFilter dumpheapFilter = new IntentFilter();
6241        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6242        mContext.registerReceiver(new BroadcastReceiver() {
6243            @Override
6244            public void onReceive(Context context, Intent intent) {
6245                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6246                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6247                } else {
6248                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6249                }
6250            }
6251        }, dumpheapFilter);
6252
6253        // Let system services know.
6254        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6255
6256        synchronized (this) {
6257            // Ensure that any processes we had put on hold are now started
6258            // up.
6259            final int NP = mProcessesOnHold.size();
6260            if (NP > 0) {
6261                ArrayList<ProcessRecord> procs =
6262                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6263                for (int ip=0; ip<NP; ip++) {
6264                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6265                            + procs.get(ip));
6266                    startProcessLocked(procs.get(ip), "on-hold", null);
6267                }
6268            }
6269
6270            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6271                // Start looking for apps that are abusing wake locks.
6272                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6273                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6274                // Tell anyone interested that we are done booting!
6275                SystemProperties.set("sys.boot_completed", "1");
6276
6277                // And trigger dev.bootcomplete if we are not showing encryption progress
6278                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6279                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6280                    SystemProperties.set("dev.bootcomplete", "1");
6281                }
6282                for (int i=0; i<mStartedUsers.size(); i++) {
6283                    UserStartedState uss = mStartedUsers.valueAt(i);
6284                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6285                        uss.mState = UserStartedState.STATE_RUNNING;
6286                        final int userId = mStartedUsers.keyAt(i);
6287                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6288                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6289                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6290                        broadcastIntentLocked(null, null, intent, null,
6291                                new IIntentReceiver.Stub() {
6292                                    @Override
6293                                    public void performReceive(Intent intent, int resultCode,
6294                                            String data, Bundle extras, boolean ordered,
6295                                            boolean sticky, int sendingUser) {
6296                                        synchronized (ActivityManagerService.this) {
6297                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6298                                                    true, false);
6299                                        }
6300                                    }
6301                                },
6302                                0, null, null,
6303                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6304                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6305                                userId);
6306                    }
6307                }
6308                scheduleStartProfilesLocked();
6309            }
6310        }
6311    }
6312
6313    @Override
6314    public void bootAnimationComplete() {
6315        final boolean callFinishBooting;
6316        synchronized (this) {
6317            callFinishBooting = mCallFinishBooting;
6318            mBootAnimationComplete = true;
6319        }
6320        if (callFinishBooting) {
6321            finishBooting();
6322        }
6323    }
6324
6325    final void ensureBootCompleted() {
6326        boolean booting;
6327        boolean enableScreen;
6328        synchronized (this) {
6329            booting = mBooting;
6330            mBooting = false;
6331            enableScreen = !mBooted;
6332            mBooted = true;
6333        }
6334
6335        if (booting) {
6336            finishBooting();
6337        }
6338
6339        if (enableScreen) {
6340            enableScreenAfterBoot();
6341        }
6342    }
6343
6344    @Override
6345    public final void activityResumed(IBinder token) {
6346        final long origId = Binder.clearCallingIdentity();
6347        synchronized(this) {
6348            ActivityStack stack = ActivityRecord.getStackLocked(token);
6349            if (stack != null) {
6350                ActivityRecord.activityResumedLocked(token);
6351            }
6352        }
6353        Binder.restoreCallingIdentity(origId);
6354    }
6355
6356    @Override
6357    public final void activityPaused(IBinder token) {
6358        final long origId = Binder.clearCallingIdentity();
6359        synchronized(this) {
6360            ActivityStack stack = ActivityRecord.getStackLocked(token);
6361            if (stack != null) {
6362                stack.activityPausedLocked(token, false);
6363            }
6364        }
6365        Binder.restoreCallingIdentity(origId);
6366    }
6367
6368    @Override
6369    public final void activityStopped(IBinder token, Bundle icicle,
6370            PersistableBundle persistentState, CharSequence description) {
6371        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6372
6373        // Refuse possible leaked file descriptors
6374        if (icicle != null && icicle.hasFileDescriptors()) {
6375            throw new IllegalArgumentException("File descriptors passed in Bundle");
6376        }
6377
6378        final long origId = Binder.clearCallingIdentity();
6379
6380        synchronized (this) {
6381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6382            if (r != null) {
6383                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6384            }
6385        }
6386
6387        trimApplications();
6388
6389        Binder.restoreCallingIdentity(origId);
6390    }
6391
6392    @Override
6393    public final void activityDestroyed(IBinder token) {
6394        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6395        synchronized (this) {
6396            ActivityStack stack = ActivityRecord.getStackLocked(token);
6397            if (stack != null) {
6398                stack.activityDestroyedLocked(token, "activityDestroyed");
6399            }
6400        }
6401    }
6402
6403    @Override
6404    public final void backgroundResourcesReleased(IBinder token) {
6405        final long origId = Binder.clearCallingIdentity();
6406        try {
6407            synchronized (this) {
6408                ActivityStack stack = ActivityRecord.getStackLocked(token);
6409                if (stack != null) {
6410                    stack.backgroundResourcesReleased();
6411                }
6412            }
6413        } finally {
6414            Binder.restoreCallingIdentity(origId);
6415        }
6416    }
6417
6418    @Override
6419    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6420        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6421    }
6422
6423    @Override
6424    public final void notifyEnterAnimationComplete(IBinder token) {
6425        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6426    }
6427
6428    @Override
6429    public String getCallingPackage(IBinder token) {
6430        synchronized (this) {
6431            ActivityRecord r = getCallingRecordLocked(token);
6432            return r != null ? r.info.packageName : null;
6433        }
6434    }
6435
6436    @Override
6437    public ComponentName getCallingActivity(IBinder token) {
6438        synchronized (this) {
6439            ActivityRecord r = getCallingRecordLocked(token);
6440            return r != null ? r.intent.getComponent() : null;
6441        }
6442    }
6443
6444    private ActivityRecord getCallingRecordLocked(IBinder token) {
6445        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6446        if (r == null) {
6447            return null;
6448        }
6449        return r.resultTo;
6450    }
6451
6452    @Override
6453    public ComponentName getActivityClassForToken(IBinder token) {
6454        synchronized(this) {
6455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6456            if (r == null) {
6457                return null;
6458            }
6459            return r.intent.getComponent();
6460        }
6461    }
6462
6463    @Override
6464    public String getPackageForToken(IBinder token) {
6465        synchronized(this) {
6466            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6467            if (r == null) {
6468                return null;
6469            }
6470            return r.packageName;
6471        }
6472    }
6473
6474    @Override
6475    public IIntentSender getIntentSender(int type,
6476            String packageName, IBinder token, String resultWho,
6477            int requestCode, Intent[] intents, String[] resolvedTypes,
6478            int flags, Bundle options, int userId) {
6479        enforceNotIsolatedCaller("getIntentSender");
6480        // Refuse possible leaked file descriptors
6481        if (intents != null) {
6482            if (intents.length < 1) {
6483                throw new IllegalArgumentException("Intents array length must be >= 1");
6484            }
6485            for (int i=0; i<intents.length; i++) {
6486                Intent intent = intents[i];
6487                if (intent != null) {
6488                    if (intent.hasFileDescriptors()) {
6489                        throw new IllegalArgumentException("File descriptors passed in Intent");
6490                    }
6491                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6492                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6493                        throw new IllegalArgumentException(
6494                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6495                    }
6496                    intents[i] = new Intent(intent);
6497                }
6498            }
6499            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6500                throw new IllegalArgumentException(
6501                        "Intent array length does not match resolvedTypes length");
6502            }
6503        }
6504        if (options != null) {
6505            if (options.hasFileDescriptors()) {
6506                throw new IllegalArgumentException("File descriptors passed in options");
6507            }
6508        }
6509
6510        synchronized(this) {
6511            int callingUid = Binder.getCallingUid();
6512            int origUserId = userId;
6513            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6514                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6515                    ALLOW_NON_FULL, "getIntentSender", null);
6516            if (origUserId == UserHandle.USER_CURRENT) {
6517                // We don't want to evaluate this until the pending intent is
6518                // actually executed.  However, we do want to always do the
6519                // security checking for it above.
6520                userId = UserHandle.USER_CURRENT;
6521            }
6522            try {
6523                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6524                    int uid = AppGlobals.getPackageManager()
6525                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6526                    if (!UserHandle.isSameApp(callingUid, uid)) {
6527                        String msg = "Permission Denial: getIntentSender() from pid="
6528                            + Binder.getCallingPid()
6529                            + ", uid=" + Binder.getCallingUid()
6530                            + ", (need uid=" + uid + ")"
6531                            + " is not allowed to send as package " + packageName;
6532                        Slog.w(TAG, msg);
6533                        throw new SecurityException(msg);
6534                    }
6535                }
6536
6537                return getIntentSenderLocked(type, packageName, callingUid, userId,
6538                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6539
6540            } catch (RemoteException e) {
6541                throw new SecurityException(e);
6542            }
6543        }
6544    }
6545
6546    IIntentSender getIntentSenderLocked(int type, String packageName,
6547            int callingUid, int userId, IBinder token, String resultWho,
6548            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6549            Bundle options) {
6550        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6551        ActivityRecord activity = null;
6552        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6553            activity = ActivityRecord.isInStackLocked(token);
6554            if (activity == null) {
6555                return null;
6556            }
6557            if (activity.finishing) {
6558                return null;
6559            }
6560        }
6561
6562        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6563        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6564        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6565        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6566                |PendingIntent.FLAG_UPDATE_CURRENT);
6567
6568        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6569                type, packageName, activity, resultWho,
6570                requestCode, intents, resolvedTypes, flags, options, userId);
6571        WeakReference<PendingIntentRecord> ref;
6572        ref = mIntentSenderRecords.get(key);
6573        PendingIntentRecord rec = ref != null ? ref.get() : null;
6574        if (rec != null) {
6575            if (!cancelCurrent) {
6576                if (updateCurrent) {
6577                    if (rec.key.requestIntent != null) {
6578                        rec.key.requestIntent.replaceExtras(intents != null ?
6579                                intents[intents.length - 1] : null);
6580                    }
6581                    if (intents != null) {
6582                        intents[intents.length-1] = rec.key.requestIntent;
6583                        rec.key.allIntents = intents;
6584                        rec.key.allResolvedTypes = resolvedTypes;
6585                    } else {
6586                        rec.key.allIntents = null;
6587                        rec.key.allResolvedTypes = null;
6588                    }
6589                }
6590                return rec;
6591            }
6592            rec.canceled = true;
6593            mIntentSenderRecords.remove(key);
6594        }
6595        if (noCreate) {
6596            return rec;
6597        }
6598        rec = new PendingIntentRecord(this, key, callingUid);
6599        mIntentSenderRecords.put(key, rec.ref);
6600        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6601            if (activity.pendingResults == null) {
6602                activity.pendingResults
6603                        = new HashSet<WeakReference<PendingIntentRecord>>();
6604            }
6605            activity.pendingResults.add(rec.ref);
6606        }
6607        return rec;
6608    }
6609
6610    @Override
6611    public void cancelIntentSender(IIntentSender sender) {
6612        if (!(sender instanceof PendingIntentRecord)) {
6613            return;
6614        }
6615        synchronized(this) {
6616            PendingIntentRecord rec = (PendingIntentRecord)sender;
6617            try {
6618                int uid = AppGlobals.getPackageManager()
6619                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6620                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6621                    String msg = "Permission Denial: cancelIntentSender() from pid="
6622                        + Binder.getCallingPid()
6623                        + ", uid=" + Binder.getCallingUid()
6624                        + " is not allowed to cancel packges "
6625                        + rec.key.packageName;
6626                    Slog.w(TAG, msg);
6627                    throw new SecurityException(msg);
6628                }
6629            } catch (RemoteException e) {
6630                throw new SecurityException(e);
6631            }
6632            cancelIntentSenderLocked(rec, true);
6633        }
6634    }
6635
6636    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6637        rec.canceled = true;
6638        mIntentSenderRecords.remove(rec.key);
6639        if (cleanActivity && rec.key.activity != null) {
6640            rec.key.activity.pendingResults.remove(rec.ref);
6641        }
6642    }
6643
6644    @Override
6645    public String getPackageForIntentSender(IIntentSender pendingResult) {
6646        if (!(pendingResult instanceof PendingIntentRecord)) {
6647            return null;
6648        }
6649        try {
6650            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6651            return res.key.packageName;
6652        } catch (ClassCastException e) {
6653        }
6654        return null;
6655    }
6656
6657    @Override
6658    public int getUidForIntentSender(IIntentSender sender) {
6659        if (sender instanceof PendingIntentRecord) {
6660            try {
6661                PendingIntentRecord res = (PendingIntentRecord)sender;
6662                return res.uid;
6663            } catch (ClassCastException e) {
6664            }
6665        }
6666        return -1;
6667    }
6668
6669    @Override
6670    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6671        if (!(pendingResult instanceof PendingIntentRecord)) {
6672            return false;
6673        }
6674        try {
6675            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6676            if (res.key.allIntents == null) {
6677                return false;
6678            }
6679            for (int i=0; i<res.key.allIntents.length; i++) {
6680                Intent intent = res.key.allIntents[i];
6681                if (intent.getPackage() != null && intent.getComponent() != null) {
6682                    return false;
6683                }
6684            }
6685            return true;
6686        } catch (ClassCastException e) {
6687        }
6688        return false;
6689    }
6690
6691    @Override
6692    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6693        if (!(pendingResult instanceof PendingIntentRecord)) {
6694            return false;
6695        }
6696        try {
6697            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6698            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6699                return true;
6700            }
6701            return false;
6702        } catch (ClassCastException e) {
6703        }
6704        return false;
6705    }
6706
6707    @Override
6708    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6709        if (!(pendingResult instanceof PendingIntentRecord)) {
6710            return null;
6711        }
6712        try {
6713            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6714            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6715        } catch (ClassCastException e) {
6716        }
6717        return null;
6718    }
6719
6720    @Override
6721    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6722        if (!(pendingResult instanceof PendingIntentRecord)) {
6723            return null;
6724        }
6725        try {
6726            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6727            synchronized (this) {
6728                return getTagForIntentSenderLocked(res, prefix);
6729            }
6730        } catch (ClassCastException e) {
6731        }
6732        return null;
6733    }
6734
6735    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6736        final Intent intent = res.key.requestIntent;
6737        if (intent != null) {
6738            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6739                    || res.lastTagPrefix.equals(prefix))) {
6740                return res.lastTag;
6741            }
6742            res.lastTagPrefix = prefix;
6743            final StringBuilder sb = new StringBuilder(128);
6744            if (prefix != null) {
6745                sb.append(prefix);
6746            }
6747            if (intent.getAction() != null) {
6748                sb.append(intent.getAction());
6749            } else if (intent.getComponent() != null) {
6750                intent.getComponent().appendShortString(sb);
6751            } else {
6752                sb.append("?");
6753            }
6754            return res.lastTag = sb.toString();
6755        }
6756        return null;
6757    }
6758
6759    @Override
6760    public void setProcessLimit(int max) {
6761        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6762                "setProcessLimit()");
6763        synchronized (this) {
6764            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6765            mProcessLimitOverride = max;
6766        }
6767        trimApplications();
6768    }
6769
6770    @Override
6771    public int getProcessLimit() {
6772        synchronized (this) {
6773            return mProcessLimitOverride;
6774        }
6775    }
6776
6777    void foregroundTokenDied(ForegroundToken token) {
6778        synchronized (ActivityManagerService.this) {
6779            synchronized (mPidsSelfLocked) {
6780                ForegroundToken cur
6781                    = mForegroundProcesses.get(token.pid);
6782                if (cur != token) {
6783                    return;
6784                }
6785                mForegroundProcesses.remove(token.pid);
6786                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6787                if (pr == null) {
6788                    return;
6789                }
6790                pr.forcingToForeground = null;
6791                updateProcessForegroundLocked(pr, false, false);
6792            }
6793            updateOomAdjLocked();
6794        }
6795    }
6796
6797    @Override
6798    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6799        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6800                "setProcessForeground()");
6801        synchronized(this) {
6802            boolean changed = false;
6803
6804            synchronized (mPidsSelfLocked) {
6805                ProcessRecord pr = mPidsSelfLocked.get(pid);
6806                if (pr == null && isForeground) {
6807                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6808                    return;
6809                }
6810                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6811                if (oldToken != null) {
6812                    oldToken.token.unlinkToDeath(oldToken, 0);
6813                    mForegroundProcesses.remove(pid);
6814                    if (pr != null) {
6815                        pr.forcingToForeground = null;
6816                    }
6817                    changed = true;
6818                }
6819                if (isForeground && token != null) {
6820                    ForegroundToken newToken = new ForegroundToken() {
6821                        @Override
6822                        public void binderDied() {
6823                            foregroundTokenDied(this);
6824                        }
6825                    };
6826                    newToken.pid = pid;
6827                    newToken.token = token;
6828                    try {
6829                        token.linkToDeath(newToken, 0);
6830                        mForegroundProcesses.put(pid, newToken);
6831                        pr.forcingToForeground = token;
6832                        changed = true;
6833                    } catch (RemoteException e) {
6834                        // If the process died while doing this, we will later
6835                        // do the cleanup with the process death link.
6836                    }
6837                }
6838            }
6839
6840            if (changed) {
6841                updateOomAdjLocked();
6842            }
6843        }
6844    }
6845
6846    // =========================================================
6847    // PROCESS INFO
6848    // =========================================================
6849
6850    static class ProcessInfoService extends IProcessInfoService.Stub {
6851        final ActivityManagerService mActivityManagerService;
6852        ProcessInfoService(ActivityManagerService activityManagerService) {
6853            mActivityManagerService = activityManagerService;
6854        }
6855
6856        @Override
6857        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6858            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6859        }
6860    }
6861
6862    /**
6863     * For each PID in the given input array, write the current process state
6864     * for that process into the output array, or -1 to indicate that no
6865     * process with the given PID exists.
6866     */
6867    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6868        if (pids == null) {
6869            throw new NullPointerException("pids");
6870        } else if (states == null) {
6871            throw new NullPointerException("states");
6872        } else if (pids.length != states.length) {
6873            throw new IllegalArgumentException("input and output arrays have different lengths!");
6874        }
6875
6876        synchronized (mPidsSelfLocked) {
6877            for (int i = 0; i < pids.length; i++) {
6878                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6879                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6880                        pr.curProcState;
6881            }
6882        }
6883    }
6884
6885    // =========================================================
6886    // PERMISSIONS
6887    // =========================================================
6888
6889    static class PermissionController extends IPermissionController.Stub {
6890        ActivityManagerService mActivityManagerService;
6891        PermissionController(ActivityManagerService activityManagerService) {
6892            mActivityManagerService = activityManagerService;
6893        }
6894
6895        @Override
6896        public boolean checkPermission(String permission, int pid, int uid) {
6897            return mActivityManagerService.checkPermission(permission, pid,
6898                    uid) == PackageManager.PERMISSION_GRANTED;
6899        }
6900
6901        @Override
6902        public String[] getPackagesForUid(int uid) {
6903            return mActivityManagerService.mContext.getPackageManager()
6904                    .getPackagesForUid(uid);
6905        }
6906
6907        @Override
6908        public boolean isRuntimePermission(String permission) {
6909            try {
6910                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6911                        .getPermissionInfo(permission, 0);
6912                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6913            } catch (NameNotFoundException nnfe) {
6914                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6915            }
6916            return false;
6917        }
6918    }
6919
6920    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6921        @Override
6922        public int checkComponentPermission(String permission, int pid, int uid,
6923                int owningUid, boolean exported) {
6924            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6925                    owningUid, exported);
6926        }
6927
6928        @Override
6929        public Object getAMSLock() {
6930            return ActivityManagerService.this;
6931        }
6932    }
6933
6934    /**
6935     * This can be called with or without the global lock held.
6936     */
6937    int checkComponentPermission(String permission, int pid, int uid,
6938            int owningUid, boolean exported) {
6939        if (pid == MY_PID) {
6940            return PackageManager.PERMISSION_GRANTED;
6941        }
6942        return ActivityManager.checkComponentPermission(permission, uid,
6943                owningUid, exported);
6944    }
6945
6946    /**
6947     * As the only public entry point for permissions checking, this method
6948     * can enforce the semantic that requesting a check on a null global
6949     * permission is automatically denied.  (Internally a null permission
6950     * string is used when calling {@link #checkComponentPermission} in cases
6951     * when only uid-based security is needed.)
6952     *
6953     * This can be called with or without the global lock held.
6954     */
6955    @Override
6956    public int checkPermission(String permission, int pid, int uid) {
6957        if (permission == null) {
6958            return PackageManager.PERMISSION_DENIED;
6959        }
6960        return checkComponentPermission(permission, pid, uid, -1, true);
6961    }
6962
6963    @Override
6964    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6965        if (permission == null) {
6966            return PackageManager.PERMISSION_DENIED;
6967        }
6968
6969        // We might be performing an operation on behalf of an indirect binder
6970        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6971        // client identity accordingly before proceeding.
6972        Identity tlsIdentity = sCallerIdentity.get();
6973        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6974            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6975                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6976            uid = tlsIdentity.uid;
6977            pid = tlsIdentity.pid;
6978        }
6979
6980        return checkComponentPermission(permission, pid, uid, -1, true);
6981    }
6982
6983    /**
6984     * Binder IPC calls go through the public entry point.
6985     * This can be called with or without the global lock held.
6986     */
6987    int checkCallingPermission(String permission) {
6988        return checkPermission(permission,
6989                Binder.getCallingPid(),
6990                UserHandle.getAppId(Binder.getCallingUid()));
6991    }
6992
6993    /**
6994     * This can be called with or without the global lock held.
6995     */
6996    void enforceCallingPermission(String permission, String func) {
6997        if (checkCallingPermission(permission)
6998                == PackageManager.PERMISSION_GRANTED) {
6999            return;
7000        }
7001
7002        String msg = "Permission Denial: " + func + " from pid="
7003                + Binder.getCallingPid()
7004                + ", uid=" + Binder.getCallingUid()
7005                + " requires " + permission;
7006        Slog.w(TAG, msg);
7007        throw new SecurityException(msg);
7008    }
7009
7010    /**
7011     * Determine if UID is holding permissions required to access {@link Uri} in
7012     * the given {@link ProviderInfo}. Final permission checking is always done
7013     * in {@link ContentProvider}.
7014     */
7015    private final boolean checkHoldingPermissionsLocked(
7016            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7017        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7018                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7019        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7020            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7021                    != PERMISSION_GRANTED) {
7022                return false;
7023            }
7024        }
7025        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7026    }
7027
7028    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7029            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7030        if (pi.applicationInfo.uid == uid) {
7031            return true;
7032        } else if (!pi.exported) {
7033            return false;
7034        }
7035
7036        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7037        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7038        try {
7039            // check if target holds top-level <provider> permissions
7040            if (!readMet && pi.readPermission != null && considerUidPermissions
7041                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7042                readMet = true;
7043            }
7044            if (!writeMet && pi.writePermission != null && considerUidPermissions
7045                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7046                writeMet = true;
7047            }
7048
7049            // track if unprotected read/write is allowed; any denied
7050            // <path-permission> below removes this ability
7051            boolean allowDefaultRead = pi.readPermission == null;
7052            boolean allowDefaultWrite = pi.writePermission == null;
7053
7054            // check if target holds any <path-permission> that match uri
7055            final PathPermission[] pps = pi.pathPermissions;
7056            if (pps != null) {
7057                final String path = grantUri.uri.getPath();
7058                int i = pps.length;
7059                while (i > 0 && (!readMet || !writeMet)) {
7060                    i--;
7061                    PathPermission pp = pps[i];
7062                    if (pp.match(path)) {
7063                        if (!readMet) {
7064                            final String pprperm = pp.getReadPermission();
7065                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7066                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7067                                    + ": match=" + pp.match(path)
7068                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7069                            if (pprperm != null) {
7070                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7071                                        == PERMISSION_GRANTED) {
7072                                    readMet = true;
7073                                } else {
7074                                    allowDefaultRead = false;
7075                                }
7076                            }
7077                        }
7078                        if (!writeMet) {
7079                            final String ppwperm = pp.getWritePermission();
7080                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7081                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7082                                    + ": match=" + pp.match(path)
7083                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7084                            if (ppwperm != null) {
7085                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7086                                        == PERMISSION_GRANTED) {
7087                                    writeMet = true;
7088                                } else {
7089                                    allowDefaultWrite = false;
7090                                }
7091                            }
7092                        }
7093                    }
7094                }
7095            }
7096
7097            // grant unprotected <provider> read/write, if not blocked by
7098            // <path-permission> above
7099            if (allowDefaultRead) readMet = true;
7100            if (allowDefaultWrite) writeMet = true;
7101
7102        } catch (RemoteException e) {
7103            return false;
7104        }
7105
7106        return readMet && writeMet;
7107    }
7108
7109    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7110        ProviderInfo pi = null;
7111        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7112        if (cpr != null) {
7113            pi = cpr.info;
7114        } else {
7115            try {
7116                pi = AppGlobals.getPackageManager().resolveContentProvider(
7117                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7118            } catch (RemoteException ex) {
7119            }
7120        }
7121        return pi;
7122    }
7123
7124    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7125        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7126        if (targetUris != null) {
7127            return targetUris.get(grantUri);
7128        }
7129        return null;
7130    }
7131
7132    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7133            String targetPkg, int targetUid, GrantUri grantUri) {
7134        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7135        if (targetUris == null) {
7136            targetUris = Maps.newArrayMap();
7137            mGrantedUriPermissions.put(targetUid, targetUris);
7138        }
7139
7140        UriPermission perm = targetUris.get(grantUri);
7141        if (perm == null) {
7142            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7143            targetUris.put(grantUri, perm);
7144        }
7145
7146        return perm;
7147    }
7148
7149    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7150            final int modeFlags) {
7151        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7152        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7153                : UriPermission.STRENGTH_OWNED;
7154
7155        // Root gets to do everything.
7156        if (uid == 0) {
7157            return true;
7158        }
7159
7160        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7161        if (perms == null) return false;
7162
7163        // First look for exact match
7164        final UriPermission exactPerm = perms.get(grantUri);
7165        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7166            return true;
7167        }
7168
7169        // No exact match, look for prefixes
7170        final int N = perms.size();
7171        for (int i = 0; i < N; i++) {
7172            final UriPermission perm = perms.valueAt(i);
7173            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7174                    && perm.getStrength(modeFlags) >= minStrength) {
7175                return true;
7176            }
7177        }
7178
7179        return false;
7180    }
7181
7182    /**
7183     * @param uri This uri must NOT contain an embedded userId.
7184     * @param userId The userId in which the uri is to be resolved.
7185     */
7186    @Override
7187    public int checkUriPermission(Uri uri, int pid, int uid,
7188            final int modeFlags, int userId, IBinder callerToken) {
7189        enforceNotIsolatedCaller("checkUriPermission");
7190
7191        // Another redirected-binder-call permissions check as in
7192        // {@link checkPermissionWithToken}.
7193        Identity tlsIdentity = sCallerIdentity.get();
7194        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7195            uid = tlsIdentity.uid;
7196            pid = tlsIdentity.pid;
7197        }
7198
7199        // Our own process gets to do everything.
7200        if (pid == MY_PID) {
7201            return PackageManager.PERMISSION_GRANTED;
7202        }
7203        synchronized (this) {
7204            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7205                    ? PackageManager.PERMISSION_GRANTED
7206                    : PackageManager.PERMISSION_DENIED;
7207        }
7208    }
7209
7210    /**
7211     * Check if the targetPkg can be granted permission to access uri by
7212     * the callingUid using the given modeFlags.  Throws a security exception
7213     * if callingUid is not allowed to do this.  Returns the uid of the target
7214     * if the URI permission grant should be performed; returns -1 if it is not
7215     * needed (for example targetPkg already has permission to access the URI).
7216     * If you already know the uid of the target, you can supply it in
7217     * lastTargetUid else set that to -1.
7218     */
7219    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7220            final int modeFlags, int lastTargetUid) {
7221        if (!Intent.isAccessUriMode(modeFlags)) {
7222            return -1;
7223        }
7224
7225        if (targetPkg != null) {
7226            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7227                    "Checking grant " + targetPkg + " permission to " + grantUri);
7228        }
7229
7230        final IPackageManager pm = AppGlobals.getPackageManager();
7231
7232        // If this is not a content: uri, we can't do anything with it.
7233        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7234            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7235                    "Can't grant URI permission for non-content URI: " + grantUri);
7236            return -1;
7237        }
7238
7239        final String authority = grantUri.uri.getAuthority();
7240        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7241        if (pi == null) {
7242            Slog.w(TAG, "No content provider found for permission check: " +
7243                    grantUri.uri.toSafeString());
7244            return -1;
7245        }
7246
7247        int targetUid = lastTargetUid;
7248        if (targetUid < 0 && targetPkg != null) {
7249            try {
7250                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7251                if (targetUid < 0) {
7252                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7253                            "Can't grant URI permission no uid for: " + targetPkg);
7254                    return -1;
7255                }
7256            } catch (RemoteException ex) {
7257                return -1;
7258            }
7259        }
7260
7261        if (targetUid >= 0) {
7262            // First...  does the target actually need this permission?
7263            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7264                // No need to grant the target this permission.
7265                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7266                        "Target " + targetPkg + " already has full permission to " + grantUri);
7267                return -1;
7268            }
7269        } else {
7270            // First...  there is no target package, so can anyone access it?
7271            boolean allowed = pi.exported;
7272            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7273                if (pi.readPermission != null) {
7274                    allowed = false;
7275                }
7276            }
7277            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7278                if (pi.writePermission != null) {
7279                    allowed = false;
7280                }
7281            }
7282            if (allowed) {
7283                return -1;
7284            }
7285        }
7286
7287        /* There is a special cross user grant if:
7288         * - The target is on another user.
7289         * - Apps on the current user can access the uri without any uid permissions.
7290         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7291         * grant uri permissions.
7292         */
7293        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7294                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7295                modeFlags, false /*without considering the uid permissions*/);
7296
7297        // Second...  is the provider allowing granting of URI permissions?
7298        if (!specialCrossUserGrant) {
7299            if (!pi.grantUriPermissions) {
7300                throw new SecurityException("Provider " + pi.packageName
7301                        + "/" + pi.name
7302                        + " does not allow granting of Uri permissions (uri "
7303                        + grantUri + ")");
7304            }
7305            if (pi.uriPermissionPatterns != null) {
7306                final int N = pi.uriPermissionPatterns.length;
7307                boolean allowed = false;
7308                for (int i=0; i<N; i++) {
7309                    if (pi.uriPermissionPatterns[i] != null
7310                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7311                        allowed = true;
7312                        break;
7313                    }
7314                }
7315                if (!allowed) {
7316                    throw new SecurityException("Provider " + pi.packageName
7317                            + "/" + pi.name
7318                            + " does not allow granting of permission to path of Uri "
7319                            + grantUri);
7320                }
7321            }
7322        }
7323
7324        // Third...  does the caller itself have permission to access
7325        // this uri?
7326        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7327            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7328                // Require they hold a strong enough Uri permission
7329                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7330                    throw new SecurityException("Uid " + callingUid
7331                            + " does not have permission to uri " + grantUri);
7332                }
7333            }
7334        }
7335        return targetUid;
7336    }
7337
7338    /**
7339     * @param uri This uri must NOT contain an embedded userId.
7340     * @param userId The userId in which the uri is to be resolved.
7341     */
7342    @Override
7343    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7344            final int modeFlags, int userId) {
7345        enforceNotIsolatedCaller("checkGrantUriPermission");
7346        synchronized(this) {
7347            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7348                    new GrantUri(userId, uri, false), modeFlags, -1);
7349        }
7350    }
7351
7352    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7353            final int modeFlags, UriPermissionOwner owner) {
7354        if (!Intent.isAccessUriMode(modeFlags)) {
7355            return;
7356        }
7357
7358        // So here we are: the caller has the assumed permission
7359        // to the uri, and the target doesn't.  Let's now give this to
7360        // the target.
7361
7362        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7363                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7364
7365        final String authority = grantUri.uri.getAuthority();
7366        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7367        if (pi == null) {
7368            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7369            return;
7370        }
7371
7372        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7373            grantUri.prefix = true;
7374        }
7375        final UriPermission perm = findOrCreateUriPermissionLocked(
7376                pi.packageName, targetPkg, targetUid, grantUri);
7377        perm.grantModes(modeFlags, owner);
7378    }
7379
7380    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7381            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7382        if (targetPkg == null) {
7383            throw new NullPointerException("targetPkg");
7384        }
7385        int targetUid;
7386        final IPackageManager pm = AppGlobals.getPackageManager();
7387        try {
7388            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7389        } catch (RemoteException ex) {
7390            return;
7391        }
7392
7393        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7394                targetUid);
7395        if (targetUid < 0) {
7396            return;
7397        }
7398
7399        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7400                owner);
7401    }
7402
7403    static class NeededUriGrants extends ArrayList<GrantUri> {
7404        final String targetPkg;
7405        final int targetUid;
7406        final int flags;
7407
7408        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7409            this.targetPkg = targetPkg;
7410            this.targetUid = targetUid;
7411            this.flags = flags;
7412        }
7413    }
7414
7415    /**
7416     * Like checkGrantUriPermissionLocked, but takes an Intent.
7417     */
7418    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7419            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7420        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7421                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7422                + " clip=" + (intent != null ? intent.getClipData() : null)
7423                + " from " + intent + "; flags=0x"
7424                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7425
7426        if (targetPkg == null) {
7427            throw new NullPointerException("targetPkg");
7428        }
7429
7430        if (intent == null) {
7431            return null;
7432        }
7433        Uri data = intent.getData();
7434        ClipData clip = intent.getClipData();
7435        if (data == null && clip == null) {
7436            return null;
7437        }
7438        // Default userId for uris in the intent (if they don't specify it themselves)
7439        int contentUserHint = intent.getContentUserHint();
7440        if (contentUserHint == UserHandle.USER_CURRENT) {
7441            contentUserHint = UserHandle.getUserId(callingUid);
7442        }
7443        final IPackageManager pm = AppGlobals.getPackageManager();
7444        int targetUid;
7445        if (needed != null) {
7446            targetUid = needed.targetUid;
7447        } else {
7448            try {
7449                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7450            } catch (RemoteException ex) {
7451                return null;
7452            }
7453            if (targetUid < 0) {
7454                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7455                        "Can't grant URI permission no uid for: " + targetPkg
7456                        + " on user " + targetUserId);
7457                return null;
7458            }
7459        }
7460        if (data != null) {
7461            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7462            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7463                    targetUid);
7464            if (targetUid > 0) {
7465                if (needed == null) {
7466                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7467                }
7468                needed.add(grantUri);
7469            }
7470        }
7471        if (clip != null) {
7472            for (int i=0; i<clip.getItemCount(); i++) {
7473                Uri uri = clip.getItemAt(i).getUri();
7474                if (uri != null) {
7475                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7476                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7477                            targetUid);
7478                    if (targetUid > 0) {
7479                        if (needed == null) {
7480                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7481                        }
7482                        needed.add(grantUri);
7483                    }
7484                } else {
7485                    Intent clipIntent = clip.getItemAt(i).getIntent();
7486                    if (clipIntent != null) {
7487                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7488                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7489                        if (newNeeded != null) {
7490                            needed = newNeeded;
7491                        }
7492                    }
7493                }
7494            }
7495        }
7496
7497        return needed;
7498    }
7499
7500    /**
7501     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7502     */
7503    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7504            UriPermissionOwner owner) {
7505        if (needed != null) {
7506            for (int i=0; i<needed.size(); i++) {
7507                GrantUri grantUri = needed.get(i);
7508                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7509                        grantUri, needed.flags, owner);
7510            }
7511        }
7512    }
7513
7514    void grantUriPermissionFromIntentLocked(int callingUid,
7515            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7516        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7517                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7518        if (needed == null) {
7519            return;
7520        }
7521
7522        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7523    }
7524
7525    /**
7526     * @param uri This uri must NOT contain an embedded userId.
7527     * @param userId The userId in which the uri is to be resolved.
7528     */
7529    @Override
7530    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7531            final int modeFlags, int userId) {
7532        enforceNotIsolatedCaller("grantUriPermission");
7533        GrantUri grantUri = new GrantUri(userId, uri, false);
7534        synchronized(this) {
7535            final ProcessRecord r = getRecordForAppLocked(caller);
7536            if (r == null) {
7537                throw new SecurityException("Unable to find app for caller "
7538                        + caller
7539                        + " when granting permission to uri " + grantUri);
7540            }
7541            if (targetPkg == null) {
7542                throw new IllegalArgumentException("null target");
7543            }
7544            if (grantUri == null) {
7545                throw new IllegalArgumentException("null uri");
7546            }
7547
7548            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7549                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7550                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7551                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7552
7553            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7554                    UserHandle.getUserId(r.uid));
7555        }
7556    }
7557
7558    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7559        if (perm.modeFlags == 0) {
7560            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7561                    perm.targetUid);
7562            if (perms != null) {
7563                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7564                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7565
7566                perms.remove(perm.uri);
7567                if (perms.isEmpty()) {
7568                    mGrantedUriPermissions.remove(perm.targetUid);
7569                }
7570            }
7571        }
7572    }
7573
7574    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7575        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7576                "Revoking all granted permissions to " + grantUri);
7577
7578        final IPackageManager pm = AppGlobals.getPackageManager();
7579        final String authority = grantUri.uri.getAuthority();
7580        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7581        if (pi == null) {
7582            Slog.w(TAG, "No content provider found for permission revoke: "
7583                    + grantUri.toSafeString());
7584            return;
7585        }
7586
7587        // Does the caller have this permission on the URI?
7588        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7589            // If they don't have direct access to the URI, then revoke any
7590            // ownerless URI permissions that have been granted to them.
7591            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7592            if (perms != null) {
7593                boolean persistChanged = false;
7594                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7595                    final UriPermission perm = it.next();
7596                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7597                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7598                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7599                                "Revoking non-owned " + perm.targetUid
7600                                + " permission to " + perm.uri);
7601                        persistChanged |= perm.revokeModes(
7602                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7603                        if (perm.modeFlags == 0) {
7604                            it.remove();
7605                        }
7606                    }
7607                }
7608                if (perms.isEmpty()) {
7609                    mGrantedUriPermissions.remove(callingUid);
7610                }
7611                if (persistChanged) {
7612                    schedulePersistUriGrants();
7613                }
7614            }
7615            return;
7616        }
7617
7618        boolean persistChanged = false;
7619
7620        // Go through all of the permissions and remove any that match.
7621        int N = mGrantedUriPermissions.size();
7622        for (int i = 0; i < N; i++) {
7623            final int targetUid = mGrantedUriPermissions.keyAt(i);
7624            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7625
7626            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7627                final UriPermission perm = it.next();
7628                if (perm.uri.sourceUserId == grantUri.sourceUserId
7629                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7630                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7631                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7632                    persistChanged |= perm.revokeModes(
7633                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7634                    if (perm.modeFlags == 0) {
7635                        it.remove();
7636                    }
7637                }
7638            }
7639
7640            if (perms.isEmpty()) {
7641                mGrantedUriPermissions.remove(targetUid);
7642                N--;
7643                i--;
7644            }
7645        }
7646
7647        if (persistChanged) {
7648            schedulePersistUriGrants();
7649        }
7650    }
7651
7652    /**
7653     * @param uri This uri must NOT contain an embedded userId.
7654     * @param userId The userId in which the uri is to be resolved.
7655     */
7656    @Override
7657    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7658            int userId) {
7659        enforceNotIsolatedCaller("revokeUriPermission");
7660        synchronized(this) {
7661            final ProcessRecord r = getRecordForAppLocked(caller);
7662            if (r == null) {
7663                throw new SecurityException("Unable to find app for caller "
7664                        + caller
7665                        + " when revoking permission to uri " + uri);
7666            }
7667            if (uri == null) {
7668                Slog.w(TAG, "revokeUriPermission: null uri");
7669                return;
7670            }
7671
7672            if (!Intent.isAccessUriMode(modeFlags)) {
7673                return;
7674            }
7675
7676            final String authority = uri.getAuthority();
7677            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7678            if (pi == null) {
7679                Slog.w(TAG, "No content provider found for permission revoke: "
7680                        + uri.toSafeString());
7681                return;
7682            }
7683
7684            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7685        }
7686    }
7687
7688    /**
7689     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7690     * given package.
7691     *
7692     * @param packageName Package name to match, or {@code null} to apply to all
7693     *            packages.
7694     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7695     *            to all users.
7696     * @param persistable If persistable grants should be removed.
7697     */
7698    private void removeUriPermissionsForPackageLocked(
7699            String packageName, int userHandle, boolean persistable) {
7700        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7701            throw new IllegalArgumentException("Must narrow by either package or user");
7702        }
7703
7704        boolean persistChanged = false;
7705
7706        int N = mGrantedUriPermissions.size();
7707        for (int i = 0; i < N; i++) {
7708            final int targetUid = mGrantedUriPermissions.keyAt(i);
7709            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7710
7711            // Only inspect grants matching user
7712            if (userHandle == UserHandle.USER_ALL
7713                    || userHandle == UserHandle.getUserId(targetUid)) {
7714                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7715                    final UriPermission perm = it.next();
7716
7717                    // Only inspect grants matching package
7718                    if (packageName == null || perm.sourcePkg.equals(packageName)
7719                            || perm.targetPkg.equals(packageName)) {
7720                        persistChanged |= perm.revokeModes(persistable
7721                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7722
7723                        // Only remove when no modes remain; any persisted grants
7724                        // will keep this alive.
7725                        if (perm.modeFlags == 0) {
7726                            it.remove();
7727                        }
7728                    }
7729                }
7730
7731                if (perms.isEmpty()) {
7732                    mGrantedUriPermissions.remove(targetUid);
7733                    N--;
7734                    i--;
7735                }
7736            }
7737        }
7738
7739        if (persistChanged) {
7740            schedulePersistUriGrants();
7741        }
7742    }
7743
7744    @Override
7745    public IBinder newUriPermissionOwner(String name) {
7746        enforceNotIsolatedCaller("newUriPermissionOwner");
7747        synchronized(this) {
7748            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7749            return owner.getExternalTokenLocked();
7750        }
7751    }
7752
7753    /**
7754     * @param uri This uri must NOT contain an embedded userId.
7755     * @param sourceUserId The userId in which the uri is to be resolved.
7756     * @param targetUserId The userId of the app that receives the grant.
7757     */
7758    @Override
7759    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7760            final int modeFlags, int sourceUserId, int targetUserId) {
7761        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7762                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7763        synchronized(this) {
7764            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7765            if (owner == null) {
7766                throw new IllegalArgumentException("Unknown owner: " + token);
7767            }
7768            if (fromUid != Binder.getCallingUid()) {
7769                if (Binder.getCallingUid() != Process.myUid()) {
7770                    // Only system code can grant URI permissions on behalf
7771                    // of other users.
7772                    throw new SecurityException("nice try");
7773                }
7774            }
7775            if (targetPkg == null) {
7776                throw new IllegalArgumentException("null target");
7777            }
7778            if (uri == null) {
7779                throw new IllegalArgumentException("null uri");
7780            }
7781
7782            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7783                    modeFlags, owner, targetUserId);
7784        }
7785    }
7786
7787    /**
7788     * @param uri This uri must NOT contain an embedded userId.
7789     * @param userId The userId in which the uri is to be resolved.
7790     */
7791    @Override
7792    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7793        synchronized(this) {
7794            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7795            if (owner == null) {
7796                throw new IllegalArgumentException("Unknown owner: " + token);
7797            }
7798
7799            if (uri == null) {
7800                owner.removeUriPermissionsLocked(mode);
7801            } else {
7802                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7803            }
7804        }
7805    }
7806
7807    private void schedulePersistUriGrants() {
7808        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7809            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7810                    10 * DateUtils.SECOND_IN_MILLIS);
7811        }
7812    }
7813
7814    private void writeGrantedUriPermissions() {
7815        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7816
7817        // Snapshot permissions so we can persist without lock
7818        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7819        synchronized (this) {
7820            final int size = mGrantedUriPermissions.size();
7821            for (int i = 0; i < size; i++) {
7822                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7823                for (UriPermission perm : perms.values()) {
7824                    if (perm.persistedModeFlags != 0) {
7825                        persist.add(perm.snapshot());
7826                    }
7827                }
7828            }
7829        }
7830
7831        FileOutputStream fos = null;
7832        try {
7833            fos = mGrantFile.startWrite();
7834
7835            XmlSerializer out = new FastXmlSerializer();
7836            out.setOutput(fos, StandardCharsets.UTF_8.name());
7837            out.startDocument(null, true);
7838            out.startTag(null, TAG_URI_GRANTS);
7839            for (UriPermission.Snapshot perm : persist) {
7840                out.startTag(null, TAG_URI_GRANT);
7841                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7842                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7843                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7844                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7845                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7846                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7847                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7848                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7849                out.endTag(null, TAG_URI_GRANT);
7850            }
7851            out.endTag(null, TAG_URI_GRANTS);
7852            out.endDocument();
7853
7854            mGrantFile.finishWrite(fos);
7855        } catch (IOException e) {
7856            if (fos != null) {
7857                mGrantFile.failWrite(fos);
7858            }
7859        }
7860    }
7861
7862    private void readGrantedUriPermissionsLocked() {
7863        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7864
7865        final long now = System.currentTimeMillis();
7866
7867        FileInputStream fis = null;
7868        try {
7869            fis = mGrantFile.openRead();
7870            final XmlPullParser in = Xml.newPullParser();
7871            in.setInput(fis, StandardCharsets.UTF_8.name());
7872
7873            int type;
7874            while ((type = in.next()) != END_DOCUMENT) {
7875                final String tag = in.getName();
7876                if (type == START_TAG) {
7877                    if (TAG_URI_GRANT.equals(tag)) {
7878                        final int sourceUserId;
7879                        final int targetUserId;
7880                        final int userHandle = readIntAttribute(in,
7881                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7882                        if (userHandle != UserHandle.USER_NULL) {
7883                            // For backwards compatibility.
7884                            sourceUserId = userHandle;
7885                            targetUserId = userHandle;
7886                        } else {
7887                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7888                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7889                        }
7890                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7891                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7892                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7893                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7894                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7895                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7896
7897                        // Sanity check that provider still belongs to source package
7898                        final ProviderInfo pi = getProviderInfoLocked(
7899                                uri.getAuthority(), sourceUserId);
7900                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7901                            int targetUid = -1;
7902                            try {
7903                                targetUid = AppGlobals.getPackageManager()
7904                                        .getPackageUid(targetPkg, targetUserId);
7905                            } catch (RemoteException e) {
7906                            }
7907                            if (targetUid != -1) {
7908                                final UriPermission perm = findOrCreateUriPermissionLocked(
7909                                        sourcePkg, targetPkg, targetUid,
7910                                        new GrantUri(sourceUserId, uri, prefix));
7911                                perm.initPersistedModes(modeFlags, createdTime);
7912                            }
7913                        } else {
7914                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7915                                    + " but instead found " + pi);
7916                        }
7917                    }
7918                }
7919            }
7920        } catch (FileNotFoundException e) {
7921            // Missing grants is okay
7922        } catch (IOException e) {
7923            Slog.wtf(TAG, "Failed reading Uri grants", e);
7924        } catch (XmlPullParserException e) {
7925            Slog.wtf(TAG, "Failed reading Uri grants", e);
7926        } finally {
7927            IoUtils.closeQuietly(fis);
7928        }
7929    }
7930
7931    /**
7932     * @param uri This uri must NOT contain an embedded userId.
7933     * @param userId The userId in which the uri is to be resolved.
7934     */
7935    @Override
7936    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7937        enforceNotIsolatedCaller("takePersistableUriPermission");
7938
7939        Preconditions.checkFlagsArgument(modeFlags,
7940                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7941
7942        synchronized (this) {
7943            final int callingUid = Binder.getCallingUid();
7944            boolean persistChanged = false;
7945            GrantUri grantUri = new GrantUri(userId, uri, false);
7946
7947            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7948                    new GrantUri(userId, uri, false));
7949            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7950                    new GrantUri(userId, uri, true));
7951
7952            final boolean exactValid = (exactPerm != null)
7953                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7954            final boolean prefixValid = (prefixPerm != null)
7955                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7956
7957            if (!(exactValid || prefixValid)) {
7958                throw new SecurityException("No persistable permission grants found for UID "
7959                        + callingUid + " and Uri " + grantUri.toSafeString());
7960            }
7961
7962            if (exactValid) {
7963                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7964            }
7965            if (prefixValid) {
7966                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7967            }
7968
7969            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7970
7971            if (persistChanged) {
7972                schedulePersistUriGrants();
7973            }
7974        }
7975    }
7976
7977    /**
7978     * @param uri This uri must NOT contain an embedded userId.
7979     * @param userId The userId in which the uri is to be resolved.
7980     */
7981    @Override
7982    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7983        enforceNotIsolatedCaller("releasePersistableUriPermission");
7984
7985        Preconditions.checkFlagsArgument(modeFlags,
7986                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7987
7988        synchronized (this) {
7989            final int callingUid = Binder.getCallingUid();
7990            boolean persistChanged = false;
7991
7992            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7993                    new GrantUri(userId, uri, false));
7994            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7995                    new GrantUri(userId, uri, true));
7996            if (exactPerm == null && prefixPerm == null) {
7997                throw new SecurityException("No permission grants found for UID " + callingUid
7998                        + " and Uri " + uri.toSafeString());
7999            }
8000
8001            if (exactPerm != null) {
8002                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8003                removeUriPermissionIfNeededLocked(exactPerm);
8004            }
8005            if (prefixPerm != null) {
8006                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8007                removeUriPermissionIfNeededLocked(prefixPerm);
8008            }
8009
8010            if (persistChanged) {
8011                schedulePersistUriGrants();
8012            }
8013        }
8014    }
8015
8016    /**
8017     * Prune any older {@link UriPermission} for the given UID until outstanding
8018     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8019     *
8020     * @return if any mutations occured that require persisting.
8021     */
8022    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8023        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8024        if (perms == null) return false;
8025        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8026
8027        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8028        for (UriPermission perm : perms.values()) {
8029            if (perm.persistedModeFlags != 0) {
8030                persisted.add(perm);
8031            }
8032        }
8033
8034        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8035        if (trimCount <= 0) return false;
8036
8037        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8038        for (int i = 0; i < trimCount; i++) {
8039            final UriPermission perm = persisted.get(i);
8040
8041            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8042                    "Trimming grant created at " + perm.persistedCreateTime);
8043
8044            perm.releasePersistableModes(~0);
8045            removeUriPermissionIfNeededLocked(perm);
8046        }
8047
8048        return true;
8049    }
8050
8051    @Override
8052    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8053            String packageName, boolean incoming) {
8054        enforceNotIsolatedCaller("getPersistedUriPermissions");
8055        Preconditions.checkNotNull(packageName, "packageName");
8056
8057        final int callingUid = Binder.getCallingUid();
8058        final IPackageManager pm = AppGlobals.getPackageManager();
8059        try {
8060            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8061            if (packageUid != callingUid) {
8062                throw new SecurityException(
8063                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8064            }
8065        } catch (RemoteException e) {
8066            throw new SecurityException("Failed to verify package name ownership");
8067        }
8068
8069        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8070        synchronized (this) {
8071            if (incoming) {
8072                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8073                        callingUid);
8074                if (perms == null) {
8075                    Slog.w(TAG, "No permission grants found for " + packageName);
8076                } else {
8077                    for (UriPermission perm : perms.values()) {
8078                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8079                            result.add(perm.buildPersistedPublicApiObject());
8080                        }
8081                    }
8082                }
8083            } else {
8084                final int size = mGrantedUriPermissions.size();
8085                for (int i = 0; i < size; i++) {
8086                    final ArrayMap<GrantUri, UriPermission> perms =
8087                            mGrantedUriPermissions.valueAt(i);
8088                    for (UriPermission perm : perms.values()) {
8089                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8090                            result.add(perm.buildPersistedPublicApiObject());
8091                        }
8092                    }
8093                }
8094            }
8095        }
8096        return new ParceledListSlice<android.content.UriPermission>(result);
8097    }
8098
8099    @Override
8100    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8101        synchronized (this) {
8102            ProcessRecord app =
8103                who != null ? getRecordForAppLocked(who) : null;
8104            if (app == null) return;
8105
8106            Message msg = Message.obtain();
8107            msg.what = WAIT_FOR_DEBUGGER_MSG;
8108            msg.obj = app;
8109            msg.arg1 = waiting ? 1 : 0;
8110            mUiHandler.sendMessage(msg);
8111        }
8112    }
8113
8114    @Override
8115    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8116        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8117        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8118        outInfo.availMem = Process.getFreeMemory();
8119        outInfo.totalMem = Process.getTotalMemory();
8120        outInfo.threshold = homeAppMem;
8121        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8122        outInfo.hiddenAppThreshold = cachedAppMem;
8123        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8124                ProcessList.SERVICE_ADJ);
8125        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8126                ProcessList.VISIBLE_APP_ADJ);
8127        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8128                ProcessList.FOREGROUND_APP_ADJ);
8129    }
8130
8131    // =========================================================
8132    // TASK MANAGEMENT
8133    // =========================================================
8134
8135    @Override
8136    public List<IAppTask> getAppTasks(String callingPackage) {
8137        int callingUid = Binder.getCallingUid();
8138        long ident = Binder.clearCallingIdentity();
8139
8140        synchronized(this) {
8141            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8142            try {
8143                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8144
8145                final int N = mRecentTasks.size();
8146                for (int i = 0; i < N; i++) {
8147                    TaskRecord tr = mRecentTasks.get(i);
8148                    // Skip tasks that do not match the caller.  We don't need to verify
8149                    // callingPackage, because we are also limiting to callingUid and know
8150                    // that will limit to the correct security sandbox.
8151                    if (tr.effectiveUid != callingUid) {
8152                        continue;
8153                    }
8154                    Intent intent = tr.getBaseIntent();
8155                    if (intent == null ||
8156                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8157                        continue;
8158                    }
8159                    ActivityManager.RecentTaskInfo taskInfo =
8160                            createRecentTaskInfoFromTaskRecord(tr);
8161                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8162                    list.add(taskImpl);
8163                }
8164            } finally {
8165                Binder.restoreCallingIdentity(ident);
8166            }
8167            return list;
8168        }
8169    }
8170
8171    @Override
8172    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8173        final int callingUid = Binder.getCallingUid();
8174        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8175
8176        synchronized(this) {
8177            if (DEBUG_ALL) Slog.v(
8178                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8179
8180            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8181                    callingUid);
8182
8183            // TODO: Improve with MRU list from all ActivityStacks.
8184            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8185        }
8186
8187        return list;
8188    }
8189
8190    /**
8191     * Creates a new RecentTaskInfo from a TaskRecord.
8192     */
8193    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8194        // Update the task description to reflect any changes in the task stack
8195        tr.updateTaskDescription();
8196
8197        // Compose the recent task info
8198        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8199        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8200        rti.persistentId = tr.taskId;
8201        rti.baseIntent = new Intent(tr.getBaseIntent());
8202        rti.origActivity = tr.origActivity;
8203        rti.description = tr.lastDescription;
8204        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8205        rti.userId = tr.userId;
8206        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8207        rti.firstActiveTime = tr.firstActiveTime;
8208        rti.lastActiveTime = tr.lastActiveTime;
8209        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8210        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8211        rti.numActivities = 0;
8212
8213        ActivityRecord base = null;
8214        ActivityRecord top = null;
8215        ActivityRecord tmp;
8216
8217        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8218            tmp = tr.mActivities.get(i);
8219            if (tmp.finishing) {
8220                continue;
8221            }
8222            base = tmp;
8223            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8224                top = base;
8225            }
8226            rti.numActivities++;
8227        }
8228
8229        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8230        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8231
8232        return rti;
8233    }
8234
8235    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8236        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8237                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8238        if (!allowed) {
8239            if (checkPermission(android.Manifest.permission.GET_TASKS,
8240                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8241                // Temporary compatibility: some existing apps on the system image may
8242                // still be requesting the old permission and not switched to the new
8243                // one; if so, we'll still allow them full access.  This means we need
8244                // to see if they are holding the old permission and are a system app.
8245                try {
8246                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8247                        allowed = true;
8248                        Slog.w(TAG, caller + ": caller " + callingUid
8249                                + " is using old GET_TASKS but privileged; allowing");
8250                    }
8251                } catch (RemoteException e) {
8252                }
8253            }
8254        }
8255        if (!allowed) {
8256            Slog.w(TAG, caller + ": caller " + callingUid
8257                    + " does not hold REAL_GET_TASKS; limiting output");
8258        }
8259        return allowed;
8260    }
8261
8262    @Override
8263    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8264        final int callingUid = Binder.getCallingUid();
8265        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8266                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8267
8268        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8269        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8270        synchronized (this) {
8271            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8272                    callingUid);
8273            final boolean detailed = checkCallingPermission(
8274                    android.Manifest.permission.GET_DETAILED_TASKS)
8275                    == PackageManager.PERMISSION_GRANTED;
8276
8277            final int recentsCount = mRecentTasks.size();
8278            ArrayList<ActivityManager.RecentTaskInfo> res =
8279                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8280
8281            final Set<Integer> includedUsers;
8282            if (includeProfiles) {
8283                includedUsers = getProfileIdsLocked(userId);
8284            } else {
8285                includedUsers = new HashSet<>();
8286            }
8287            includedUsers.add(Integer.valueOf(userId));
8288
8289            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8290                TaskRecord tr = mRecentTasks.get(i);
8291                // Only add calling user or related users recent tasks
8292                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8293                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8294                    continue;
8295                }
8296
8297                // Return the entry if desired by the caller.  We always return
8298                // the first entry, because callers always expect this to be the
8299                // foreground app.  We may filter others if the caller has
8300                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8301                // we should exclude the entry.
8302
8303                if (i == 0
8304                        || withExcluded
8305                        || (tr.intent == null)
8306                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8307                                == 0)) {
8308                    if (!allowed) {
8309                        // If the caller doesn't have the GET_TASKS permission, then only
8310                        // allow them to see a small subset of tasks -- their own and home.
8311                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8312                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8313                            continue;
8314                        }
8315                    }
8316                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8317                        if (tr.stack != null && tr.stack.isHomeStack()) {
8318                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8319                                    "Skipping, home stack task: " + tr);
8320                            continue;
8321                        }
8322                    }
8323                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8324                        // Don't include auto remove tasks that are finished or finishing.
8325                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8326                                "Skipping, auto-remove without activity: " + tr);
8327                        continue;
8328                    }
8329                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8330                            && !tr.isAvailable) {
8331                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8332                                "Skipping, unavail real act: " + tr);
8333                        continue;
8334                    }
8335
8336                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8337                    if (!detailed) {
8338                        rti.baseIntent.replaceExtras((Bundle)null);
8339                    }
8340
8341                    res.add(rti);
8342                    maxNum--;
8343                }
8344            }
8345            return res;
8346        }
8347    }
8348
8349    @Override
8350    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8351        synchronized (this) {
8352            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8353                    "getTaskThumbnail()");
8354            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8355            if (tr != null) {
8356                return tr.getTaskThumbnailLocked();
8357            }
8358        }
8359        return null;
8360    }
8361
8362    @Override
8363    public int addAppTask(IBinder activityToken, Intent intent,
8364            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8365        final int callingUid = Binder.getCallingUid();
8366        final long callingIdent = Binder.clearCallingIdentity();
8367
8368        try {
8369            synchronized (this) {
8370                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8371                if (r == null) {
8372                    throw new IllegalArgumentException("Activity does not exist; token="
8373                            + activityToken);
8374                }
8375                ComponentName comp = intent.getComponent();
8376                if (comp == null) {
8377                    throw new IllegalArgumentException("Intent " + intent
8378                            + " must specify explicit component");
8379                }
8380                if (thumbnail.getWidth() != mThumbnailWidth
8381                        || thumbnail.getHeight() != mThumbnailHeight) {
8382                    throw new IllegalArgumentException("Bad thumbnail size: got "
8383                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8384                            + mThumbnailWidth + "x" + mThumbnailHeight);
8385                }
8386                if (intent.getSelector() != null) {
8387                    intent.setSelector(null);
8388                }
8389                if (intent.getSourceBounds() != null) {
8390                    intent.setSourceBounds(null);
8391                }
8392                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8393                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8394                        // The caller has added this as an auto-remove task...  that makes no
8395                        // sense, so turn off auto-remove.
8396                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8397                    }
8398                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8399                    // Must be a new task.
8400                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8401                }
8402                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8403                    mLastAddedTaskActivity = null;
8404                }
8405                ActivityInfo ainfo = mLastAddedTaskActivity;
8406                if (ainfo == null) {
8407                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8408                            comp, 0, UserHandle.getUserId(callingUid));
8409                    if (ainfo.applicationInfo.uid != callingUid) {
8410                        throw new SecurityException(
8411                                "Can't add task for another application: target uid="
8412                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8413                    }
8414                }
8415
8416                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8417                        intent, description);
8418
8419                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8420                if (trimIdx >= 0) {
8421                    // If this would have caused a trim, then we'll abort because that
8422                    // means it would be added at the end of the list but then just removed.
8423                    return INVALID_TASK_ID;
8424                }
8425
8426                final int N = mRecentTasks.size();
8427                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8428                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8429                    tr.removedFromRecents();
8430                }
8431
8432                task.inRecents = true;
8433                mRecentTasks.add(task);
8434                r.task.stack.addTask(task, false, false);
8435
8436                task.setLastThumbnail(thumbnail);
8437                task.freeLastThumbnail();
8438
8439                return task.taskId;
8440            }
8441        } finally {
8442            Binder.restoreCallingIdentity(callingIdent);
8443        }
8444    }
8445
8446    @Override
8447    public Point getAppTaskThumbnailSize() {
8448        synchronized (this) {
8449            return new Point(mThumbnailWidth,  mThumbnailHeight);
8450        }
8451    }
8452
8453    @Override
8454    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8455        synchronized (this) {
8456            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8457            if (r != null) {
8458                r.setTaskDescription(td);
8459                r.task.updateTaskDescription();
8460            }
8461        }
8462    }
8463
8464    @Override
8465    public void setTaskResizeable(int taskId, boolean resizeable) {
8466        synchronized (this) {
8467            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8468            if (task == null) {
8469                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8470                return;
8471            }
8472            if (task.mResizeable != resizeable) {
8473                task.mResizeable = resizeable;
8474                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8475                mStackSupervisor.resumeTopActivitiesLocked();
8476            }
8477        }
8478    }
8479
8480    @Override
8481    public void resizeTask(int taskId, Rect bounds) {
8482        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8483                "resizeTask()");
8484        long ident = Binder.clearCallingIdentity();
8485        try {
8486            synchronized (this) {
8487                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8488                if (task == null) {
8489                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8490                    return;
8491                }
8492                mStackSupervisor.resizeTaskLocked(task, bounds);
8493            }
8494        } finally {
8495            Binder.restoreCallingIdentity(ident);
8496        }
8497    }
8498
8499    @Override
8500    public Bitmap getTaskDescriptionIcon(String filename) {
8501        if (!FileUtils.isValidExtFilename(filename)
8502                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8503            throw new IllegalArgumentException("Bad filename: " + filename);
8504        }
8505        return mTaskPersister.getTaskDescriptionIcon(filename);
8506    }
8507
8508    @Override
8509    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8510            throws RemoteException {
8511        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8512                opts.getCustomInPlaceResId() == 0) {
8513            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8514                    "with valid animation");
8515        }
8516        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8517        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8518                opts.getCustomInPlaceResId());
8519        mWindowManager.executeAppTransition();
8520    }
8521
8522    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8523        mRecentTasks.remove(tr);
8524        tr.removedFromRecents();
8525        ComponentName component = tr.getBaseIntent().getComponent();
8526        if (component == null) {
8527            Slog.w(TAG, "No component for base intent of task: " + tr);
8528            return;
8529        }
8530
8531        if (!killProcess) {
8532            return;
8533        }
8534
8535        // Determine if the process(es) for this task should be killed.
8536        final String pkg = component.getPackageName();
8537        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8538        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8539        for (int i = 0; i < pmap.size(); i++) {
8540
8541            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8542            for (int j = 0; j < uids.size(); j++) {
8543                ProcessRecord proc = uids.valueAt(j);
8544                if (proc.userId != tr.userId) {
8545                    // Don't kill process for a different user.
8546                    continue;
8547                }
8548                if (proc == mHomeProcess) {
8549                    // Don't kill the home process along with tasks from the same package.
8550                    continue;
8551                }
8552                if (!proc.pkgList.containsKey(pkg)) {
8553                    // Don't kill process that is not associated with this task.
8554                    continue;
8555                }
8556
8557                for (int k = 0; k < proc.activities.size(); k++) {
8558                    TaskRecord otherTask = proc.activities.get(k).task;
8559                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8560                        // Don't kill process(es) that has an activity in a different task that is
8561                        // also in recents.
8562                        return;
8563                    }
8564                }
8565
8566                // Add process to kill list.
8567                procsToKill.add(proc);
8568            }
8569        }
8570
8571        // Find any running services associated with this app and stop if needed.
8572        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8573
8574        // Kill the running processes.
8575        for (int i = 0; i < procsToKill.size(); i++) {
8576            ProcessRecord pr = procsToKill.get(i);
8577            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8578                pr.kill("remove task", true);
8579            } else {
8580                pr.waitingToKill = "remove task";
8581            }
8582        }
8583    }
8584
8585    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8586        // Remove all tasks with activities in the specified package from the list of recent tasks
8587        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8588            TaskRecord tr = mRecentTasks.get(i);
8589            if (tr.userId != userId) continue;
8590
8591            ComponentName cn = tr.intent.getComponent();
8592            if (cn != null && cn.getPackageName().equals(packageName)) {
8593                // If the package name matches, remove the task.
8594                removeTaskByIdLocked(tr.taskId, true);
8595            }
8596        }
8597    }
8598
8599    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8600            int userId) {
8601
8602        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8603            TaskRecord tr = mRecentTasks.get(i);
8604            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8605                continue;
8606            }
8607
8608            ComponentName cn = tr.intent.getComponent();
8609            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8610                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8611            if (sameComponent) {
8612                removeTaskByIdLocked(tr.taskId, false);
8613            }
8614        }
8615    }
8616
8617    /**
8618     * Removes the task with the specified task id.
8619     *
8620     * @param taskId Identifier of the task to be removed.
8621     * @param killProcess Kill any process associated with the task if possible.
8622     * @return Returns true if the given task was found and removed.
8623     */
8624    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8625        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8626        if (tr != null) {
8627            tr.removeTaskActivitiesLocked();
8628            cleanUpRemovedTaskLocked(tr, killProcess);
8629            if (tr.isPersistable) {
8630                notifyTaskPersisterLocked(null, true);
8631            }
8632            return true;
8633        }
8634        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8635        return false;
8636    }
8637
8638    @Override
8639    public boolean removeTask(int taskId) {
8640        synchronized (this) {
8641            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8642                    "removeTask()");
8643            long ident = Binder.clearCallingIdentity();
8644            try {
8645                return removeTaskByIdLocked(taskId, true);
8646            } finally {
8647                Binder.restoreCallingIdentity(ident);
8648            }
8649        }
8650    }
8651
8652    /**
8653     * TODO: Add mController hook
8654     */
8655    @Override
8656    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8657        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8658
8659        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8660        synchronized(this) {
8661            moveTaskToFrontLocked(taskId, flags, options);
8662        }
8663    }
8664
8665    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8666        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8667                Binder.getCallingUid(), -1, -1, "Task to front")) {
8668            ActivityOptions.abort(options);
8669            return;
8670        }
8671        final long origId = Binder.clearCallingIdentity();
8672        try {
8673            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8674            if (task == null) {
8675                Slog.d(TAG, "Could not find task for id: "+ taskId);
8676                return;
8677            }
8678            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8679                mStackSupervisor.showLockTaskToast();
8680                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8681                return;
8682            }
8683            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8684            if (prev != null && prev.isRecentsActivity()) {
8685                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8686            }
8687            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8688        } finally {
8689            Binder.restoreCallingIdentity(origId);
8690        }
8691        ActivityOptions.abort(options);
8692    }
8693
8694    /**
8695     * Moves an activity, and all of the other activities within the same task, to the bottom
8696     * of the history stack.  The activity's order within the task is unchanged.
8697     *
8698     * @param token A reference to the activity we wish to move
8699     * @param nonRoot If false then this only works if the activity is the root
8700     *                of a task; if true it will work for any activity in a task.
8701     * @return Returns true if the move completed, false if not.
8702     */
8703    @Override
8704    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8705        enforceNotIsolatedCaller("moveActivityTaskToBack");
8706        synchronized(this) {
8707            final long origId = Binder.clearCallingIdentity();
8708            try {
8709                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8710                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8711                if (task != null) {
8712                    if (mStackSupervisor.isLockedTask(task)) {
8713                        mStackSupervisor.showLockTaskToast();
8714                        return false;
8715                    }
8716                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8717                }
8718            } finally {
8719                Binder.restoreCallingIdentity(origId);
8720            }
8721        }
8722        return false;
8723    }
8724
8725    @Override
8726    public void moveTaskBackwards(int task) {
8727        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8728                "moveTaskBackwards()");
8729
8730        synchronized(this) {
8731            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8732                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8733                return;
8734            }
8735            final long origId = Binder.clearCallingIdentity();
8736            moveTaskBackwardsLocked(task);
8737            Binder.restoreCallingIdentity(origId);
8738        }
8739    }
8740
8741    private final void moveTaskBackwardsLocked(int task) {
8742        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8743    }
8744
8745    @Override
8746    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8747            IActivityContainerCallback callback) throws RemoteException {
8748        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8749                "createActivityContainer()");
8750        synchronized (this) {
8751            if (parentActivityToken == null) {
8752                throw new IllegalArgumentException("parent token must not be null");
8753            }
8754            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8755            if (r == null) {
8756                return null;
8757            }
8758            if (callback == null) {
8759                throw new IllegalArgumentException("callback must not be null");
8760            }
8761            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8762        }
8763    }
8764
8765    @Override
8766    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8767        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8768                "deleteActivityContainer()");
8769        synchronized (this) {
8770            mStackSupervisor.deleteActivityContainer(container);
8771        }
8772    }
8773
8774    @Override
8775    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8776        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8777                "createStackOnDisplay()");
8778        synchronized (this) {
8779            final int stackId = mStackSupervisor.getNextStackId();
8780            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8781            if (stack == null) {
8782                return null;
8783            }
8784            return stack.mActivityContainer;
8785        }
8786    }
8787
8788    @Override
8789    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8790        synchronized (this) {
8791            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8792            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8793                return stack.mActivityContainer.getDisplayId();
8794            }
8795            return Display.DEFAULT_DISPLAY;
8796        }
8797    }
8798
8799    @Override
8800    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8801        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8802                "moveTaskToStack()");
8803        if (stackId == HOME_STACK_ID) {
8804            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8805                    new RuntimeException("here").fillInStackTrace());
8806        }
8807        synchronized (this) {
8808            long ident = Binder.clearCallingIdentity();
8809            try {
8810                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8811                        + " to stackId=" + stackId + " toTop=" + toTop);
8812                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8813            } finally {
8814                Binder.restoreCallingIdentity(ident);
8815            }
8816        }
8817    }
8818
8819    @Override
8820    public void resizeStack(int stackId, Rect bounds) {
8821        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8822                "resizeStack()");
8823        long ident = Binder.clearCallingIdentity();
8824        try {
8825            synchronized (this) {
8826                mStackSupervisor.resizeStackLocked(stackId, bounds);
8827            }
8828        } finally {
8829            Binder.restoreCallingIdentity(ident);
8830        }
8831    }
8832
8833    @Override
8834    public List<StackInfo> getAllStackInfos() {
8835        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8836                "getAllStackInfos()");
8837        long ident = Binder.clearCallingIdentity();
8838        try {
8839            synchronized (this) {
8840                return mStackSupervisor.getAllStackInfosLocked();
8841            }
8842        } finally {
8843            Binder.restoreCallingIdentity(ident);
8844        }
8845    }
8846
8847    @Override
8848    public StackInfo getStackInfo(int stackId) {
8849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8850                "getStackInfo()");
8851        long ident = Binder.clearCallingIdentity();
8852        try {
8853            synchronized (this) {
8854                return mStackSupervisor.getStackInfoLocked(stackId);
8855            }
8856        } finally {
8857            Binder.restoreCallingIdentity(ident);
8858        }
8859    }
8860
8861    @Override
8862    public boolean isInHomeStack(int taskId) {
8863        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8864                "getStackInfo()");
8865        long ident = Binder.clearCallingIdentity();
8866        try {
8867            synchronized (this) {
8868                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8869                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8870            }
8871        } finally {
8872            Binder.restoreCallingIdentity(ident);
8873        }
8874    }
8875
8876    @Override
8877    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8878        synchronized(this) {
8879            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8880        }
8881    }
8882
8883    @Override
8884    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId) {
8885        final int callingUid = Binder.getCallingUid();
8886        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8887            throw new SecurityException(
8888                    "updatePreferredSetupActivity called from non-system process");
8889        }
8890        synchronized (this) {
8891            if (preferredActivity == null) {
8892                mPreferredSetupActivities.delete(userId);
8893            } else {
8894                mPreferredSetupActivities.put(userId, preferredActivity);
8895            }
8896        }
8897    }
8898
8899    @Override
8900    public void updateDeviceOwner(String packageName) {
8901        final int callingUid = Binder.getCallingUid();
8902        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8903            throw new SecurityException("updateDeviceOwner called from non-system process");
8904        }
8905        synchronized (this) {
8906            mDeviceOwnerName = packageName;
8907        }
8908    }
8909
8910    @Override
8911    public void updateLockTaskPackages(int userId, String[] packages) {
8912        final int callingUid = Binder.getCallingUid();
8913        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8914            throw new SecurityException("updateLockTaskPackage called from non-system process");
8915        }
8916        synchronized (this) {
8917            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8918                    Arrays.toString(packages));
8919            mLockTaskPackages.put(userId, packages);
8920            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8921        }
8922    }
8923
8924
8925    void startLockTaskModeLocked(TaskRecord task) {
8926        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8927        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8928            return;
8929        }
8930
8931        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8932        // is initiated by system after the pinning request was shown and locked mode is initiated
8933        // by an authorized app directly
8934        final int callingUid = Binder.getCallingUid();
8935        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8936        long ident = Binder.clearCallingIdentity();
8937        try {
8938            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8939            if (!isSystemInitiated) {
8940                task.mLockTaskUid = callingUid;
8941                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8942                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8943                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8944                    StatusBarManagerInternal statusBarManager =
8945                            LocalServices.getService(StatusBarManagerInternal.class);
8946                    if (statusBarManager != null) {
8947                        statusBarManager.showScreenPinningRequest();
8948                    }
8949                    return;
8950                }
8951
8952                if (stack == null || task != stack.topTask()) {
8953                    throw new IllegalArgumentException("Invalid task, not in foreground");
8954                }
8955            }
8956            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8957                    "Locking fully");
8958            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8959                    ActivityManager.LOCK_TASK_MODE_PINNED :
8960                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8961                    "startLockTask", true);
8962        } finally {
8963            Binder.restoreCallingIdentity(ident);
8964        }
8965    }
8966
8967    @Override
8968    public void startLockTaskMode(int taskId) {
8969        synchronized (this) {
8970            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8971            if (task != null) {
8972                startLockTaskModeLocked(task);
8973            }
8974        }
8975    }
8976
8977    @Override
8978    public void startLockTaskMode(IBinder token) {
8979        synchronized (this) {
8980            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8981            if (r == null) {
8982                return;
8983            }
8984            final TaskRecord task = r.task;
8985            if (task != null) {
8986                startLockTaskModeLocked(task);
8987            }
8988        }
8989    }
8990
8991    @Override
8992    public void startLockTaskModeOnCurrent() throws RemoteException {
8993        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8994                "startLockTaskModeOnCurrent");
8995        long ident = Binder.clearCallingIdentity();
8996        try {
8997            synchronized (this) {
8998                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
8999                if (r != null) {
9000                    startLockTaskModeLocked(r.task);
9001                }
9002            }
9003        } finally {
9004            Binder.restoreCallingIdentity(ident);
9005        }
9006    }
9007
9008    @Override
9009    public void stopLockTaskMode() {
9010        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9011        if (lockTask == null) {
9012            // Our work here is done.
9013            return;
9014        }
9015        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9016        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9017                Binder.getCallingUid() != lockTask.mLockTaskUid) {
9018            throw new SecurityException("Invalid uid, expected " + lockTask.mLockTaskUid);
9019        }
9020        long ident = Binder.clearCallingIdentity();
9021        try {
9022            Log.d(TAG, "stopLockTaskMode");
9023            // Stop lock task
9024            synchronized (this) {
9025                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9026                        "stopLockTask", true);
9027            }
9028        } finally {
9029            Binder.restoreCallingIdentity(ident);
9030        }
9031    }
9032
9033    @Override
9034    public void stopLockTaskModeOnCurrent() throws RemoteException {
9035        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9036                "stopLockTaskModeOnCurrent");
9037        long ident = Binder.clearCallingIdentity();
9038        try {
9039            stopLockTaskMode();
9040        } finally {
9041            Binder.restoreCallingIdentity(ident);
9042        }
9043    }
9044
9045    @Override
9046    public boolean isInLockTaskMode() {
9047        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9048    }
9049
9050    @Override
9051    public int getLockTaskModeState() {
9052        synchronized (this) {
9053            return mStackSupervisor.getLockTaskModeState();
9054        }
9055    }
9056
9057    @Override
9058    public void showLockTaskEscapeMessage(IBinder token) {
9059        synchronized (this) {
9060            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9061            if (r == null) {
9062                return;
9063            }
9064            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9065        }
9066    }
9067
9068    // =========================================================
9069    // CONTENT PROVIDERS
9070    // =========================================================
9071
9072    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9073        List<ProviderInfo> providers = null;
9074        try {
9075            providers = AppGlobals.getPackageManager().
9076                queryContentProviders(app.processName, app.uid,
9077                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9078        } catch (RemoteException ex) {
9079        }
9080        if (DEBUG_MU) Slog.v(TAG_MU,
9081                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9082        int userId = app.userId;
9083        if (providers != null) {
9084            int N = providers.size();
9085            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9086            for (int i=0; i<N; i++) {
9087                ProviderInfo cpi =
9088                    (ProviderInfo)providers.get(i);
9089                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9090                        cpi.name, cpi.flags);
9091                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9092                    // This is a singleton provider, but a user besides the
9093                    // default user is asking to initialize a process it runs
9094                    // in...  well, no, it doesn't actually run in this process,
9095                    // it runs in the process of the default user.  Get rid of it.
9096                    providers.remove(i);
9097                    N--;
9098                    i--;
9099                    continue;
9100                }
9101
9102                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9103                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9104                if (cpr == null) {
9105                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9106                    mProviderMap.putProviderByClass(comp, cpr);
9107                }
9108                if (DEBUG_MU) Slog.v(TAG_MU,
9109                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9110                app.pubProviders.put(cpi.name, cpr);
9111                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9112                    // Don't add this if it is a platform component that is marked
9113                    // to run in multiple processes, because this is actually
9114                    // part of the framework so doesn't make sense to track as a
9115                    // separate apk in the process.
9116                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9117                            mProcessStats);
9118                }
9119                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9120            }
9121        }
9122        return providers;
9123    }
9124
9125    /**
9126     * Check if {@link ProcessRecord} has a possible chance at accessing the
9127     * given {@link ProviderInfo}. Final permission checking is always done
9128     * in {@link ContentProvider}.
9129     */
9130    private final String checkContentProviderPermissionLocked(
9131            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9132        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9133        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9134        boolean checkedGrants = false;
9135        if (checkUser) {
9136            // Looking for cross-user grants before enforcing the typical cross-users permissions
9137            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9138            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9139                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9140                    return null;
9141                }
9142                checkedGrants = true;
9143            }
9144            userId = handleIncomingUser(callingPid, callingUid, userId,
9145                    false, ALLOW_NON_FULL,
9146                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9147            if (userId != tmpTargetUserId) {
9148                // When we actually went to determine the final targer user ID, this ended
9149                // up different than our initial check for the authority.  This is because
9150                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9151                // SELF.  So we need to re-check the grants again.
9152                checkedGrants = false;
9153            }
9154        }
9155        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9156                cpi.applicationInfo.uid, cpi.exported)
9157                == PackageManager.PERMISSION_GRANTED) {
9158            return null;
9159        }
9160        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9161                cpi.applicationInfo.uid, cpi.exported)
9162                == PackageManager.PERMISSION_GRANTED) {
9163            return null;
9164        }
9165
9166        PathPermission[] pps = cpi.pathPermissions;
9167        if (pps != null) {
9168            int i = pps.length;
9169            while (i > 0) {
9170                i--;
9171                PathPermission pp = pps[i];
9172                String pprperm = pp.getReadPermission();
9173                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9174                        cpi.applicationInfo.uid, cpi.exported)
9175                        == PackageManager.PERMISSION_GRANTED) {
9176                    return null;
9177                }
9178                String ppwperm = pp.getWritePermission();
9179                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9180                        cpi.applicationInfo.uid, cpi.exported)
9181                        == PackageManager.PERMISSION_GRANTED) {
9182                    return null;
9183                }
9184            }
9185        }
9186        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9187            return null;
9188        }
9189
9190        String msg;
9191        if (!cpi.exported) {
9192            msg = "Permission Denial: opening provider " + cpi.name
9193                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9194                    + ", uid=" + callingUid + ") that is not exported from uid "
9195                    + cpi.applicationInfo.uid;
9196        } else {
9197            msg = "Permission Denial: opening provider " + cpi.name
9198                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9199                    + ", uid=" + callingUid + ") requires "
9200                    + cpi.readPermission + " or " + cpi.writePermission;
9201        }
9202        Slog.w(TAG, msg);
9203        return msg;
9204    }
9205
9206    /**
9207     * Returns if the ContentProvider has granted a uri to callingUid
9208     */
9209    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9210        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9211        if (perms != null) {
9212            for (int i=perms.size()-1; i>=0; i--) {
9213                GrantUri grantUri = perms.keyAt(i);
9214                if (grantUri.sourceUserId == userId || !checkUser) {
9215                    if (matchesProvider(grantUri.uri, cpi)) {
9216                        return true;
9217                    }
9218                }
9219            }
9220        }
9221        return false;
9222    }
9223
9224    /**
9225     * Returns true if the uri authority is one of the authorities specified in the provider.
9226     */
9227    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9228        String uriAuth = uri.getAuthority();
9229        String cpiAuth = cpi.authority;
9230        if (cpiAuth.indexOf(';') == -1) {
9231            return cpiAuth.equals(uriAuth);
9232        }
9233        String[] cpiAuths = cpiAuth.split(";");
9234        int length = cpiAuths.length;
9235        for (int i = 0; i < length; i++) {
9236            if (cpiAuths[i].equals(uriAuth)) return true;
9237        }
9238        return false;
9239    }
9240
9241    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9242            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9243        if (r != null) {
9244            for (int i=0; i<r.conProviders.size(); i++) {
9245                ContentProviderConnection conn = r.conProviders.get(i);
9246                if (conn.provider == cpr) {
9247                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9248                            "Adding provider requested by "
9249                            + r.processName + " from process "
9250                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9251                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9252                    if (stable) {
9253                        conn.stableCount++;
9254                        conn.numStableIncs++;
9255                    } else {
9256                        conn.unstableCount++;
9257                        conn.numUnstableIncs++;
9258                    }
9259                    return conn;
9260                }
9261            }
9262            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9263            if (stable) {
9264                conn.stableCount = 1;
9265                conn.numStableIncs = 1;
9266            } else {
9267                conn.unstableCount = 1;
9268                conn.numUnstableIncs = 1;
9269            }
9270            cpr.connections.add(conn);
9271            r.conProviders.add(conn);
9272            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9273            return conn;
9274        }
9275        cpr.addExternalProcessHandleLocked(externalProcessToken);
9276        return null;
9277    }
9278
9279    boolean decProviderCountLocked(ContentProviderConnection conn,
9280            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9281        if (conn != null) {
9282            cpr = conn.provider;
9283            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9284                    "Removing provider requested by "
9285                    + conn.client.processName + " from process "
9286                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9287                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9288            if (stable) {
9289                conn.stableCount--;
9290            } else {
9291                conn.unstableCount--;
9292            }
9293            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9294                cpr.connections.remove(conn);
9295                conn.client.conProviders.remove(conn);
9296                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9297                return true;
9298            }
9299            return false;
9300        }
9301        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9302        return false;
9303    }
9304
9305    private void checkTime(long startTime, String where) {
9306        long now = SystemClock.elapsedRealtime();
9307        if ((now-startTime) > 1000) {
9308            // If we are taking more than a second, log about it.
9309            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9310        }
9311    }
9312
9313    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9314            String name, IBinder token, boolean stable, int userId) {
9315        ContentProviderRecord cpr;
9316        ContentProviderConnection conn = null;
9317        ProviderInfo cpi = null;
9318
9319        synchronized(this) {
9320            long startTime = SystemClock.elapsedRealtime();
9321
9322            ProcessRecord r = null;
9323            if (caller != null) {
9324                r = getRecordForAppLocked(caller);
9325                if (r == null) {
9326                    throw new SecurityException(
9327                            "Unable to find app for caller " + caller
9328                          + " (pid=" + Binder.getCallingPid()
9329                          + ") when getting content provider " + name);
9330                }
9331            }
9332
9333            boolean checkCrossUser = true;
9334
9335            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9336
9337            // First check if this content provider has been published...
9338            cpr = mProviderMap.getProviderByName(name, userId);
9339            // If that didn't work, check if it exists for user 0 and then
9340            // verify that it's a singleton provider before using it.
9341            if (cpr == null && userId != UserHandle.USER_OWNER) {
9342                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9343                if (cpr != null) {
9344                    cpi = cpr.info;
9345                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9346                            cpi.name, cpi.flags)
9347                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9348                        userId = UserHandle.USER_OWNER;
9349                        checkCrossUser = false;
9350                    } else {
9351                        cpr = null;
9352                        cpi = null;
9353                    }
9354                }
9355            }
9356
9357            boolean providerRunning = cpr != null;
9358            if (providerRunning) {
9359                cpi = cpr.info;
9360                String msg;
9361                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9362                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9363                        != null) {
9364                    throw new SecurityException(msg);
9365                }
9366                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9367
9368                if (r != null && cpr.canRunHere(r)) {
9369                    // This provider has been published or is in the process
9370                    // of being published...  but it is also allowed to run
9371                    // in the caller's process, so don't make a connection
9372                    // and just let the caller instantiate its own instance.
9373                    ContentProviderHolder holder = cpr.newHolder(null);
9374                    // don't give caller the provider object, it needs
9375                    // to make its own.
9376                    holder.provider = null;
9377                    return holder;
9378                }
9379
9380                final long origId = Binder.clearCallingIdentity();
9381
9382                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9383
9384                // In this case the provider instance already exists, so we can
9385                // return it right away.
9386                conn = incProviderCountLocked(r, cpr, token, stable);
9387                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9388                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9389                        // If this is a perceptible app accessing the provider,
9390                        // make sure to count it as being accessed and thus
9391                        // back up on the LRU list.  This is good because
9392                        // content providers are often expensive to start.
9393                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9394                        updateLruProcessLocked(cpr.proc, false, null);
9395                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9396                    }
9397                }
9398
9399                if (cpr.proc != null) {
9400                    if (false) {
9401                        if (cpr.name.flattenToShortString().equals(
9402                                "com.android.providers.calendar/.CalendarProvider2")) {
9403                            Slog.v(TAG, "****************** KILLING "
9404                                + cpr.name.flattenToShortString());
9405                            Process.killProcess(cpr.proc.pid);
9406                        }
9407                    }
9408                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9409                    boolean success = updateOomAdjLocked(cpr.proc);
9410                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9411                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9412                    // NOTE: there is still a race here where a signal could be
9413                    // pending on the process even though we managed to update its
9414                    // adj level.  Not sure what to do about this, but at least
9415                    // the race is now smaller.
9416                    if (!success) {
9417                        // Uh oh...  it looks like the provider's process
9418                        // has been killed on us.  We need to wait for a new
9419                        // process to be started, and make sure its death
9420                        // doesn't kill our process.
9421                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9422                                + " is crashing; detaching " + r);
9423                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9424                        checkTime(startTime, "getContentProviderImpl: before appDied");
9425                        appDiedLocked(cpr.proc);
9426                        checkTime(startTime, "getContentProviderImpl: after appDied");
9427                        if (!lastRef) {
9428                            // This wasn't the last ref our process had on
9429                            // the provider...  we have now been killed, bail.
9430                            return null;
9431                        }
9432                        providerRunning = false;
9433                        conn = null;
9434                    }
9435                }
9436
9437                Binder.restoreCallingIdentity(origId);
9438            }
9439
9440            boolean singleton;
9441            if (!providerRunning) {
9442                try {
9443                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9444                    cpi = AppGlobals.getPackageManager().
9445                        resolveContentProvider(name,
9446                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9447                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9448                } catch (RemoteException ex) {
9449                }
9450                if (cpi == null) {
9451                    return null;
9452                }
9453                // If the provider is a singleton AND
9454                // (it's a call within the same user || the provider is a
9455                // privileged app)
9456                // Then allow connecting to the singleton provider
9457                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9458                        cpi.name, cpi.flags)
9459                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9460                if (singleton) {
9461                    userId = UserHandle.USER_OWNER;
9462                }
9463                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9464                checkTime(startTime, "getContentProviderImpl: got app info for user");
9465
9466                String msg;
9467                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9468                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9469                        != null) {
9470                    throw new SecurityException(msg);
9471                }
9472                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9473
9474                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9475                        && !cpi.processName.equals("system")) {
9476                    // If this content provider does not run in the system
9477                    // process, and the system is not yet ready to run other
9478                    // processes, then fail fast instead of hanging.
9479                    throw new IllegalArgumentException(
9480                            "Attempt to launch content provider before system ready");
9481                }
9482
9483                // Make sure that the user who owns this provider is running.  If not,
9484                // we don't want to allow it to run.
9485                if (!isUserRunningLocked(userId, false)) {
9486                    Slog.w(TAG, "Unable to launch app "
9487                            + cpi.applicationInfo.packageName + "/"
9488                            + cpi.applicationInfo.uid + " for provider "
9489                            + name + ": user " + userId + " is stopped");
9490                    return null;
9491                }
9492
9493                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9494                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9495                cpr = mProviderMap.getProviderByClass(comp, userId);
9496                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9497                final boolean firstClass = cpr == null;
9498                if (firstClass) {
9499                    final long ident = Binder.clearCallingIdentity();
9500                    try {
9501                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9502                        ApplicationInfo ai =
9503                            AppGlobals.getPackageManager().
9504                                getApplicationInfo(
9505                                        cpi.applicationInfo.packageName,
9506                                        STOCK_PM_FLAGS, userId);
9507                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9508                        if (ai == null) {
9509                            Slog.w(TAG, "No package info for content provider "
9510                                    + cpi.name);
9511                            return null;
9512                        }
9513                        ai = getAppInfoForUser(ai, userId);
9514                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9515                    } catch (RemoteException ex) {
9516                        // pm is in same process, this will never happen.
9517                    } finally {
9518                        Binder.restoreCallingIdentity(ident);
9519                    }
9520                }
9521
9522                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9523
9524                if (r != null && cpr.canRunHere(r)) {
9525                    // If this is a multiprocess provider, then just return its
9526                    // info and allow the caller to instantiate it.  Only do
9527                    // this if the provider is the same user as the caller's
9528                    // process, or can run as root (so can be in any process).
9529                    return cpr.newHolder(null);
9530                }
9531
9532                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9533                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9534                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9535
9536                // This is single process, and our app is now connecting to it.
9537                // See if we are already in the process of launching this
9538                // provider.
9539                final int N = mLaunchingProviders.size();
9540                int i;
9541                for (i = 0; i < N; i++) {
9542                    if (mLaunchingProviders.get(i) == cpr) {
9543                        break;
9544                    }
9545                }
9546
9547                // If the provider is not already being launched, then get it
9548                // started.
9549                if (i >= N) {
9550                    final long origId = Binder.clearCallingIdentity();
9551
9552                    try {
9553                        // Content provider is now in use, its package can't be stopped.
9554                        try {
9555                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9556                            AppGlobals.getPackageManager().setPackageStoppedState(
9557                                    cpr.appInfo.packageName, false, userId);
9558                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9559                        } catch (RemoteException e) {
9560                        } catch (IllegalArgumentException e) {
9561                            Slog.w(TAG, "Failed trying to unstop package "
9562                                    + cpr.appInfo.packageName + ": " + e);
9563                        }
9564
9565                        // Use existing process if already started
9566                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9567                        ProcessRecord proc = getProcessRecordLocked(
9568                                cpi.processName, cpr.appInfo.uid, false);
9569                        if (proc != null && proc.thread != null) {
9570                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9571                                    "Installing in existing process " + proc);
9572                            if (!proc.pubProviders.containsKey(cpi.name)) {
9573                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9574                                proc.pubProviders.put(cpi.name, cpr);
9575                                try {
9576                                    proc.thread.scheduleInstallProvider(cpi);
9577                                } catch (RemoteException e) {
9578                                }
9579                            }
9580                        } else {
9581                            checkTime(startTime, "getContentProviderImpl: before start process");
9582                            proc = startProcessLocked(cpi.processName,
9583                                    cpr.appInfo, false, 0, "content provider",
9584                                    new ComponentName(cpi.applicationInfo.packageName,
9585                                            cpi.name), false, false, false);
9586                            checkTime(startTime, "getContentProviderImpl: after start process");
9587                            if (proc == null) {
9588                                Slog.w(TAG, "Unable to launch app "
9589                                        + cpi.applicationInfo.packageName + "/"
9590                                        + cpi.applicationInfo.uid + " for provider "
9591                                        + name + ": process is bad");
9592                                return null;
9593                            }
9594                        }
9595                        cpr.launchingApp = proc;
9596                        mLaunchingProviders.add(cpr);
9597                    } finally {
9598                        Binder.restoreCallingIdentity(origId);
9599                    }
9600                }
9601
9602                checkTime(startTime, "getContentProviderImpl: updating data structures");
9603
9604                // Make sure the provider is published (the same provider class
9605                // may be published under multiple names).
9606                if (firstClass) {
9607                    mProviderMap.putProviderByClass(comp, cpr);
9608                }
9609
9610                mProviderMap.putProviderByName(name, cpr);
9611                conn = incProviderCountLocked(r, cpr, token, stable);
9612                if (conn != null) {
9613                    conn.waiting = true;
9614                }
9615            }
9616            checkTime(startTime, "getContentProviderImpl: done!");
9617        }
9618
9619        // Wait for the provider to be published...
9620        synchronized (cpr) {
9621            while (cpr.provider == null) {
9622                if (cpr.launchingApp == null) {
9623                    Slog.w(TAG, "Unable to launch app "
9624                            + cpi.applicationInfo.packageName + "/"
9625                            + cpi.applicationInfo.uid + " for provider "
9626                            + name + ": launching app became null");
9627                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9628                            UserHandle.getUserId(cpi.applicationInfo.uid),
9629                            cpi.applicationInfo.packageName,
9630                            cpi.applicationInfo.uid, name);
9631                    return null;
9632                }
9633                try {
9634                    if (DEBUG_MU) Slog.v(TAG_MU,
9635                            "Waiting to start provider " + cpr
9636                            + " launchingApp=" + cpr.launchingApp);
9637                    if (conn != null) {
9638                        conn.waiting = true;
9639                    }
9640                    cpr.wait();
9641                } catch (InterruptedException ex) {
9642                } finally {
9643                    if (conn != null) {
9644                        conn.waiting = false;
9645                    }
9646                }
9647            }
9648        }
9649        return cpr != null ? cpr.newHolder(conn) : null;
9650    }
9651
9652    @Override
9653    public final ContentProviderHolder getContentProvider(
9654            IApplicationThread caller, String name, int userId, boolean stable) {
9655        enforceNotIsolatedCaller("getContentProvider");
9656        if (caller == null) {
9657            String msg = "null IApplicationThread when getting content provider "
9658                    + name;
9659            Slog.w(TAG, msg);
9660            throw new SecurityException(msg);
9661        }
9662        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9663        // with cross-user grant.
9664        return getContentProviderImpl(caller, name, null, stable, userId);
9665    }
9666
9667    public ContentProviderHolder getContentProviderExternal(
9668            String name, int userId, IBinder token) {
9669        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9670            "Do not have permission in call getContentProviderExternal()");
9671        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9672                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9673        return getContentProviderExternalUnchecked(name, token, userId);
9674    }
9675
9676    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9677            IBinder token, int userId) {
9678        return getContentProviderImpl(null, name, token, true, userId);
9679    }
9680
9681    /**
9682     * Drop a content provider from a ProcessRecord's bookkeeping
9683     */
9684    public void removeContentProvider(IBinder connection, boolean stable) {
9685        enforceNotIsolatedCaller("removeContentProvider");
9686        long ident = Binder.clearCallingIdentity();
9687        try {
9688            synchronized (this) {
9689                ContentProviderConnection conn;
9690                try {
9691                    conn = (ContentProviderConnection)connection;
9692                } catch (ClassCastException e) {
9693                    String msg ="removeContentProvider: " + connection
9694                            + " not a ContentProviderConnection";
9695                    Slog.w(TAG, msg);
9696                    throw new IllegalArgumentException(msg);
9697                }
9698                if (conn == null) {
9699                    throw new NullPointerException("connection is null");
9700                }
9701                if (decProviderCountLocked(conn, null, null, stable)) {
9702                    updateOomAdjLocked();
9703                }
9704            }
9705        } finally {
9706            Binder.restoreCallingIdentity(ident);
9707        }
9708    }
9709
9710    public void removeContentProviderExternal(String name, IBinder token) {
9711        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9712            "Do not have permission in call removeContentProviderExternal()");
9713        int userId = UserHandle.getCallingUserId();
9714        long ident = Binder.clearCallingIdentity();
9715        try {
9716            removeContentProviderExternalUnchecked(name, token, userId);
9717        } finally {
9718            Binder.restoreCallingIdentity(ident);
9719        }
9720    }
9721
9722    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9723        synchronized (this) {
9724            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9725            if(cpr == null) {
9726                //remove from mProvidersByClass
9727                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9728                return;
9729            }
9730
9731            //update content provider record entry info
9732            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9733            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9734            if (localCpr.hasExternalProcessHandles()) {
9735                if (localCpr.removeExternalProcessHandleLocked(token)) {
9736                    updateOomAdjLocked();
9737                } else {
9738                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9739                            + " with no external reference for token: "
9740                            + token + ".");
9741                }
9742            } else {
9743                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9744                        + " with no external references.");
9745            }
9746        }
9747    }
9748
9749    public final void publishContentProviders(IApplicationThread caller,
9750            List<ContentProviderHolder> providers) {
9751        if (providers == null) {
9752            return;
9753        }
9754
9755        enforceNotIsolatedCaller("publishContentProviders");
9756        synchronized (this) {
9757            final ProcessRecord r = getRecordForAppLocked(caller);
9758            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9759            if (r == null) {
9760                throw new SecurityException(
9761                        "Unable to find app for caller " + caller
9762                      + " (pid=" + Binder.getCallingPid()
9763                      + ") when publishing content providers");
9764            }
9765
9766            final long origId = Binder.clearCallingIdentity();
9767
9768            final int N = providers.size();
9769            for (int i=0; i<N; i++) {
9770                ContentProviderHolder src = providers.get(i);
9771                if (src == null || src.info == null || src.provider == null) {
9772                    continue;
9773                }
9774                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9775                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9776                if (dst != null) {
9777                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9778                    mProviderMap.putProviderByClass(comp, dst);
9779                    String names[] = dst.info.authority.split(";");
9780                    for (int j = 0; j < names.length; j++) {
9781                        mProviderMap.putProviderByName(names[j], dst);
9782                    }
9783
9784                    int NL = mLaunchingProviders.size();
9785                    int j;
9786                    for (j=0; j<NL; j++) {
9787                        if (mLaunchingProviders.get(j) == dst) {
9788                            mLaunchingProviders.remove(j);
9789                            j--;
9790                            NL--;
9791                        }
9792                    }
9793                    synchronized (dst) {
9794                        dst.provider = src.provider;
9795                        dst.proc = r;
9796                        dst.notifyAll();
9797                    }
9798                    updateOomAdjLocked(r);
9799                }
9800            }
9801
9802            Binder.restoreCallingIdentity(origId);
9803        }
9804    }
9805
9806    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9807        ContentProviderConnection conn;
9808        try {
9809            conn = (ContentProviderConnection)connection;
9810        } catch (ClassCastException e) {
9811            String msg ="refContentProvider: " + connection
9812                    + " not a ContentProviderConnection";
9813            Slog.w(TAG, msg);
9814            throw new IllegalArgumentException(msg);
9815        }
9816        if (conn == null) {
9817            throw new NullPointerException("connection is null");
9818        }
9819
9820        synchronized (this) {
9821            if (stable > 0) {
9822                conn.numStableIncs += stable;
9823            }
9824            stable = conn.stableCount + stable;
9825            if (stable < 0) {
9826                throw new IllegalStateException("stableCount < 0: " + stable);
9827            }
9828
9829            if (unstable > 0) {
9830                conn.numUnstableIncs += unstable;
9831            }
9832            unstable = conn.unstableCount + unstable;
9833            if (unstable < 0) {
9834                throw new IllegalStateException("unstableCount < 0: " + unstable);
9835            }
9836
9837            if ((stable+unstable) <= 0) {
9838                throw new IllegalStateException("ref counts can't go to zero here: stable="
9839                        + stable + " unstable=" + unstable);
9840            }
9841            conn.stableCount = stable;
9842            conn.unstableCount = unstable;
9843            return !conn.dead;
9844        }
9845    }
9846
9847    public void unstableProviderDied(IBinder connection) {
9848        ContentProviderConnection conn;
9849        try {
9850            conn = (ContentProviderConnection)connection;
9851        } catch (ClassCastException e) {
9852            String msg ="refContentProvider: " + connection
9853                    + " not a ContentProviderConnection";
9854            Slog.w(TAG, msg);
9855            throw new IllegalArgumentException(msg);
9856        }
9857        if (conn == null) {
9858            throw new NullPointerException("connection is null");
9859        }
9860
9861        // Safely retrieve the content provider associated with the connection.
9862        IContentProvider provider;
9863        synchronized (this) {
9864            provider = conn.provider.provider;
9865        }
9866
9867        if (provider == null) {
9868            // Um, yeah, we're way ahead of you.
9869            return;
9870        }
9871
9872        // Make sure the caller is being honest with us.
9873        if (provider.asBinder().pingBinder()) {
9874            // Er, no, still looks good to us.
9875            synchronized (this) {
9876                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9877                        + " says " + conn + " died, but we don't agree");
9878                return;
9879            }
9880        }
9881
9882        // Well look at that!  It's dead!
9883        synchronized (this) {
9884            if (conn.provider.provider != provider) {
9885                // But something changed...  good enough.
9886                return;
9887            }
9888
9889            ProcessRecord proc = conn.provider.proc;
9890            if (proc == null || proc.thread == null) {
9891                // Seems like the process is already cleaned up.
9892                return;
9893            }
9894
9895            // As far as we're concerned, this is just like receiving a
9896            // death notification...  just a bit prematurely.
9897            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9898                    + ") early provider death");
9899            final long ident = Binder.clearCallingIdentity();
9900            try {
9901                appDiedLocked(proc);
9902            } finally {
9903                Binder.restoreCallingIdentity(ident);
9904            }
9905        }
9906    }
9907
9908    @Override
9909    public void appNotRespondingViaProvider(IBinder connection) {
9910        enforceCallingPermission(
9911                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9912
9913        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9914        if (conn == null) {
9915            Slog.w(TAG, "ContentProviderConnection is null");
9916            return;
9917        }
9918
9919        final ProcessRecord host = conn.provider.proc;
9920        if (host == null) {
9921            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9922            return;
9923        }
9924
9925        final long token = Binder.clearCallingIdentity();
9926        try {
9927            appNotResponding(host, null, null, false, "ContentProvider not responding");
9928        } finally {
9929            Binder.restoreCallingIdentity(token);
9930        }
9931    }
9932
9933    public final void installSystemProviders() {
9934        List<ProviderInfo> providers;
9935        synchronized (this) {
9936            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9937            providers = generateApplicationProvidersLocked(app);
9938            if (providers != null) {
9939                for (int i=providers.size()-1; i>=0; i--) {
9940                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9941                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9942                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9943                                + ": not system .apk");
9944                        providers.remove(i);
9945                    }
9946                }
9947            }
9948        }
9949        if (providers != null) {
9950            mSystemThread.installSystemProviders(providers);
9951        }
9952
9953        mCoreSettingsObserver = new CoreSettingsObserver(this);
9954
9955        //mUsageStatsService.monitorPackages();
9956    }
9957
9958    /**
9959     * Allows apps to retrieve the MIME type of a URI.
9960     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9961     * users, then it does not need permission to access the ContentProvider.
9962     * Either, it needs cross-user uri grants.
9963     *
9964     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9965     *
9966     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9967     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9968     */
9969    public String getProviderMimeType(Uri uri, int userId) {
9970        enforceNotIsolatedCaller("getProviderMimeType");
9971        final String name = uri.getAuthority();
9972        int callingUid = Binder.getCallingUid();
9973        int callingPid = Binder.getCallingPid();
9974        long ident = 0;
9975        boolean clearedIdentity = false;
9976        userId = unsafeConvertIncomingUser(userId);
9977        if (canClearIdentity(callingPid, callingUid, userId)) {
9978            clearedIdentity = true;
9979            ident = Binder.clearCallingIdentity();
9980        }
9981        ContentProviderHolder holder = null;
9982        try {
9983            holder = getContentProviderExternalUnchecked(name, null, userId);
9984            if (holder != null) {
9985                return holder.provider.getType(uri);
9986            }
9987        } catch (RemoteException e) {
9988            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9989            return null;
9990        } finally {
9991            // We need to clear the identity to call removeContentProviderExternalUnchecked
9992            if (!clearedIdentity) {
9993                ident = Binder.clearCallingIdentity();
9994            }
9995            try {
9996                if (holder != null) {
9997                    removeContentProviderExternalUnchecked(name, null, userId);
9998                }
9999            } finally {
10000                Binder.restoreCallingIdentity(ident);
10001            }
10002        }
10003
10004        return null;
10005    }
10006
10007    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10008        if (UserHandle.getUserId(callingUid) == userId) {
10009            return true;
10010        }
10011        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10012                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10013                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10014                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10015                return true;
10016        }
10017        return false;
10018    }
10019
10020    // =========================================================
10021    // GLOBAL MANAGEMENT
10022    // =========================================================
10023
10024    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10025            boolean isolated, int isolatedUid) {
10026        String proc = customProcess != null ? customProcess : info.processName;
10027        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10028        final int userId = UserHandle.getUserId(info.uid);
10029        int uid = info.uid;
10030        if (isolated) {
10031            if (isolatedUid == 0) {
10032                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10033                while (true) {
10034                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10035                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10036                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10037                    }
10038                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10039                    mNextIsolatedProcessUid++;
10040                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10041                        // No process for this uid, use it.
10042                        break;
10043                    }
10044                    stepsLeft--;
10045                    if (stepsLeft <= 0) {
10046                        return null;
10047                    }
10048                }
10049            } else {
10050                // Special case for startIsolatedProcess (internal only), where
10051                // the uid of the isolated process is specified by the caller.
10052                uid = isolatedUid;
10053            }
10054        }
10055        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10056        if (!mBooted && !mBooting
10057                && userId == UserHandle.USER_OWNER
10058                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10059            r.persistent = true;
10060        }
10061        addProcessNameLocked(r);
10062        return r;
10063    }
10064
10065    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10066            String abiOverride) {
10067        ProcessRecord app;
10068        if (!isolated) {
10069            app = getProcessRecordLocked(info.processName, info.uid, true);
10070        } else {
10071            app = null;
10072        }
10073
10074        if (app == null) {
10075            app = newProcessRecordLocked(info, null, isolated, 0);
10076            updateLruProcessLocked(app, false, null);
10077            updateOomAdjLocked();
10078        }
10079
10080        // This package really, really can not be stopped.
10081        try {
10082            AppGlobals.getPackageManager().setPackageStoppedState(
10083                    info.packageName, false, UserHandle.getUserId(app.uid));
10084        } catch (RemoteException e) {
10085        } catch (IllegalArgumentException e) {
10086            Slog.w(TAG, "Failed trying to unstop package "
10087                    + info.packageName + ": " + e);
10088        }
10089
10090        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10091            app.persistent = true;
10092            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10093        }
10094        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10095            mPersistentStartingProcesses.add(app);
10096            startProcessLocked(app, "added application", app.processName, abiOverride,
10097                    null /* entryPoint */, null /* entryPointArgs */);
10098        }
10099
10100        return app;
10101    }
10102
10103    public void unhandledBack() {
10104        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10105                "unhandledBack()");
10106
10107        synchronized(this) {
10108            final long origId = Binder.clearCallingIdentity();
10109            try {
10110                getFocusedStack().unhandledBackLocked();
10111            } finally {
10112                Binder.restoreCallingIdentity(origId);
10113            }
10114        }
10115    }
10116
10117    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10118        enforceNotIsolatedCaller("openContentUri");
10119        final int userId = UserHandle.getCallingUserId();
10120        String name = uri.getAuthority();
10121        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10122        ParcelFileDescriptor pfd = null;
10123        if (cph != null) {
10124            // We record the binder invoker's uid in thread-local storage before
10125            // going to the content provider to open the file.  Later, in the code
10126            // that handles all permissions checks, we look for this uid and use
10127            // that rather than the Activity Manager's own uid.  The effect is that
10128            // we do the check against the caller's permissions even though it looks
10129            // to the content provider like the Activity Manager itself is making
10130            // the request.
10131            Binder token = new Binder();
10132            sCallerIdentity.set(new Identity(
10133                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10134            try {
10135                pfd = cph.provider.openFile(null, uri, "r", null, token);
10136            } catch (FileNotFoundException e) {
10137                // do nothing; pfd will be returned null
10138            } finally {
10139                // Ensure that whatever happens, we clean up the identity state
10140                sCallerIdentity.remove();
10141                // Ensure we're done with the provider.
10142                removeContentProviderExternalUnchecked(name, null, userId);
10143            }
10144        } else {
10145            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10146        }
10147        return pfd;
10148    }
10149
10150    // Actually is sleeping or shutting down or whatever else in the future
10151    // is an inactive state.
10152    public boolean isSleepingOrShuttingDown() {
10153        return isSleeping() || mShuttingDown;
10154    }
10155
10156    public boolean isSleeping() {
10157        return mSleeping;
10158    }
10159
10160    void onWakefulnessChanged(int wakefulness) {
10161        synchronized(this) {
10162            mWakefulness = wakefulness;
10163            updateSleepIfNeededLocked();
10164        }
10165    }
10166
10167    void finishRunningVoiceLocked() {
10168        if (mRunningVoice != null) {
10169            mRunningVoice = null;
10170            updateSleepIfNeededLocked();
10171        }
10172    }
10173
10174    void startTimeTrackingFocusedActivityLocked() {
10175        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10176            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10177        }
10178    }
10179
10180    void updateSleepIfNeededLocked() {
10181        if (mSleeping && !shouldSleepLocked()) {
10182            mSleeping = false;
10183            startTimeTrackingFocusedActivityLocked();
10184            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10185            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10186            updateOomAdjLocked();
10187        } else if (!mSleeping && shouldSleepLocked()) {
10188            mSleeping = true;
10189            if (mCurAppTimeTracker != null) {
10190                mCurAppTimeTracker.stop();
10191            }
10192            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10193            mStackSupervisor.goingToSleepLocked();
10194            updateOomAdjLocked();
10195
10196            // Initialize the wake times of all processes.
10197            checkExcessivePowerUsageLocked(false);
10198            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10199            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10200            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10201        }
10202    }
10203
10204    private boolean shouldSleepLocked() {
10205        // Resume applications while running a voice interactor.
10206        if (mRunningVoice != null) {
10207            return false;
10208        }
10209
10210        // TODO: Transform the lock screen state into a sleep token instead.
10211        switch (mWakefulness) {
10212            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10213            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10214            case PowerManagerInternal.WAKEFULNESS_DOZING:
10215                // Pause applications whenever the lock screen is shown or any sleep
10216                // tokens have been acquired.
10217                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10218            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10219            default:
10220                // If we're asleep then pause applications unconditionally.
10221                return true;
10222        }
10223    }
10224
10225    /** Pokes the task persister. */
10226    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10227        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10228            // Never persist the home stack.
10229            return;
10230        }
10231        mTaskPersister.wakeup(task, flush);
10232    }
10233
10234    /** Notifies all listeners when the task stack has changed. */
10235    void notifyTaskStackChangedLocked() {
10236        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10237        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10238        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10239    }
10240
10241    @Override
10242    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10243        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10244    }
10245
10246    @Override
10247    public boolean shutdown(int timeout) {
10248        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10249                != PackageManager.PERMISSION_GRANTED) {
10250            throw new SecurityException("Requires permission "
10251                    + android.Manifest.permission.SHUTDOWN);
10252        }
10253
10254        boolean timedout = false;
10255
10256        synchronized(this) {
10257            mShuttingDown = true;
10258            updateEventDispatchingLocked();
10259            timedout = mStackSupervisor.shutdownLocked(timeout);
10260        }
10261
10262        mAppOpsService.shutdown();
10263        if (mUsageStatsService != null) {
10264            mUsageStatsService.prepareShutdown();
10265        }
10266        mBatteryStatsService.shutdown();
10267        synchronized (this) {
10268            mProcessStats.shutdownLocked();
10269            notifyTaskPersisterLocked(null, true);
10270        }
10271
10272        return timedout;
10273    }
10274
10275    public final void activitySlept(IBinder token) {
10276        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10277
10278        final long origId = Binder.clearCallingIdentity();
10279
10280        synchronized (this) {
10281            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10282            if (r != null) {
10283                mStackSupervisor.activitySleptLocked(r);
10284            }
10285        }
10286
10287        Binder.restoreCallingIdentity(origId);
10288    }
10289
10290    private String lockScreenShownToString() {
10291        switch (mLockScreenShown) {
10292            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10293            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10294            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10295            default: return "Unknown=" + mLockScreenShown;
10296        }
10297    }
10298
10299    void logLockScreen(String msg) {
10300        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10301                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10302                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10303                + " mSleeping=" + mSleeping);
10304    }
10305
10306    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10307        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10308        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10309            if (mRunningVoice == null) {
10310                mVoiceWakeLock.acquire();
10311                updateSleepIfNeededLocked();
10312            }
10313            mRunningVoice = session;
10314        }
10315    }
10316
10317    private void updateEventDispatchingLocked() {
10318        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10319    }
10320
10321    public void setLockScreenShown(boolean shown) {
10322        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10323                != PackageManager.PERMISSION_GRANTED) {
10324            throw new SecurityException("Requires permission "
10325                    + android.Manifest.permission.DEVICE_POWER);
10326        }
10327
10328        synchronized(this) {
10329            long ident = Binder.clearCallingIdentity();
10330            try {
10331                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10332                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10333                updateSleepIfNeededLocked();
10334            } finally {
10335                Binder.restoreCallingIdentity(ident);
10336            }
10337        }
10338    }
10339
10340    @Override
10341    public void stopAppSwitches() {
10342        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10343                != PackageManager.PERMISSION_GRANTED) {
10344            throw new SecurityException("Requires permission "
10345                    + android.Manifest.permission.STOP_APP_SWITCHES);
10346        }
10347
10348        synchronized(this) {
10349            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10350                    + APP_SWITCH_DELAY_TIME;
10351            mDidAppSwitch = false;
10352            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10353            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10354            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10355        }
10356    }
10357
10358    public void resumeAppSwitches() {
10359        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10360                != PackageManager.PERMISSION_GRANTED) {
10361            throw new SecurityException("Requires permission "
10362                    + android.Manifest.permission.STOP_APP_SWITCHES);
10363        }
10364
10365        synchronized(this) {
10366            // Note that we don't execute any pending app switches... we will
10367            // let those wait until either the timeout, or the next start
10368            // activity request.
10369            mAppSwitchesAllowedTime = 0;
10370        }
10371    }
10372
10373    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10374            int callingPid, int callingUid, String name) {
10375        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10376            return true;
10377        }
10378
10379        int perm = checkComponentPermission(
10380                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10381                sourceUid, -1, true);
10382        if (perm == PackageManager.PERMISSION_GRANTED) {
10383            return true;
10384        }
10385
10386        // If the actual IPC caller is different from the logical source, then
10387        // also see if they are allowed to control app switches.
10388        if (callingUid != -1 && callingUid != sourceUid) {
10389            perm = checkComponentPermission(
10390                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10391                    callingUid, -1, true);
10392            if (perm == PackageManager.PERMISSION_GRANTED) {
10393                return true;
10394            }
10395        }
10396
10397        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10398        return false;
10399    }
10400
10401    public void setDebugApp(String packageName, boolean waitForDebugger,
10402            boolean persistent) {
10403        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10404                "setDebugApp()");
10405
10406        long ident = Binder.clearCallingIdentity();
10407        try {
10408            // Note that this is not really thread safe if there are multiple
10409            // callers into it at the same time, but that's not a situation we
10410            // care about.
10411            if (persistent) {
10412                final ContentResolver resolver = mContext.getContentResolver();
10413                Settings.Global.putString(
10414                    resolver, Settings.Global.DEBUG_APP,
10415                    packageName);
10416                Settings.Global.putInt(
10417                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10418                    waitForDebugger ? 1 : 0);
10419            }
10420
10421            synchronized (this) {
10422                if (!persistent) {
10423                    mOrigDebugApp = mDebugApp;
10424                    mOrigWaitForDebugger = mWaitForDebugger;
10425                }
10426                mDebugApp = packageName;
10427                mWaitForDebugger = waitForDebugger;
10428                mDebugTransient = !persistent;
10429                if (packageName != null) {
10430                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10431                            false, UserHandle.USER_ALL, "set debug app");
10432                }
10433            }
10434        } finally {
10435            Binder.restoreCallingIdentity(ident);
10436        }
10437    }
10438
10439    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10440        synchronized (this) {
10441            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10442            if (!isDebuggable) {
10443                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10444                    throw new SecurityException("Process not debuggable: " + app.packageName);
10445                }
10446            }
10447
10448            mOpenGlTraceApp = processName;
10449        }
10450    }
10451
10452    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10453        synchronized (this) {
10454            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10455            if (!isDebuggable) {
10456                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10457                    throw new SecurityException("Process not debuggable: " + app.packageName);
10458                }
10459            }
10460            mProfileApp = processName;
10461            mProfileFile = profilerInfo.profileFile;
10462            if (mProfileFd != null) {
10463                try {
10464                    mProfileFd.close();
10465                } catch (IOException e) {
10466                }
10467                mProfileFd = null;
10468            }
10469            mProfileFd = profilerInfo.profileFd;
10470            mSamplingInterval = profilerInfo.samplingInterval;
10471            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10472            mProfileType = 0;
10473        }
10474    }
10475
10476    @Override
10477    public void setAlwaysFinish(boolean enabled) {
10478        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10479                "setAlwaysFinish()");
10480
10481        Settings.Global.putInt(
10482                mContext.getContentResolver(),
10483                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10484
10485        synchronized (this) {
10486            mAlwaysFinishActivities = enabled;
10487        }
10488    }
10489
10490    @Override
10491    public void setActivityController(IActivityController controller) {
10492        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10493                "setActivityController()");
10494        synchronized (this) {
10495            mController = controller;
10496            Watchdog.getInstance().setActivityController(controller);
10497        }
10498    }
10499
10500    @Override
10501    public void setUserIsMonkey(boolean userIsMonkey) {
10502        synchronized (this) {
10503            synchronized (mPidsSelfLocked) {
10504                final int callingPid = Binder.getCallingPid();
10505                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10506                if (precessRecord == null) {
10507                    throw new SecurityException("Unknown process: " + callingPid);
10508                }
10509                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10510                    throw new SecurityException("Only an instrumentation process "
10511                            + "with a UiAutomation can call setUserIsMonkey");
10512                }
10513            }
10514            mUserIsMonkey = userIsMonkey;
10515        }
10516    }
10517
10518    @Override
10519    public boolean isUserAMonkey() {
10520        synchronized (this) {
10521            // If there is a controller also implies the user is a monkey.
10522            return (mUserIsMonkey || mController != null);
10523        }
10524    }
10525
10526    public void requestBugReport() {
10527        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10528        SystemProperties.set("ctl.start", "bugreport");
10529    }
10530
10531    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10532        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10533    }
10534
10535    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10536        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10537            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10538        }
10539        return KEY_DISPATCHING_TIMEOUT;
10540    }
10541
10542    @Override
10543    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10544        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10545                != PackageManager.PERMISSION_GRANTED) {
10546            throw new SecurityException("Requires permission "
10547                    + android.Manifest.permission.FILTER_EVENTS);
10548        }
10549        ProcessRecord proc;
10550        long timeout;
10551        synchronized (this) {
10552            synchronized (mPidsSelfLocked) {
10553                proc = mPidsSelfLocked.get(pid);
10554            }
10555            timeout = getInputDispatchingTimeoutLocked(proc);
10556        }
10557
10558        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10559            return -1;
10560        }
10561
10562        return timeout;
10563    }
10564
10565    /**
10566     * Handle input dispatching timeouts.
10567     * Returns whether input dispatching should be aborted or not.
10568     */
10569    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10570            final ActivityRecord activity, final ActivityRecord parent,
10571            final boolean aboveSystem, String reason) {
10572        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10573                != PackageManager.PERMISSION_GRANTED) {
10574            throw new SecurityException("Requires permission "
10575                    + android.Manifest.permission.FILTER_EVENTS);
10576        }
10577
10578        final String annotation;
10579        if (reason == null) {
10580            annotation = "Input dispatching timed out";
10581        } else {
10582            annotation = "Input dispatching timed out (" + reason + ")";
10583        }
10584
10585        if (proc != null) {
10586            synchronized (this) {
10587                if (proc.debugging) {
10588                    return false;
10589                }
10590
10591                if (mDidDexOpt) {
10592                    // Give more time since we were dexopting.
10593                    mDidDexOpt = false;
10594                    return false;
10595                }
10596
10597                if (proc.instrumentationClass != null) {
10598                    Bundle info = new Bundle();
10599                    info.putString("shortMsg", "keyDispatchingTimedOut");
10600                    info.putString("longMsg", annotation);
10601                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10602                    return true;
10603                }
10604            }
10605            mHandler.post(new Runnable() {
10606                @Override
10607                public void run() {
10608                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10609                }
10610            });
10611        }
10612
10613        return true;
10614    }
10615
10616    @Override
10617    public Bundle getAssistContextExtras(int requestType) {
10618        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10619                UserHandle.getCallingUserId(), PENDING_ASSIST_EXTRAS_TIMEOUT);
10620        if (pae == null) {
10621            return null;
10622        }
10623        synchronized (pae) {
10624            while (!pae.haveResult) {
10625                try {
10626                    pae.wait();
10627                } catch (InterruptedException e) {
10628                }
10629            }
10630        }
10631        synchronized (this) {
10632            buildAssistBundleLocked(pae, pae.result);
10633            mPendingAssistExtras.remove(pae);
10634            mHandler.removeCallbacks(pae);
10635        }
10636        return pae.extras;
10637    }
10638
10639    @Override
10640    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10641        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10642                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10643    }
10644
10645    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10646            IResultReceiver receiver, int userHandle, long timeout) {
10647        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10648                "enqueueAssistContext()");
10649        synchronized (this) {
10650            ActivityRecord activity = getFocusedStack().topActivity();
10651            if (activity == null) {
10652                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10653                return null;
10654            }
10655            if (activity.app == null || activity.app.thread == null) {
10656                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10657                return null;
10658            }
10659            if (activity.app.pid == Binder.getCallingPid()) {
10660                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10661                return null;
10662            }
10663            PendingAssistExtras pae;
10664            Bundle extras = new Bundle();
10665            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10666            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10667            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10668            try {
10669                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10670                        requestType);
10671                mPendingAssistExtras.add(pae);
10672                mHandler.postDelayed(pae, timeout);
10673            } catch (RemoteException e) {
10674                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10675                return null;
10676            }
10677            return pae;
10678        }
10679    }
10680
10681    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10682        mPendingAssistExtras.remove(pae);
10683        if (pae.receiver != null) {
10684            // Caller wants result sent back to them.
10685            try {
10686                pae.receiver.send(0, null);
10687            } catch (RemoteException e) {
10688            }
10689        }
10690    }
10691
10692    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10693        if (result != null) {
10694            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10695        }
10696        if (pae.hint != null) {
10697            pae.extras.putBoolean(pae.hint, true);
10698        }
10699    }
10700
10701    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10702            AssistContent content) {
10703        PendingAssistExtras pae = (PendingAssistExtras)token;
10704        synchronized (pae) {
10705            pae.result = extras;
10706            pae.structure = structure;
10707            pae.content = content;
10708            pae.haveResult = true;
10709            pae.notifyAll();
10710            if (pae.intent == null && pae.receiver == null) {
10711                // Caller is just waiting for the result.
10712                return;
10713            }
10714        }
10715
10716        // We are now ready to launch the assist activity.
10717        synchronized (this) {
10718            buildAssistBundleLocked(pae, extras);
10719            boolean exists = mPendingAssistExtras.remove(pae);
10720            mHandler.removeCallbacks(pae);
10721            if (!exists) {
10722                // Timed out.
10723                return;
10724            }
10725            if (pae.receiver != null) {
10726                // Caller wants result sent back to them.
10727                Bundle topBundle = new Bundle();
10728                topBundle.putBundle("data", pae.extras);
10729                topBundle.putParcelable("structure", pae.structure);
10730                topBundle.putParcelable("content", pae.content);
10731                try {
10732                    pae.receiver.send(0, topBundle);
10733                } catch (RemoteException e) {
10734                }
10735                return;
10736            }
10737        }
10738        pae.intent.replaceExtras(pae.extras);
10739        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10740                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10741                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10742        closeSystemDialogs("assist");
10743        try {
10744            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10745        } catch (ActivityNotFoundException e) {
10746            Slog.w(TAG, "No activity to handle assist action.", e);
10747        }
10748    }
10749
10750    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10751        return enqueueAssistContext(requestType, intent, hint, null, userHandle,
10752                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10753    }
10754
10755    public void registerProcessObserver(IProcessObserver observer) {
10756        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10757                "registerProcessObserver()");
10758        synchronized (this) {
10759            mProcessObservers.register(observer);
10760        }
10761    }
10762
10763    @Override
10764    public void unregisterProcessObserver(IProcessObserver observer) {
10765        synchronized (this) {
10766            mProcessObservers.unregister(observer);
10767        }
10768    }
10769
10770    public void registerUidObserver(IUidObserver observer) {
10771        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10772                "registerUidObserver()");
10773        synchronized (this) {
10774            mUidObservers.register(observer);
10775        }
10776    }
10777
10778    @Override
10779    public void unregisterUidObserver(IUidObserver observer) {
10780        synchronized (this) {
10781            mUidObservers.unregister(observer);
10782        }
10783    }
10784
10785    @Override
10786    public boolean convertFromTranslucent(IBinder token) {
10787        final long origId = Binder.clearCallingIdentity();
10788        try {
10789            synchronized (this) {
10790                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10791                if (r == null) {
10792                    return false;
10793                }
10794                final boolean translucentChanged = r.changeWindowTranslucency(true);
10795                if (translucentChanged) {
10796                    r.task.stack.releaseBackgroundResources(r);
10797                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10798                }
10799                mWindowManager.setAppFullscreen(token, true);
10800                return translucentChanged;
10801            }
10802        } finally {
10803            Binder.restoreCallingIdentity(origId);
10804        }
10805    }
10806
10807    @Override
10808    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10809        final long origId = Binder.clearCallingIdentity();
10810        try {
10811            synchronized (this) {
10812                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10813                if (r == null) {
10814                    return false;
10815                }
10816                int index = r.task.mActivities.lastIndexOf(r);
10817                if (index > 0) {
10818                    ActivityRecord under = r.task.mActivities.get(index - 1);
10819                    under.returningOptions = options;
10820                }
10821                final boolean translucentChanged = r.changeWindowTranslucency(false);
10822                if (translucentChanged) {
10823                    r.task.stack.convertActivityToTranslucent(r);
10824                }
10825                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10826                mWindowManager.setAppFullscreen(token, false);
10827                return translucentChanged;
10828            }
10829        } finally {
10830            Binder.restoreCallingIdentity(origId);
10831        }
10832    }
10833
10834    @Override
10835    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10836        final long origId = Binder.clearCallingIdentity();
10837        try {
10838            synchronized (this) {
10839                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10840                if (r != null) {
10841                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10842                }
10843            }
10844            return false;
10845        } finally {
10846            Binder.restoreCallingIdentity(origId);
10847        }
10848    }
10849
10850    @Override
10851    public boolean isBackgroundVisibleBehind(IBinder token) {
10852        final long origId = Binder.clearCallingIdentity();
10853        try {
10854            synchronized (this) {
10855                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10856                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10857                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10858                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10859                return visible;
10860            }
10861        } finally {
10862            Binder.restoreCallingIdentity(origId);
10863        }
10864    }
10865
10866    @Override
10867    public ActivityOptions getActivityOptions(IBinder token) {
10868        final long origId = Binder.clearCallingIdentity();
10869        try {
10870            synchronized (this) {
10871                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10872                if (r != null) {
10873                    final ActivityOptions activityOptions = r.pendingOptions;
10874                    r.pendingOptions = null;
10875                    return activityOptions;
10876                }
10877                return null;
10878            }
10879        } finally {
10880            Binder.restoreCallingIdentity(origId);
10881        }
10882    }
10883
10884    @Override
10885    public void setImmersive(IBinder token, boolean immersive) {
10886        synchronized(this) {
10887            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10888            if (r == null) {
10889                throw new IllegalArgumentException();
10890            }
10891            r.immersive = immersive;
10892
10893            // update associated state if we're frontmost
10894            if (r == mFocusedActivity) {
10895                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10896                applyUpdateLockStateLocked(r);
10897            }
10898        }
10899    }
10900
10901    @Override
10902    public boolean isImmersive(IBinder token) {
10903        synchronized (this) {
10904            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10905            if (r == null) {
10906                throw new IllegalArgumentException();
10907            }
10908            return r.immersive;
10909        }
10910    }
10911
10912    public boolean isTopActivityImmersive() {
10913        enforceNotIsolatedCaller("startActivity");
10914        synchronized (this) {
10915            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10916            return (r != null) ? r.immersive : false;
10917        }
10918    }
10919
10920    @Override
10921    public boolean isTopOfTask(IBinder token) {
10922        synchronized (this) {
10923            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10924            if (r == null) {
10925                throw new IllegalArgumentException();
10926            }
10927            return r.task.getTopActivity() == r;
10928        }
10929    }
10930
10931    public final void enterSafeMode() {
10932        synchronized(this) {
10933            // It only makes sense to do this before the system is ready
10934            // and started launching other packages.
10935            if (!mSystemReady) {
10936                try {
10937                    AppGlobals.getPackageManager().enterSafeMode();
10938                } catch (RemoteException e) {
10939                }
10940            }
10941
10942            mSafeMode = true;
10943        }
10944    }
10945
10946    public final void showSafeModeOverlay() {
10947        View v = LayoutInflater.from(mContext).inflate(
10948                com.android.internal.R.layout.safe_mode, null);
10949        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10950        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10951        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10952        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10953        lp.gravity = Gravity.BOTTOM | Gravity.START;
10954        lp.format = v.getBackground().getOpacity();
10955        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10956                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10957        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10958        ((WindowManager)mContext.getSystemService(
10959                Context.WINDOW_SERVICE)).addView(v, lp);
10960    }
10961
10962    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
10963        if (!(sender instanceof PendingIntentRecord)) {
10964            return;
10965        }
10966        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10967        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10968        synchronized (stats) {
10969            if (mBatteryStatsService.isOnBattery()) {
10970                mBatteryStatsService.enforceCallingPermission();
10971                int MY_UID = Binder.getCallingUid();
10972                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10973                BatteryStatsImpl.Uid.Pkg pkg =
10974                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10975                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10976                pkg.noteWakeupAlarmLocked(tag);
10977            }
10978        }
10979    }
10980
10981    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
10982        if (!(sender instanceof PendingIntentRecord)) {
10983            return;
10984        }
10985        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10986        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10987        synchronized (stats) {
10988            mBatteryStatsService.enforceCallingPermission();
10989            int MY_UID = Binder.getCallingUid();
10990            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10991            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
10992        }
10993    }
10994
10995    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
10996        if (!(sender instanceof PendingIntentRecord)) {
10997            return;
10998        }
10999        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11000        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11001        synchronized (stats) {
11002            mBatteryStatsService.enforceCallingPermission();
11003            int MY_UID = Binder.getCallingUid();
11004            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11005            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11006        }
11007    }
11008
11009    public boolean killPids(int[] pids, String pReason, boolean secure) {
11010        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11011            throw new SecurityException("killPids only available to the system");
11012        }
11013        String reason = (pReason == null) ? "Unknown" : pReason;
11014        // XXX Note: don't acquire main activity lock here, because the window
11015        // manager calls in with its locks held.
11016
11017        boolean killed = false;
11018        synchronized (mPidsSelfLocked) {
11019            int[] types = new int[pids.length];
11020            int worstType = 0;
11021            for (int i=0; i<pids.length; i++) {
11022                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11023                if (proc != null) {
11024                    int type = proc.setAdj;
11025                    types[i] = type;
11026                    if (type > worstType) {
11027                        worstType = type;
11028                    }
11029                }
11030            }
11031
11032            // If the worst oom_adj is somewhere in the cached proc LRU range,
11033            // then constrain it so we will kill all cached procs.
11034            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11035                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11036                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11037            }
11038
11039            // If this is not a secure call, don't let it kill processes that
11040            // are important.
11041            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11042                worstType = ProcessList.SERVICE_ADJ;
11043            }
11044
11045            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11046            for (int i=0; i<pids.length; i++) {
11047                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11048                if (proc == null) {
11049                    continue;
11050                }
11051                int adj = proc.setAdj;
11052                if (adj >= worstType && !proc.killedByAm) {
11053                    proc.kill(reason, true);
11054                    killed = true;
11055                }
11056            }
11057        }
11058        return killed;
11059    }
11060
11061    @Override
11062    public void killUid(int uid, String reason) {
11063        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11064        synchronized (this) {
11065            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
11066                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
11067                    reason != null ? reason : "kill uid");
11068        }
11069    }
11070
11071    @Override
11072    public boolean killProcessesBelowForeground(String reason) {
11073        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11074            throw new SecurityException("killProcessesBelowForeground() only available to system");
11075        }
11076
11077        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11078    }
11079
11080    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11081        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11082            throw new SecurityException("killProcessesBelowAdj() only available to system");
11083        }
11084
11085        boolean killed = false;
11086        synchronized (mPidsSelfLocked) {
11087            final int size = mPidsSelfLocked.size();
11088            for (int i = 0; i < size; i++) {
11089                final int pid = mPidsSelfLocked.keyAt(i);
11090                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11091                if (proc == null) continue;
11092
11093                final int adj = proc.setAdj;
11094                if (adj > belowAdj && !proc.killedByAm) {
11095                    proc.kill(reason, true);
11096                    killed = true;
11097                }
11098            }
11099        }
11100        return killed;
11101    }
11102
11103    @Override
11104    public void hang(final IBinder who, boolean allowRestart) {
11105        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11106                != PackageManager.PERMISSION_GRANTED) {
11107            throw new SecurityException("Requires permission "
11108                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11109        }
11110
11111        final IBinder.DeathRecipient death = new DeathRecipient() {
11112            @Override
11113            public void binderDied() {
11114                synchronized (this) {
11115                    notifyAll();
11116                }
11117            }
11118        };
11119
11120        try {
11121            who.linkToDeath(death, 0);
11122        } catch (RemoteException e) {
11123            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11124            return;
11125        }
11126
11127        synchronized (this) {
11128            Watchdog.getInstance().setAllowRestart(allowRestart);
11129            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11130            synchronized (death) {
11131                while (who.isBinderAlive()) {
11132                    try {
11133                        death.wait();
11134                    } catch (InterruptedException e) {
11135                    }
11136                }
11137            }
11138            Watchdog.getInstance().setAllowRestart(true);
11139        }
11140    }
11141
11142    @Override
11143    public void restart() {
11144        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11145                != PackageManager.PERMISSION_GRANTED) {
11146            throw new SecurityException("Requires permission "
11147                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11148        }
11149
11150        Log.i(TAG, "Sending shutdown broadcast...");
11151
11152        BroadcastReceiver br = new BroadcastReceiver() {
11153            @Override public void onReceive(Context context, Intent intent) {
11154                // Now the broadcast is done, finish up the low-level shutdown.
11155                Log.i(TAG, "Shutting down activity manager...");
11156                shutdown(10000);
11157                Log.i(TAG, "Shutdown complete, restarting!");
11158                Process.killProcess(Process.myPid());
11159                System.exit(10);
11160            }
11161        };
11162
11163        // First send the high-level shut down broadcast.
11164        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11165        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11166        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11167        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11168        mContext.sendOrderedBroadcastAsUser(intent,
11169                UserHandle.ALL, null, br, mHandler, 0, null, null);
11170        */
11171        br.onReceive(mContext, intent);
11172    }
11173
11174    private long getLowRamTimeSinceIdle(long now) {
11175        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11176    }
11177
11178    @Override
11179    public void performIdleMaintenance() {
11180        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11181                != PackageManager.PERMISSION_GRANTED) {
11182            throw new SecurityException("Requires permission "
11183                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11184        }
11185
11186        synchronized (this) {
11187            final long now = SystemClock.uptimeMillis();
11188            final long timeSinceLastIdle = now - mLastIdleTime;
11189            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11190            mLastIdleTime = now;
11191            mLowRamTimeSinceLastIdle = 0;
11192            if (mLowRamStartTime != 0) {
11193                mLowRamStartTime = now;
11194            }
11195
11196            StringBuilder sb = new StringBuilder(128);
11197            sb.append("Idle maintenance over ");
11198            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11199            sb.append(" low RAM for ");
11200            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11201            Slog.i(TAG, sb.toString());
11202
11203            // If at least 1/3 of our time since the last idle period has been spent
11204            // with RAM low, then we want to kill processes.
11205            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11206
11207            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11208                ProcessRecord proc = mLruProcesses.get(i);
11209                if (proc.notCachedSinceIdle) {
11210                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11211                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11212                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11213                        if (doKilling && proc.initialIdlePss != 0
11214                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11215                            sb = new StringBuilder(128);
11216                            sb.append("Kill");
11217                            sb.append(proc.processName);
11218                            sb.append(" in idle maint: pss=");
11219                            sb.append(proc.lastPss);
11220                            sb.append(", initialPss=");
11221                            sb.append(proc.initialIdlePss);
11222                            sb.append(", period=");
11223                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11224                            sb.append(", lowRamPeriod=");
11225                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11226                            Slog.wtfQuiet(TAG, sb.toString());
11227                            proc.kill("idle maint (pss " + proc.lastPss
11228                                    + " from " + proc.initialIdlePss + ")", true);
11229                        }
11230                    }
11231                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11232                    proc.notCachedSinceIdle = true;
11233                    proc.initialIdlePss = 0;
11234                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11235                            mTestPssMode, isSleeping(), now);
11236                }
11237            }
11238
11239            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11240            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11241        }
11242    }
11243
11244    private void retrieveSettings() {
11245        final ContentResolver resolver = mContext.getContentResolver();
11246        String debugApp = Settings.Global.getString(
11247            resolver, Settings.Global.DEBUG_APP);
11248        boolean waitForDebugger = Settings.Global.getInt(
11249            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11250        boolean alwaysFinishActivities = Settings.Global.getInt(
11251            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11252        boolean forceRtl = Settings.Global.getInt(
11253                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11254        // Transfer any global setting for forcing RTL layout, into a System Property
11255        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11256
11257        Configuration configuration = new Configuration();
11258        Settings.System.getConfiguration(resolver, configuration);
11259        if (forceRtl) {
11260            // This will take care of setting the correct layout direction flags
11261            configuration.setLayoutDirection(configuration.locale);
11262        }
11263
11264        synchronized (this) {
11265            mDebugApp = mOrigDebugApp = debugApp;
11266            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11267            mAlwaysFinishActivities = alwaysFinishActivities;
11268            // This happens before any activities are started, so we can
11269            // change mConfiguration in-place.
11270            updateConfigurationLocked(configuration, null, false, true);
11271            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11272                    "Initial config: " + mConfiguration);
11273        }
11274    }
11275
11276    /** Loads resources after the current configuration has been set. */
11277    private void loadResourcesOnSystemReady() {
11278        final Resources res = mContext.getResources();
11279        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11280        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11281        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11282    }
11283
11284    public boolean testIsSystemReady() {
11285        // no need to synchronize(this) just to read & return the value
11286        return mSystemReady;
11287    }
11288
11289    private static File getCalledPreBootReceiversFile() {
11290        File dataDir = Environment.getDataDirectory();
11291        File systemDir = new File(dataDir, "system");
11292        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11293        return fname;
11294    }
11295
11296    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11297        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11298        File file = getCalledPreBootReceiversFile();
11299        FileInputStream fis = null;
11300        try {
11301            fis = new FileInputStream(file);
11302            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11303            int fvers = dis.readInt();
11304            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11305                String vers = dis.readUTF();
11306                String codename = dis.readUTF();
11307                String build = dis.readUTF();
11308                if (android.os.Build.VERSION.RELEASE.equals(vers)
11309                        && android.os.Build.VERSION.CODENAME.equals(codename)
11310                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11311                    int num = dis.readInt();
11312                    while (num > 0) {
11313                        num--;
11314                        String pkg = dis.readUTF();
11315                        String cls = dis.readUTF();
11316                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11317                    }
11318                }
11319            }
11320        } catch (FileNotFoundException e) {
11321        } catch (IOException e) {
11322            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11323        } finally {
11324            if (fis != null) {
11325                try {
11326                    fis.close();
11327                } catch (IOException e) {
11328                }
11329            }
11330        }
11331        return lastDoneReceivers;
11332    }
11333
11334    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11335        File file = getCalledPreBootReceiversFile();
11336        FileOutputStream fos = null;
11337        DataOutputStream dos = null;
11338        try {
11339            fos = new FileOutputStream(file);
11340            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11341            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11342            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11343            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11344            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11345            dos.writeInt(list.size());
11346            for (int i=0; i<list.size(); i++) {
11347                dos.writeUTF(list.get(i).getPackageName());
11348                dos.writeUTF(list.get(i).getClassName());
11349            }
11350        } catch (IOException e) {
11351            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11352            file.delete();
11353        } finally {
11354            FileUtils.sync(fos);
11355            if (dos != null) {
11356                try {
11357                    dos.close();
11358                } catch (IOException e) {
11359                    // TODO Auto-generated catch block
11360                    e.printStackTrace();
11361                }
11362            }
11363        }
11364    }
11365
11366    final class PreBootContinuation extends IIntentReceiver.Stub {
11367        final Intent intent;
11368        final Runnable onFinishCallback;
11369        final ArrayList<ComponentName> doneReceivers;
11370        final List<ResolveInfo> ris;
11371        final int[] users;
11372        int lastRi = -1;
11373        int curRi = 0;
11374        int curUser = 0;
11375
11376        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11377                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11378            intent = _intent;
11379            onFinishCallback = _onFinishCallback;
11380            doneReceivers = _doneReceivers;
11381            ris = _ris;
11382            users = _users;
11383        }
11384
11385        void go() {
11386            if (lastRi != curRi) {
11387                ActivityInfo ai = ris.get(curRi).activityInfo;
11388                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11389                intent.setComponent(comp);
11390                doneReceivers.add(comp);
11391                lastRi = curRi;
11392                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11393                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11394            }
11395            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11396                    + " for user " + users[curUser]);
11397            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11398            broadcastIntentLocked(null, null, intent, null, this,
11399                    0, null, null, null, AppOpsManager.OP_NONE,
11400                    true, false, MY_PID, Process.SYSTEM_UID,
11401                    users[curUser]);
11402        }
11403
11404        public void performReceive(Intent intent, int resultCode,
11405                String data, Bundle extras, boolean ordered,
11406                boolean sticky, int sendingUser) {
11407            curUser++;
11408            if (curUser >= users.length) {
11409                curUser = 0;
11410                curRi++;
11411                if (curRi >= ris.size()) {
11412                    // All done sending broadcasts!
11413                    if (onFinishCallback != null) {
11414                        // The raw IIntentReceiver interface is called
11415                        // with the AM lock held, so redispatch to
11416                        // execute our code without the lock.
11417                        mHandler.post(onFinishCallback);
11418                    }
11419                    return;
11420                }
11421            }
11422            go();
11423        }
11424    }
11425
11426    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11427            ArrayList<ComponentName> doneReceivers, int userId) {
11428        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11429        List<ResolveInfo> ris = null;
11430        try {
11431            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11432                    intent, null, 0, userId);
11433        } catch (RemoteException e) {
11434        }
11435        if (ris == null) {
11436            return false;
11437        }
11438        for (int i=ris.size()-1; i>=0; i--) {
11439            if ((ris.get(i).activityInfo.applicationInfo.flags
11440                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11441                ris.remove(i);
11442            }
11443        }
11444        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11445
11446        // For User 0, load the version number. When delivering to a new user, deliver
11447        // to all receivers.
11448        if (userId == UserHandle.USER_OWNER) {
11449            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11450            for (int i=0; i<ris.size(); i++) {
11451                ActivityInfo ai = ris.get(i).activityInfo;
11452                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11453                if (false && lastDoneReceivers.contains(comp)) {
11454                    // We already did the pre boot receiver for this app with the current
11455                    // platform version, so don't do it again...
11456                    ris.remove(i);
11457                    i--;
11458                    // ...however, do keep it as one that has been done, so we don't
11459                    // forget about it when rewriting the file of last done receivers.
11460                    doneReceivers.add(comp);
11461                }
11462            }
11463        }
11464
11465        if (ris.size() <= 0) {
11466            return false;
11467        }
11468
11469        // If primary user, send broadcast to all available users, else just to userId
11470        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11471                : new int[] { userId };
11472        if (users.length <= 0) {
11473            return false;
11474        }
11475
11476        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11477                ris, users);
11478        cont.go();
11479        return true;
11480    }
11481
11482    public void systemReady(final Runnable goingCallback) {
11483        synchronized(this) {
11484            if (mSystemReady) {
11485                // If we're done calling all the receivers, run the next "boot phase" passed in
11486                // by the SystemServer
11487                if (goingCallback != null) {
11488                    goingCallback.run();
11489                }
11490                return;
11491            }
11492
11493            // Make sure we have the current profile info, since it is needed for
11494            // security checks.
11495            updateCurrentProfileIdsLocked();
11496
11497            mRecentTasks.clear();
11498            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11499            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11500            mTaskPersister.startPersisting();
11501
11502            // Check to see if there are any update receivers to run.
11503            if (!mDidUpdate) {
11504                if (mWaitingUpdate) {
11505                    return;
11506                }
11507                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11508                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11509                    public void run() {
11510                        synchronized (ActivityManagerService.this) {
11511                            mDidUpdate = true;
11512                        }
11513                        showBootMessage(mContext.getText(
11514                                R.string.android_upgrading_complete),
11515                                false);
11516                        writeLastDonePreBootReceivers(doneReceivers);
11517                        systemReady(goingCallback);
11518                    }
11519                }, doneReceivers, UserHandle.USER_OWNER);
11520
11521                if (mWaitingUpdate) {
11522                    return;
11523                }
11524                mDidUpdate = true;
11525            }
11526
11527            mAppOpsService.systemReady();
11528            mSystemReady = true;
11529        }
11530
11531        ArrayList<ProcessRecord> procsToKill = null;
11532        synchronized(mPidsSelfLocked) {
11533            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11534                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11535                if (!isAllowedWhileBooting(proc.info)){
11536                    if (procsToKill == null) {
11537                        procsToKill = new ArrayList<ProcessRecord>();
11538                    }
11539                    procsToKill.add(proc);
11540                }
11541            }
11542        }
11543
11544        synchronized(this) {
11545            if (procsToKill != null) {
11546                for (int i=procsToKill.size()-1; i>=0; i--) {
11547                    ProcessRecord proc = procsToKill.get(i);
11548                    Slog.i(TAG, "Removing system update proc: " + proc);
11549                    removeProcessLocked(proc, true, false, "system update done");
11550                }
11551            }
11552
11553            // Now that we have cleaned up any update processes, we
11554            // are ready to start launching real processes and know that
11555            // we won't trample on them any more.
11556            mProcessesReady = true;
11557        }
11558
11559        Slog.i(TAG, "System now ready");
11560        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11561            SystemClock.uptimeMillis());
11562
11563        synchronized(this) {
11564            // Make sure we have no pre-ready processes sitting around.
11565
11566            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11567                ResolveInfo ri = mContext.getPackageManager()
11568                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11569                                STOCK_PM_FLAGS);
11570                CharSequence errorMsg = null;
11571                if (ri != null) {
11572                    ActivityInfo ai = ri.activityInfo;
11573                    ApplicationInfo app = ai.applicationInfo;
11574                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11575                        mTopAction = Intent.ACTION_FACTORY_TEST;
11576                        mTopData = null;
11577                        mTopComponent = new ComponentName(app.packageName,
11578                                ai.name);
11579                    } else {
11580                        errorMsg = mContext.getResources().getText(
11581                                com.android.internal.R.string.factorytest_not_system);
11582                    }
11583                } else {
11584                    errorMsg = mContext.getResources().getText(
11585                            com.android.internal.R.string.factorytest_no_action);
11586                }
11587                if (errorMsg != null) {
11588                    mTopAction = null;
11589                    mTopData = null;
11590                    mTopComponent = null;
11591                    Message msg = Message.obtain();
11592                    msg.what = SHOW_FACTORY_ERROR_MSG;
11593                    msg.getData().putCharSequence("msg", errorMsg);
11594                    mUiHandler.sendMessage(msg);
11595                }
11596            }
11597        }
11598
11599        retrieveSettings();
11600        loadResourcesOnSystemReady();
11601
11602        synchronized (this) {
11603            readGrantedUriPermissionsLocked();
11604        }
11605
11606        if (goingCallback != null) goingCallback.run();
11607
11608        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11609                Integer.toString(mCurrentUserId), mCurrentUserId);
11610        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11611                Integer.toString(mCurrentUserId), mCurrentUserId);
11612        mSystemServiceManager.startUser(mCurrentUserId);
11613
11614        synchronized (this) {
11615            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11616                try {
11617                    List apps = AppGlobals.getPackageManager().
11618                        getPersistentApplications(STOCK_PM_FLAGS);
11619                    if (apps != null) {
11620                        int N = apps.size();
11621                        int i;
11622                        for (i=0; i<N; i++) {
11623                            ApplicationInfo info
11624                                = (ApplicationInfo)apps.get(i);
11625                            if (info != null &&
11626                                    !info.packageName.equals("android")) {
11627                                addAppLocked(info, false, null /* ABI override */);
11628                            }
11629                        }
11630                    }
11631                } catch (RemoteException ex) {
11632                    // pm is in same process, this will never happen.
11633                }
11634            }
11635
11636            // Start up initial activity.
11637            mBooting = true;
11638            startHomeActivityLocked(mCurrentUserId, "systemReady");
11639
11640            try {
11641                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11642                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11643                            + " data partition or your device will be unstable.");
11644                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11645                }
11646            } catch (RemoteException e) {
11647            }
11648
11649            if (!Build.isBuildConsistent()) {
11650                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11651                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11652            }
11653
11654            long ident = Binder.clearCallingIdentity();
11655            try {
11656                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11657                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11658                        | Intent.FLAG_RECEIVER_FOREGROUND);
11659                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11660                broadcastIntentLocked(null, null, intent,
11661                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11662                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11663                intent = new Intent(Intent.ACTION_USER_STARTING);
11664                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11665                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11666                broadcastIntentLocked(null, null, intent,
11667                        null, new IIntentReceiver.Stub() {
11668                            @Override
11669                            public void performReceive(Intent intent, int resultCode, String data,
11670                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11671                                    throws RemoteException {
11672                            }
11673                        }, 0, null, null,
11674                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11675                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11676            } catch (Throwable t) {
11677                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11678            } finally {
11679                Binder.restoreCallingIdentity(ident);
11680            }
11681            mStackSupervisor.resumeTopActivitiesLocked();
11682            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11683        }
11684    }
11685
11686    private boolean makeAppCrashingLocked(ProcessRecord app,
11687            String shortMsg, String longMsg, String stackTrace) {
11688        app.crashing = true;
11689        app.crashingReport = generateProcessError(app,
11690                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11691        startAppProblemLocked(app);
11692        app.stopFreezingAllLocked();
11693        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11694    }
11695
11696    private void makeAppNotRespondingLocked(ProcessRecord app,
11697            String activity, String shortMsg, String longMsg) {
11698        app.notResponding = true;
11699        app.notRespondingReport = generateProcessError(app,
11700                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11701                activity, shortMsg, longMsg, null);
11702        startAppProblemLocked(app);
11703        app.stopFreezingAllLocked();
11704    }
11705
11706    /**
11707     * Generate a process error record, suitable for attachment to a ProcessRecord.
11708     *
11709     * @param app The ProcessRecord in which the error occurred.
11710     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11711     *                      ActivityManager.AppErrorStateInfo
11712     * @param activity The activity associated with the crash, if known.
11713     * @param shortMsg Short message describing the crash.
11714     * @param longMsg Long message describing the crash.
11715     * @param stackTrace Full crash stack trace, may be null.
11716     *
11717     * @return Returns a fully-formed AppErrorStateInfo record.
11718     */
11719    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11720            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11721        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11722
11723        report.condition = condition;
11724        report.processName = app.processName;
11725        report.pid = app.pid;
11726        report.uid = app.info.uid;
11727        report.tag = activity;
11728        report.shortMsg = shortMsg;
11729        report.longMsg = longMsg;
11730        report.stackTrace = stackTrace;
11731
11732        return report;
11733    }
11734
11735    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11736        synchronized (this) {
11737            app.crashing = false;
11738            app.crashingReport = null;
11739            app.notResponding = false;
11740            app.notRespondingReport = null;
11741            if (app.anrDialog == fromDialog) {
11742                app.anrDialog = null;
11743            }
11744            if (app.waitDialog == fromDialog) {
11745                app.waitDialog = null;
11746            }
11747            if (app.pid > 0 && app.pid != MY_PID) {
11748                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11749                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11750                app.kill("user request after error", true);
11751            }
11752        }
11753    }
11754
11755    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11756            String shortMsg, String longMsg, String stackTrace) {
11757        long now = SystemClock.uptimeMillis();
11758
11759        Long crashTime;
11760        if (!app.isolated) {
11761            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11762        } else {
11763            crashTime = null;
11764        }
11765        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11766            // This process loses!
11767            Slog.w(TAG, "Process " + app.info.processName
11768                    + " has crashed too many times: killing!");
11769            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11770                    app.userId, app.info.processName, app.uid);
11771            mStackSupervisor.handleAppCrashLocked(app);
11772            if (!app.persistent) {
11773                // We don't want to start this process again until the user
11774                // explicitly does so...  but for persistent process, we really
11775                // need to keep it running.  If a persistent process is actually
11776                // repeatedly crashing, then badness for everyone.
11777                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11778                        app.info.processName);
11779                if (!app.isolated) {
11780                    // XXX We don't have a way to mark isolated processes
11781                    // as bad, since they don't have a peristent identity.
11782                    mBadProcesses.put(app.info.processName, app.uid,
11783                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11784                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11785                }
11786                app.bad = true;
11787                app.removed = true;
11788                // Don't let services in this process be restarted and potentially
11789                // annoy the user repeatedly.  Unless it is persistent, since those
11790                // processes run critical code.
11791                removeProcessLocked(app, false, false, "crash");
11792                mStackSupervisor.resumeTopActivitiesLocked();
11793                return false;
11794            }
11795            mStackSupervisor.resumeTopActivitiesLocked();
11796        } else {
11797            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11798        }
11799
11800        // Bump up the crash count of any services currently running in the proc.
11801        for (int i=app.services.size()-1; i>=0; i--) {
11802            // Any services running in the application need to be placed
11803            // back in the pending list.
11804            ServiceRecord sr = app.services.valueAt(i);
11805            sr.crashCount++;
11806        }
11807
11808        // If the crashing process is what we consider to be the "home process" and it has been
11809        // replaced by a third-party app, clear the package preferred activities from packages
11810        // with a home activity running in the process to prevent a repeatedly crashing app
11811        // from blocking the user to manually clear the list.
11812        final ArrayList<ActivityRecord> activities = app.activities;
11813        if (app == mHomeProcess && activities.size() > 0
11814                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11815            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11816                final ActivityRecord r = activities.get(activityNdx);
11817                if (r.isHomeActivity()) {
11818                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11819                    try {
11820                        ActivityThread.getPackageManager()
11821                                .clearPackagePreferredActivities(r.packageName);
11822                    } catch (RemoteException c) {
11823                        // pm is in same process, this will never happen.
11824                    }
11825                }
11826            }
11827        }
11828
11829        if (!app.isolated) {
11830            // XXX Can't keep track of crash times for isolated processes,
11831            // because they don't have a perisistent identity.
11832            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11833        }
11834
11835        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11836        return true;
11837    }
11838
11839    void startAppProblemLocked(ProcessRecord app) {
11840        // If this app is not running under the current user, then we
11841        // can't give it a report button because that would require
11842        // launching the report UI under a different user.
11843        app.errorReportReceiver = null;
11844
11845        for (int userId : mCurrentProfileIds) {
11846            if (app.userId == userId) {
11847                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11848                        mContext, app.info.packageName, app.info.flags);
11849            }
11850        }
11851        skipCurrentReceiverLocked(app);
11852    }
11853
11854    void skipCurrentReceiverLocked(ProcessRecord app) {
11855        for (BroadcastQueue queue : mBroadcastQueues) {
11856            queue.skipCurrentReceiverLocked(app);
11857        }
11858    }
11859
11860    /**
11861     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11862     * The application process will exit immediately after this call returns.
11863     * @param app object of the crashing app, null for the system server
11864     * @param crashInfo describing the exception
11865     */
11866    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11867        ProcessRecord r = findAppProcess(app, "Crash");
11868        final String processName = app == null ? "system_server"
11869                : (r == null ? "unknown" : r.processName);
11870
11871        handleApplicationCrashInner("crash", r, processName, crashInfo);
11872    }
11873
11874    /* Native crash reporting uses this inner version because it needs to be somewhat
11875     * decoupled from the AM-managed cleanup lifecycle
11876     */
11877    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11878            ApplicationErrorReport.CrashInfo crashInfo) {
11879        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11880                UserHandle.getUserId(Binder.getCallingUid()), processName,
11881                r == null ? -1 : r.info.flags,
11882                crashInfo.exceptionClassName,
11883                crashInfo.exceptionMessage,
11884                crashInfo.throwFileName,
11885                crashInfo.throwLineNumber);
11886
11887        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11888
11889        crashApplication(r, crashInfo);
11890    }
11891
11892    public void handleApplicationStrictModeViolation(
11893            IBinder app,
11894            int violationMask,
11895            StrictMode.ViolationInfo info) {
11896        ProcessRecord r = findAppProcess(app, "StrictMode");
11897        if (r == null) {
11898            return;
11899        }
11900
11901        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11902            Integer stackFingerprint = info.hashCode();
11903            boolean logIt = true;
11904            synchronized (mAlreadyLoggedViolatedStacks) {
11905                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11906                    logIt = false;
11907                    // TODO: sub-sample into EventLog for these, with
11908                    // the info.durationMillis?  Then we'd get
11909                    // the relative pain numbers, without logging all
11910                    // the stack traces repeatedly.  We'd want to do
11911                    // likewise in the client code, which also does
11912                    // dup suppression, before the Binder call.
11913                } else {
11914                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11915                        mAlreadyLoggedViolatedStacks.clear();
11916                    }
11917                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11918                }
11919            }
11920            if (logIt) {
11921                logStrictModeViolationToDropBox(r, info);
11922            }
11923        }
11924
11925        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11926            AppErrorResult result = new AppErrorResult();
11927            synchronized (this) {
11928                final long origId = Binder.clearCallingIdentity();
11929
11930                Message msg = Message.obtain();
11931                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11932                HashMap<String, Object> data = new HashMap<String, Object>();
11933                data.put("result", result);
11934                data.put("app", r);
11935                data.put("violationMask", violationMask);
11936                data.put("info", info);
11937                msg.obj = data;
11938                mUiHandler.sendMessage(msg);
11939
11940                Binder.restoreCallingIdentity(origId);
11941            }
11942            int res = result.get();
11943            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11944        }
11945    }
11946
11947    // Depending on the policy in effect, there could be a bunch of
11948    // these in quick succession so we try to batch these together to
11949    // minimize disk writes, number of dropbox entries, and maximize
11950    // compression, by having more fewer, larger records.
11951    private void logStrictModeViolationToDropBox(
11952            ProcessRecord process,
11953            StrictMode.ViolationInfo info) {
11954        if (info == null) {
11955            return;
11956        }
11957        final boolean isSystemApp = process == null ||
11958                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11959                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11960        final String processName = process == null ? "unknown" : process.processName;
11961        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11962        final DropBoxManager dbox = (DropBoxManager)
11963                mContext.getSystemService(Context.DROPBOX_SERVICE);
11964
11965        // Exit early if the dropbox isn't configured to accept this report type.
11966        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11967
11968        boolean bufferWasEmpty;
11969        boolean needsFlush;
11970        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11971        synchronized (sb) {
11972            bufferWasEmpty = sb.length() == 0;
11973            appendDropBoxProcessHeaders(process, processName, sb);
11974            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11975            sb.append("System-App: ").append(isSystemApp).append("\n");
11976            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11977            if (info.violationNumThisLoop != 0) {
11978                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11979            }
11980            if (info.numAnimationsRunning != 0) {
11981                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11982            }
11983            if (info.broadcastIntentAction != null) {
11984                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11985            }
11986            if (info.durationMillis != -1) {
11987                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11988            }
11989            if (info.numInstances != -1) {
11990                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11991            }
11992            if (info.tags != null) {
11993                for (String tag : info.tags) {
11994                    sb.append("Span-Tag: ").append(tag).append("\n");
11995                }
11996            }
11997            sb.append("\n");
11998            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11999                sb.append(info.crashInfo.stackTrace);
12000                sb.append("\n");
12001            }
12002            if (info.message != null) {
12003                sb.append(info.message);
12004                sb.append("\n");
12005            }
12006
12007            // Only buffer up to ~64k.  Various logging bits truncate
12008            // things at 128k.
12009            needsFlush = (sb.length() > 64 * 1024);
12010        }
12011
12012        // Flush immediately if the buffer's grown too large, or this
12013        // is a non-system app.  Non-system apps are isolated with a
12014        // different tag & policy and not batched.
12015        //
12016        // Batching is useful during internal testing with
12017        // StrictMode settings turned up high.  Without batching,
12018        // thousands of separate files could be created on boot.
12019        if (!isSystemApp || needsFlush) {
12020            new Thread("Error dump: " + dropboxTag) {
12021                @Override
12022                public void run() {
12023                    String report;
12024                    synchronized (sb) {
12025                        report = sb.toString();
12026                        sb.delete(0, sb.length());
12027                        sb.trimToSize();
12028                    }
12029                    if (report.length() != 0) {
12030                        dbox.addText(dropboxTag, report);
12031                    }
12032                }
12033            }.start();
12034            return;
12035        }
12036
12037        // System app batching:
12038        if (!bufferWasEmpty) {
12039            // An existing dropbox-writing thread is outstanding, so
12040            // we don't need to start it up.  The existing thread will
12041            // catch the buffer appends we just did.
12042            return;
12043        }
12044
12045        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12046        // (After this point, we shouldn't access AMS internal data structures.)
12047        new Thread("Error dump: " + dropboxTag) {
12048            @Override
12049            public void run() {
12050                // 5 second sleep to let stacks arrive and be batched together
12051                try {
12052                    Thread.sleep(5000);  // 5 seconds
12053                } catch (InterruptedException e) {}
12054
12055                String errorReport;
12056                synchronized (mStrictModeBuffer) {
12057                    errorReport = mStrictModeBuffer.toString();
12058                    if (errorReport.length() == 0) {
12059                        return;
12060                    }
12061                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12062                    mStrictModeBuffer.trimToSize();
12063                }
12064                dbox.addText(dropboxTag, errorReport);
12065            }
12066        }.start();
12067    }
12068
12069    /**
12070     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12071     * @param app object of the crashing app, null for the system server
12072     * @param tag reported by the caller
12073     * @param system whether this wtf is coming from the system
12074     * @param crashInfo describing the context of the error
12075     * @return true if the process should exit immediately (WTF is fatal)
12076     */
12077    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12078            final ApplicationErrorReport.CrashInfo crashInfo) {
12079        final int callingUid = Binder.getCallingUid();
12080        final int callingPid = Binder.getCallingPid();
12081
12082        if (system) {
12083            // If this is coming from the system, we could very well have low-level
12084            // system locks held, so we want to do this all asynchronously.  And we
12085            // never want this to become fatal, so there is that too.
12086            mHandler.post(new Runnable() {
12087                @Override public void run() {
12088                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12089                }
12090            });
12091            return false;
12092        }
12093
12094        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12095                crashInfo);
12096
12097        if (r != null && r.pid != Process.myPid() &&
12098                Settings.Global.getInt(mContext.getContentResolver(),
12099                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12100            crashApplication(r, crashInfo);
12101            return true;
12102        } else {
12103            return false;
12104        }
12105    }
12106
12107    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12108            final ApplicationErrorReport.CrashInfo crashInfo) {
12109        final ProcessRecord r = findAppProcess(app, "WTF");
12110        final String processName = app == null ? "system_server"
12111                : (r == null ? "unknown" : r.processName);
12112
12113        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12114                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12115
12116        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12117
12118        return r;
12119    }
12120
12121    /**
12122     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12123     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12124     */
12125    private ProcessRecord findAppProcess(IBinder app, String reason) {
12126        if (app == null) {
12127            return null;
12128        }
12129
12130        synchronized (this) {
12131            final int NP = mProcessNames.getMap().size();
12132            for (int ip=0; ip<NP; ip++) {
12133                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12134                final int NA = apps.size();
12135                for (int ia=0; ia<NA; ia++) {
12136                    ProcessRecord p = apps.valueAt(ia);
12137                    if (p.thread != null && p.thread.asBinder() == app) {
12138                        return p;
12139                    }
12140                }
12141            }
12142
12143            Slog.w(TAG, "Can't find mystery application for " + reason
12144                    + " from pid=" + Binder.getCallingPid()
12145                    + " uid=" + Binder.getCallingUid() + ": " + app);
12146            return null;
12147        }
12148    }
12149
12150    /**
12151     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12152     * to append various headers to the dropbox log text.
12153     */
12154    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12155            StringBuilder sb) {
12156        // Watchdog thread ends up invoking this function (with
12157        // a null ProcessRecord) to add the stack file to dropbox.
12158        // Do not acquire a lock on this (am) in such cases, as it
12159        // could cause a potential deadlock, if and when watchdog
12160        // is invoked due to unavailability of lock on am and it
12161        // would prevent watchdog from killing system_server.
12162        if (process == null) {
12163            sb.append("Process: ").append(processName).append("\n");
12164            return;
12165        }
12166        // Note: ProcessRecord 'process' is guarded by the service
12167        // instance.  (notably process.pkgList, which could otherwise change
12168        // concurrently during execution of this method)
12169        synchronized (this) {
12170            sb.append("Process: ").append(processName).append("\n");
12171            int flags = process.info.flags;
12172            IPackageManager pm = AppGlobals.getPackageManager();
12173            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12174            for (int ip=0; ip<process.pkgList.size(); ip++) {
12175                String pkg = process.pkgList.keyAt(ip);
12176                sb.append("Package: ").append(pkg);
12177                try {
12178                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12179                    if (pi != null) {
12180                        sb.append(" v").append(pi.versionCode);
12181                        if (pi.versionName != null) {
12182                            sb.append(" (").append(pi.versionName).append(")");
12183                        }
12184                    }
12185                } catch (RemoteException e) {
12186                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12187                }
12188                sb.append("\n");
12189            }
12190        }
12191    }
12192
12193    private static String processClass(ProcessRecord process) {
12194        if (process == null || process.pid == MY_PID) {
12195            return "system_server";
12196        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12197            return "system_app";
12198        } else {
12199            return "data_app";
12200        }
12201    }
12202
12203    /**
12204     * Write a description of an error (crash, WTF, ANR) to the drop box.
12205     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12206     * @param process which caused the error, null means the system server
12207     * @param activity which triggered the error, null if unknown
12208     * @param parent activity related to the error, null if unknown
12209     * @param subject line related to the error, null if absent
12210     * @param report in long form describing the error, null if absent
12211     * @param logFile to include in the report, null if none
12212     * @param crashInfo giving an application stack trace, null if absent
12213     */
12214    public void addErrorToDropBox(String eventType,
12215            ProcessRecord process, String processName, ActivityRecord activity,
12216            ActivityRecord parent, String subject,
12217            final String report, final File logFile,
12218            final ApplicationErrorReport.CrashInfo crashInfo) {
12219        // NOTE -- this must never acquire the ActivityManagerService lock,
12220        // otherwise the watchdog may be prevented from resetting the system.
12221
12222        final String dropboxTag = processClass(process) + "_" + eventType;
12223        final DropBoxManager dbox = (DropBoxManager)
12224                mContext.getSystemService(Context.DROPBOX_SERVICE);
12225
12226        // Exit early if the dropbox isn't configured to accept this report type.
12227        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12228
12229        final StringBuilder sb = new StringBuilder(1024);
12230        appendDropBoxProcessHeaders(process, processName, sb);
12231        if (activity != null) {
12232            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12233        }
12234        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12235            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12236        }
12237        if (parent != null && parent != activity) {
12238            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12239        }
12240        if (subject != null) {
12241            sb.append("Subject: ").append(subject).append("\n");
12242        }
12243        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12244        if (Debug.isDebuggerConnected()) {
12245            sb.append("Debugger: Connected\n");
12246        }
12247        sb.append("\n");
12248
12249        // Do the rest in a worker thread to avoid blocking the caller on I/O
12250        // (After this point, we shouldn't access AMS internal data structures.)
12251        Thread worker = new Thread("Error dump: " + dropboxTag) {
12252            @Override
12253            public void run() {
12254                if (report != null) {
12255                    sb.append(report);
12256                }
12257                if (logFile != null) {
12258                    try {
12259                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12260                                    "\n\n[[TRUNCATED]]"));
12261                    } catch (IOException e) {
12262                        Slog.e(TAG, "Error reading " + logFile, e);
12263                    }
12264                }
12265                if (crashInfo != null && crashInfo.stackTrace != null) {
12266                    sb.append(crashInfo.stackTrace);
12267                }
12268
12269                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12270                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12271                if (lines > 0) {
12272                    sb.append("\n");
12273
12274                    // Merge several logcat streams, and take the last N lines
12275                    InputStreamReader input = null;
12276                    try {
12277                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12278                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12279                                "-b", "crash",
12280                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12281
12282                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12283                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12284                        input = new InputStreamReader(logcat.getInputStream());
12285
12286                        int num;
12287                        char[] buf = new char[8192];
12288                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12289                    } catch (IOException e) {
12290                        Slog.e(TAG, "Error running logcat", e);
12291                    } finally {
12292                        if (input != null) try { input.close(); } catch (IOException e) {}
12293                    }
12294                }
12295
12296                dbox.addText(dropboxTag, sb.toString());
12297            }
12298        };
12299
12300        if (process == null) {
12301            // If process is null, we are being called from some internal code
12302            // and may be about to die -- run this synchronously.
12303            worker.run();
12304        } else {
12305            worker.start();
12306        }
12307    }
12308
12309    /**
12310     * Bring up the "unexpected error" dialog box for a crashing app.
12311     * Deal with edge cases (intercepts from instrumented applications,
12312     * ActivityController, error intent receivers, that sort of thing).
12313     * @param r the application crashing
12314     * @param crashInfo describing the failure
12315     */
12316    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12317        long timeMillis = System.currentTimeMillis();
12318        String shortMsg = crashInfo.exceptionClassName;
12319        String longMsg = crashInfo.exceptionMessage;
12320        String stackTrace = crashInfo.stackTrace;
12321        if (shortMsg != null && longMsg != null) {
12322            longMsg = shortMsg + ": " + longMsg;
12323        } else if (shortMsg != null) {
12324            longMsg = shortMsg;
12325        }
12326
12327        AppErrorResult result = new AppErrorResult();
12328        synchronized (this) {
12329            if (mController != null) {
12330                try {
12331                    String name = r != null ? r.processName : null;
12332                    int pid = r != null ? r.pid : Binder.getCallingPid();
12333                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12334                    if (!mController.appCrashed(name, pid,
12335                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12336                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12337                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12338                            Slog.w(TAG, "Skip killing native crashed app " + name
12339                                    + "(" + pid + ") during testing");
12340                        } else {
12341                            Slog.w(TAG, "Force-killing crashed app " + name
12342                                    + " at watcher's request");
12343                            if (r != null) {
12344                                r.kill("crash", true);
12345                            } else {
12346                                // Huh.
12347                                Process.killProcess(pid);
12348                                Process.killProcessGroup(uid, pid);
12349                            }
12350                        }
12351                        return;
12352                    }
12353                } catch (RemoteException e) {
12354                    mController = null;
12355                    Watchdog.getInstance().setActivityController(null);
12356                }
12357            }
12358
12359            final long origId = Binder.clearCallingIdentity();
12360
12361            // If this process is running instrumentation, finish it.
12362            if (r != null && r.instrumentationClass != null) {
12363                Slog.w(TAG, "Error in app " + r.processName
12364                      + " running instrumentation " + r.instrumentationClass + ":");
12365                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12366                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12367                Bundle info = new Bundle();
12368                info.putString("shortMsg", shortMsg);
12369                info.putString("longMsg", longMsg);
12370                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12371                Binder.restoreCallingIdentity(origId);
12372                return;
12373            }
12374
12375            // Log crash in battery stats.
12376            if (r != null) {
12377                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12378            }
12379
12380            // If we can't identify the process or it's already exceeded its crash quota,
12381            // quit right away without showing a crash dialog.
12382            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12383                Binder.restoreCallingIdentity(origId);
12384                return;
12385            }
12386
12387            Message msg = Message.obtain();
12388            msg.what = SHOW_ERROR_MSG;
12389            HashMap data = new HashMap();
12390            data.put("result", result);
12391            data.put("app", r);
12392            msg.obj = data;
12393            mUiHandler.sendMessage(msg);
12394
12395            Binder.restoreCallingIdentity(origId);
12396        }
12397
12398        int res = result.get();
12399
12400        Intent appErrorIntent = null;
12401        synchronized (this) {
12402            if (r != null && !r.isolated) {
12403                // XXX Can't keep track of crash time for isolated processes,
12404                // since they don't have a persistent identity.
12405                mProcessCrashTimes.put(r.info.processName, r.uid,
12406                        SystemClock.uptimeMillis());
12407            }
12408            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12409                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12410            }
12411        }
12412
12413        if (appErrorIntent != null) {
12414            try {
12415                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12416            } catch (ActivityNotFoundException e) {
12417                Slog.w(TAG, "bug report receiver dissappeared", e);
12418            }
12419        }
12420    }
12421
12422    Intent createAppErrorIntentLocked(ProcessRecord r,
12423            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12424        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12425        if (report == null) {
12426            return null;
12427        }
12428        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12429        result.setComponent(r.errorReportReceiver);
12430        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12431        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12432        return result;
12433    }
12434
12435    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12436            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12437        if (r.errorReportReceiver == null) {
12438            return null;
12439        }
12440
12441        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12442            return null;
12443        }
12444
12445        ApplicationErrorReport report = new ApplicationErrorReport();
12446        report.packageName = r.info.packageName;
12447        report.installerPackageName = r.errorReportReceiver.getPackageName();
12448        report.processName = r.processName;
12449        report.time = timeMillis;
12450        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12451
12452        if (r.crashing || r.forceCrashReport) {
12453            report.type = ApplicationErrorReport.TYPE_CRASH;
12454            report.crashInfo = crashInfo;
12455        } else if (r.notResponding) {
12456            report.type = ApplicationErrorReport.TYPE_ANR;
12457            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12458
12459            report.anrInfo.activity = r.notRespondingReport.tag;
12460            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12461            report.anrInfo.info = r.notRespondingReport.longMsg;
12462        }
12463
12464        return report;
12465    }
12466
12467    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12468        enforceNotIsolatedCaller("getProcessesInErrorState");
12469        // assume our apps are happy - lazy create the list
12470        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12471
12472        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12473                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12474        int userId = UserHandle.getUserId(Binder.getCallingUid());
12475
12476        synchronized (this) {
12477
12478            // iterate across all processes
12479            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12480                ProcessRecord app = mLruProcesses.get(i);
12481                if (!allUsers && app.userId != userId) {
12482                    continue;
12483                }
12484                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12485                    // This one's in trouble, so we'll generate a report for it
12486                    // crashes are higher priority (in case there's a crash *and* an anr)
12487                    ActivityManager.ProcessErrorStateInfo report = null;
12488                    if (app.crashing) {
12489                        report = app.crashingReport;
12490                    } else if (app.notResponding) {
12491                        report = app.notRespondingReport;
12492                    }
12493
12494                    if (report != null) {
12495                        if (errList == null) {
12496                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12497                        }
12498                        errList.add(report);
12499                    } else {
12500                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12501                                " crashing = " + app.crashing +
12502                                " notResponding = " + app.notResponding);
12503                    }
12504                }
12505            }
12506        }
12507
12508        return errList;
12509    }
12510
12511    static int procStateToImportance(int procState, int memAdj,
12512            ActivityManager.RunningAppProcessInfo currApp) {
12513        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12514        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12515            currApp.lru = memAdj;
12516        } else {
12517            currApp.lru = 0;
12518        }
12519        return imp;
12520    }
12521
12522    private void fillInProcMemInfo(ProcessRecord app,
12523            ActivityManager.RunningAppProcessInfo outInfo) {
12524        outInfo.pid = app.pid;
12525        outInfo.uid = app.info.uid;
12526        if (mHeavyWeightProcess == app) {
12527            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12528        }
12529        if (app.persistent) {
12530            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12531        }
12532        if (app.activities.size() > 0) {
12533            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12534        }
12535        outInfo.lastTrimLevel = app.trimMemoryLevel;
12536        int adj = app.curAdj;
12537        int procState = app.curProcState;
12538        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12539        outInfo.importanceReasonCode = app.adjTypeCode;
12540        outInfo.processState = app.curProcState;
12541    }
12542
12543    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12544        enforceNotIsolatedCaller("getRunningAppProcesses");
12545
12546        final int callingUid = Binder.getCallingUid();
12547
12548        // Lazy instantiation of list
12549        List<ActivityManager.RunningAppProcessInfo> runList = null;
12550        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12551                callingUid) == PackageManager.PERMISSION_GRANTED;
12552        final int userId = UserHandle.getUserId(callingUid);
12553        final boolean allUids = isGetTasksAllowed(
12554                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12555
12556        synchronized (this) {
12557            // Iterate across all processes
12558            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12559                ProcessRecord app = mLruProcesses.get(i);
12560                if ((!allUsers && app.userId != userId)
12561                        || (!allUids && app.uid != callingUid)) {
12562                    continue;
12563                }
12564                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12565                    // Generate process state info for running application
12566                    ActivityManager.RunningAppProcessInfo currApp =
12567                        new ActivityManager.RunningAppProcessInfo(app.processName,
12568                                app.pid, app.getPackageList());
12569                    fillInProcMemInfo(app, currApp);
12570                    if (app.adjSource instanceof ProcessRecord) {
12571                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12572                        currApp.importanceReasonImportance =
12573                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12574                                        app.adjSourceProcState);
12575                    } else if (app.adjSource instanceof ActivityRecord) {
12576                        ActivityRecord r = (ActivityRecord)app.adjSource;
12577                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12578                    }
12579                    if (app.adjTarget instanceof ComponentName) {
12580                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12581                    }
12582                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12583                    //        + " lru=" + currApp.lru);
12584                    if (runList == null) {
12585                        runList = new ArrayList<>();
12586                    }
12587                    runList.add(currApp);
12588                }
12589            }
12590        }
12591        return runList;
12592    }
12593
12594    public List<ApplicationInfo> getRunningExternalApplications() {
12595        enforceNotIsolatedCaller("getRunningExternalApplications");
12596        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12597        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12598        if (runningApps != null && runningApps.size() > 0) {
12599            Set<String> extList = new HashSet<String>();
12600            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12601                if (app.pkgList != null) {
12602                    for (String pkg : app.pkgList) {
12603                        extList.add(pkg);
12604                    }
12605                }
12606            }
12607            IPackageManager pm = AppGlobals.getPackageManager();
12608            for (String pkg : extList) {
12609                try {
12610                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12611                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12612                        retList.add(info);
12613                    }
12614                } catch (RemoteException e) {
12615                }
12616            }
12617        }
12618        return retList;
12619    }
12620
12621    @Override
12622    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12623        enforceNotIsolatedCaller("getMyMemoryState");
12624        synchronized (this) {
12625            ProcessRecord proc;
12626            synchronized (mPidsSelfLocked) {
12627                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12628            }
12629            fillInProcMemInfo(proc, outInfo);
12630        }
12631    }
12632
12633    @Override
12634    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12635        if (checkCallingPermission(android.Manifest.permission.DUMP)
12636                != PackageManager.PERMISSION_GRANTED) {
12637            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12638                    + Binder.getCallingPid()
12639                    + ", uid=" + Binder.getCallingUid()
12640                    + " without permission "
12641                    + android.Manifest.permission.DUMP);
12642            return;
12643        }
12644
12645        boolean dumpAll = false;
12646        boolean dumpClient = false;
12647        String dumpPackage = null;
12648
12649        int opti = 0;
12650        while (opti < args.length) {
12651            String opt = args[opti];
12652            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12653                break;
12654            }
12655            opti++;
12656            if ("-a".equals(opt)) {
12657                dumpAll = true;
12658            } else if ("-c".equals(opt)) {
12659                dumpClient = true;
12660            } else if ("-p".equals(opt)) {
12661                if (opti < args.length) {
12662                    dumpPackage = args[opti];
12663                    opti++;
12664                } else {
12665                    pw.println("Error: -p option requires package argument");
12666                    return;
12667                }
12668                dumpClient = true;
12669            } else if ("-h".equals(opt)) {
12670                pw.println("Activity manager dump options:");
12671                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12672                pw.println("  cmd may be one of:");
12673                pw.println("    a[ctivities]: activity stack state");
12674                pw.println("    r[recents]: recent activities state");
12675                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12676                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12677                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12678                pw.println("    o[om]: out of memory management");
12679                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12680                pw.println("    provider [COMP_SPEC]: provider client-side state");
12681                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12682                pw.println("    as[sociations]: tracked app associations");
12683                pw.println("    service [COMP_SPEC]: service client-side state");
12684                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12685                pw.println("    all: dump all activities");
12686                pw.println("    top: dump the top activity");
12687                pw.println("    write: write all pending state to storage");
12688                pw.println("    track-associations: enable association tracking");
12689                pw.println("    untrack-associations: disable and clear association tracking");
12690                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12691                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12692                pw.println("    a partial substring in a component name, a");
12693                pw.println("    hex object identifier.");
12694                pw.println("  -a: include all available server state.");
12695                pw.println("  -c: include client state.");
12696                pw.println("  -p: limit output to given package.");
12697                return;
12698            } else {
12699                pw.println("Unknown argument: " + opt + "; use -h for help");
12700            }
12701        }
12702
12703        long origId = Binder.clearCallingIdentity();
12704        boolean more = false;
12705        // Is the caller requesting to dump a particular piece of data?
12706        if (opti < args.length) {
12707            String cmd = args[opti];
12708            opti++;
12709            if ("activities".equals(cmd) || "a".equals(cmd)) {
12710                synchronized (this) {
12711                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12712                }
12713            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12714                synchronized (this) {
12715                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12716                }
12717            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12718                String[] newArgs;
12719                String name;
12720                if (opti >= args.length) {
12721                    name = null;
12722                    newArgs = EMPTY_STRING_ARRAY;
12723                } else {
12724                    dumpPackage = args[opti];
12725                    opti++;
12726                    newArgs = new String[args.length - opti];
12727                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12728                            args.length - opti);
12729                }
12730                synchronized (this) {
12731                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12732                }
12733            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12734                String[] newArgs;
12735                String name;
12736                if (opti >= args.length) {
12737                    name = null;
12738                    newArgs = EMPTY_STRING_ARRAY;
12739                } else {
12740                    dumpPackage = args[opti];
12741                    opti++;
12742                    newArgs = new String[args.length - opti];
12743                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12744                            args.length - opti);
12745                }
12746                synchronized (this) {
12747                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12748                }
12749            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12750                String[] newArgs;
12751                String name;
12752                if (opti >= args.length) {
12753                    name = null;
12754                    newArgs = EMPTY_STRING_ARRAY;
12755                } else {
12756                    dumpPackage = args[opti];
12757                    opti++;
12758                    newArgs = new String[args.length - opti];
12759                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12760                            args.length - opti);
12761                }
12762                synchronized (this) {
12763                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12764                }
12765            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12766                synchronized (this) {
12767                    dumpOomLocked(fd, pw, args, opti, true);
12768                }
12769            } else if ("provider".equals(cmd)) {
12770                String[] newArgs;
12771                String name;
12772                if (opti >= args.length) {
12773                    name = null;
12774                    newArgs = EMPTY_STRING_ARRAY;
12775                } else {
12776                    name = args[opti];
12777                    opti++;
12778                    newArgs = new String[args.length - opti];
12779                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12780                }
12781                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12782                    pw.println("No providers match: " + name);
12783                    pw.println("Use -h for help.");
12784                }
12785            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12786                synchronized (this) {
12787                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12788                }
12789            } else if ("service".equals(cmd)) {
12790                String[] newArgs;
12791                String name;
12792                if (opti >= args.length) {
12793                    name = null;
12794                    newArgs = EMPTY_STRING_ARRAY;
12795                } else {
12796                    name = args[opti];
12797                    opti++;
12798                    newArgs = new String[args.length - opti];
12799                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12800                            args.length - opti);
12801                }
12802                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12803                    pw.println("No services match: " + name);
12804                    pw.println("Use -h for help.");
12805                }
12806            } else if ("package".equals(cmd)) {
12807                String[] newArgs;
12808                if (opti >= args.length) {
12809                    pw.println("package: no package name specified");
12810                    pw.println("Use -h for help.");
12811                } else {
12812                    dumpPackage = args[opti];
12813                    opti++;
12814                    newArgs = new String[args.length - opti];
12815                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12816                            args.length - opti);
12817                    args = newArgs;
12818                    opti = 0;
12819                    more = true;
12820                }
12821            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12822                synchronized (this) {
12823                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12824                }
12825            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12826                synchronized (this) {
12827                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12828                }
12829            } else if ("write".equals(cmd)) {
12830                mTaskPersister.flush();
12831                pw.println("All tasks persisted.");
12832                return;
12833            } else if ("track-associations".equals(cmd)) {
12834                synchronized (this) {
12835                    if (!mTrackingAssociations) {
12836                        mTrackingAssociations = true;
12837                        pw.println("Association tracking started.");
12838                    } else {
12839                        pw.println("Association tracking already enabled.");
12840                    }
12841                }
12842                return;
12843            } else if ("untrack-associations".equals(cmd)) {
12844                synchronized (this) {
12845                    if (mTrackingAssociations) {
12846                        mTrackingAssociations = false;
12847                        mAssociations.clear();
12848                        pw.println("Association tracking stopped.");
12849                    } else {
12850                        pw.println("Association tracking not running.");
12851                    }
12852                }
12853                return;
12854            } else {
12855                // Dumping a single activity?
12856                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12857                    pw.println("Bad activity command, or no activities match: " + cmd);
12858                    pw.println("Use -h for help.");
12859                }
12860            }
12861            if (!more) {
12862                Binder.restoreCallingIdentity(origId);
12863                return;
12864            }
12865        }
12866
12867        // No piece of data specified, dump everything.
12868        synchronized (this) {
12869            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12870            pw.println();
12871            if (dumpAll) {
12872                pw.println("-------------------------------------------------------------------------------");
12873            }
12874            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12875            pw.println();
12876            if (dumpAll) {
12877                pw.println("-------------------------------------------------------------------------------");
12878            }
12879            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12880            pw.println();
12881            if (dumpAll) {
12882                pw.println("-------------------------------------------------------------------------------");
12883            }
12884            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12885            pw.println();
12886            if (dumpAll) {
12887                pw.println("-------------------------------------------------------------------------------");
12888            }
12889            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12890            pw.println();
12891            if (dumpAll) {
12892                pw.println("-------------------------------------------------------------------------------");
12893            }
12894            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12895            if (mAssociations.size() > 0) {
12896                pw.println();
12897                if (dumpAll) {
12898                    pw.println("-------------------------------------------------------------------------------");
12899                }
12900                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12901            }
12902            pw.println();
12903            if (dumpAll) {
12904                pw.println("-------------------------------------------------------------------------------");
12905            }
12906            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12907        }
12908        Binder.restoreCallingIdentity(origId);
12909    }
12910
12911    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12912            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12913        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12914
12915        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12916                dumpPackage);
12917        boolean needSep = printedAnything;
12918
12919        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12920                dumpPackage, needSep, "  mFocusedActivity: ");
12921        if (printed) {
12922            printedAnything = true;
12923            needSep = false;
12924        }
12925
12926        if (dumpPackage == null) {
12927            if (needSep) {
12928                pw.println();
12929            }
12930            needSep = true;
12931            printedAnything = true;
12932            mStackSupervisor.dump(pw, "  ");
12933        }
12934
12935        if (!printedAnything) {
12936            pw.println("  (nothing)");
12937        }
12938    }
12939
12940    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12941            int opti, boolean dumpAll, String dumpPackage) {
12942        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12943
12944        boolean printedAnything = false;
12945
12946        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12947            boolean printedHeader = false;
12948
12949            final int N = mRecentTasks.size();
12950            for (int i=0; i<N; i++) {
12951                TaskRecord tr = mRecentTasks.get(i);
12952                if (dumpPackage != null) {
12953                    if (tr.realActivity == null ||
12954                            !dumpPackage.equals(tr.realActivity)) {
12955                        continue;
12956                    }
12957                }
12958                if (!printedHeader) {
12959                    pw.println("  Recent tasks:");
12960                    printedHeader = true;
12961                    printedAnything = true;
12962                }
12963                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12964                        pw.println(tr);
12965                if (dumpAll) {
12966                    mRecentTasks.get(i).dump(pw, "    ");
12967                }
12968            }
12969        }
12970
12971        if (!printedAnything) {
12972            pw.println("  (nothing)");
12973        }
12974    }
12975
12976    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12977            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12978        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12979
12980        int dumpUid = 0;
12981        if (dumpPackage != null) {
12982            IPackageManager pm = AppGlobals.getPackageManager();
12983            try {
12984                dumpUid = pm.getPackageUid(dumpPackage, 0);
12985            } catch (RemoteException e) {
12986            }
12987        }
12988
12989        boolean printedAnything = false;
12990
12991        final long now = SystemClock.uptimeMillis();
12992
12993        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12994            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12995                    = mAssociations.valueAt(i1);
12996            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12997                SparseArray<ArrayMap<String, Association>> sourceUids
12998                        = targetComponents.valueAt(i2);
12999                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13000                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13001                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13002                        Association ass = sourceProcesses.valueAt(i4);
13003                        if (dumpPackage != null) {
13004                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13005                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13006                                continue;
13007                            }
13008                        }
13009                        printedAnything = true;
13010                        pw.print("  ");
13011                        pw.print(ass.mTargetProcess);
13012                        pw.print("/");
13013                        UserHandle.formatUid(pw, ass.mTargetUid);
13014                        pw.print(" <- ");
13015                        pw.print(ass.mSourceProcess);
13016                        pw.print("/");
13017                        UserHandle.formatUid(pw, ass.mSourceUid);
13018                        pw.println();
13019                        pw.print("    via ");
13020                        pw.print(ass.mTargetComponent.flattenToShortString());
13021                        pw.println();
13022                        pw.print("    ");
13023                        long dur = ass.mTime;
13024                        if (ass.mNesting > 0) {
13025                            dur += now - ass.mStartTime;
13026                        }
13027                        TimeUtils.formatDuration(dur, pw);
13028                        pw.print(" (");
13029                        pw.print(ass.mCount);
13030                        pw.println(" times)");
13031                        if (ass.mNesting > 0) {
13032                            pw.print("    ");
13033                            pw.print(" Currently active: ");
13034                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13035                            pw.println();
13036                        }
13037                    }
13038                }
13039            }
13040
13041        }
13042
13043        if (!printedAnything) {
13044            pw.println("  (nothing)");
13045        }
13046    }
13047
13048    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13049            int opti, boolean dumpAll, String dumpPackage) {
13050        boolean needSep = false;
13051        boolean printedAnything = false;
13052        int numPers = 0;
13053
13054        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13055
13056        if (dumpAll) {
13057            final int NP = mProcessNames.getMap().size();
13058            for (int ip=0; ip<NP; ip++) {
13059                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13060                final int NA = procs.size();
13061                for (int ia=0; ia<NA; ia++) {
13062                    ProcessRecord r = procs.valueAt(ia);
13063                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13064                        continue;
13065                    }
13066                    if (!needSep) {
13067                        pw.println("  All known processes:");
13068                        needSep = true;
13069                        printedAnything = true;
13070                    }
13071                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13072                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13073                        pw.print(" "); pw.println(r);
13074                    r.dump(pw, "    ");
13075                    if (r.persistent) {
13076                        numPers++;
13077                    }
13078                }
13079            }
13080        }
13081
13082        if (mIsolatedProcesses.size() > 0) {
13083            boolean printed = false;
13084            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13085                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13086                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13087                    continue;
13088                }
13089                if (!printed) {
13090                    if (needSep) {
13091                        pw.println();
13092                    }
13093                    pw.println("  Isolated process list (sorted by uid):");
13094                    printedAnything = true;
13095                    printed = true;
13096                    needSep = true;
13097                }
13098                pw.println(String.format("%sIsolated #%2d: %s",
13099                        "    ", i, r.toString()));
13100            }
13101        }
13102
13103        if (mActiveUids.size() > 0) {
13104            if (needSep) {
13105                pw.println();
13106            }
13107            pw.println("  UID states:");
13108            for (int i=0; i<mActiveUids.size(); i++) {
13109                UidRecord uidRec = mActiveUids.valueAt(i);
13110                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13111                pw.print(": "); pw.println(uidRec);
13112            }
13113            needSep = true;
13114            printedAnything = true;
13115        }
13116
13117        if (mLruProcesses.size() > 0) {
13118            if (needSep) {
13119                pw.println();
13120            }
13121            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13122                    pw.print(" total, non-act at ");
13123                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13124                    pw.print(", non-svc at ");
13125                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13126                    pw.println("):");
13127            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13128            needSep = true;
13129            printedAnything = true;
13130        }
13131
13132        if (dumpAll || dumpPackage != null) {
13133            synchronized (mPidsSelfLocked) {
13134                boolean printed = false;
13135                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13136                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13137                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13138                        continue;
13139                    }
13140                    if (!printed) {
13141                        if (needSep) pw.println();
13142                        needSep = true;
13143                        pw.println("  PID mappings:");
13144                        printed = true;
13145                        printedAnything = true;
13146                    }
13147                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13148                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13149                }
13150            }
13151        }
13152
13153        if (mForegroundProcesses.size() > 0) {
13154            synchronized (mPidsSelfLocked) {
13155                boolean printed = false;
13156                for (int i=0; i<mForegroundProcesses.size(); i++) {
13157                    ProcessRecord r = mPidsSelfLocked.get(
13158                            mForegroundProcesses.valueAt(i).pid);
13159                    if (dumpPackage != null && (r == null
13160                            || !r.pkgList.containsKey(dumpPackage))) {
13161                        continue;
13162                    }
13163                    if (!printed) {
13164                        if (needSep) pw.println();
13165                        needSep = true;
13166                        pw.println("  Foreground Processes:");
13167                        printed = true;
13168                        printedAnything = true;
13169                    }
13170                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13171                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13172                }
13173            }
13174        }
13175
13176        if (mPersistentStartingProcesses.size() > 0) {
13177            if (needSep) pw.println();
13178            needSep = true;
13179            printedAnything = true;
13180            pw.println("  Persisent processes that are starting:");
13181            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13182                    "Starting Norm", "Restarting PERS", dumpPackage);
13183        }
13184
13185        if (mRemovedProcesses.size() > 0) {
13186            if (needSep) pw.println();
13187            needSep = true;
13188            printedAnything = true;
13189            pw.println("  Processes that are being removed:");
13190            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13191                    "Removed Norm", "Removed PERS", dumpPackage);
13192        }
13193
13194        if (mProcessesOnHold.size() > 0) {
13195            if (needSep) pw.println();
13196            needSep = true;
13197            printedAnything = true;
13198            pw.println("  Processes that are on old until the system is ready:");
13199            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13200                    "OnHold Norm", "OnHold PERS", dumpPackage);
13201        }
13202
13203        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13204
13205        if (mProcessCrashTimes.getMap().size() > 0) {
13206            boolean printed = false;
13207            long now = SystemClock.uptimeMillis();
13208            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13209            final int NP = pmap.size();
13210            for (int ip=0; ip<NP; ip++) {
13211                String pname = pmap.keyAt(ip);
13212                SparseArray<Long> uids = pmap.valueAt(ip);
13213                final int N = uids.size();
13214                for (int i=0; i<N; i++) {
13215                    int puid = uids.keyAt(i);
13216                    ProcessRecord r = mProcessNames.get(pname, puid);
13217                    if (dumpPackage != null && (r == null
13218                            || !r.pkgList.containsKey(dumpPackage))) {
13219                        continue;
13220                    }
13221                    if (!printed) {
13222                        if (needSep) pw.println();
13223                        needSep = true;
13224                        pw.println("  Time since processes crashed:");
13225                        printed = true;
13226                        printedAnything = true;
13227                    }
13228                    pw.print("    Process "); pw.print(pname);
13229                            pw.print(" uid "); pw.print(puid);
13230                            pw.print(": last crashed ");
13231                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13232                            pw.println(" ago");
13233                }
13234            }
13235        }
13236
13237        if (mBadProcesses.getMap().size() > 0) {
13238            boolean printed = false;
13239            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13240            final int NP = pmap.size();
13241            for (int ip=0; ip<NP; ip++) {
13242                String pname = pmap.keyAt(ip);
13243                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13244                final int N = uids.size();
13245                for (int i=0; i<N; i++) {
13246                    int puid = uids.keyAt(i);
13247                    ProcessRecord r = mProcessNames.get(pname, puid);
13248                    if (dumpPackage != null && (r == null
13249                            || !r.pkgList.containsKey(dumpPackage))) {
13250                        continue;
13251                    }
13252                    if (!printed) {
13253                        if (needSep) pw.println();
13254                        needSep = true;
13255                        pw.println("  Bad processes:");
13256                        printedAnything = true;
13257                    }
13258                    BadProcessInfo info = uids.valueAt(i);
13259                    pw.print("    Bad process "); pw.print(pname);
13260                            pw.print(" uid "); pw.print(puid);
13261                            pw.print(": crashed at time "); pw.println(info.time);
13262                    if (info.shortMsg != null) {
13263                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13264                    }
13265                    if (info.longMsg != null) {
13266                        pw.print("      Long msg: "); pw.println(info.longMsg);
13267                    }
13268                    if (info.stack != null) {
13269                        pw.println("      Stack:");
13270                        int lastPos = 0;
13271                        for (int pos=0; pos<info.stack.length(); pos++) {
13272                            if (info.stack.charAt(pos) == '\n') {
13273                                pw.print("        ");
13274                                pw.write(info.stack, lastPos, pos-lastPos);
13275                                pw.println();
13276                                lastPos = pos+1;
13277                            }
13278                        }
13279                        if (lastPos < info.stack.length()) {
13280                            pw.print("        ");
13281                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13282                            pw.println();
13283                        }
13284                    }
13285                }
13286            }
13287        }
13288
13289        if (dumpPackage == null) {
13290            pw.println();
13291            needSep = false;
13292            pw.println("  mStartedUsers:");
13293            for (int i=0; i<mStartedUsers.size(); i++) {
13294                UserStartedState uss = mStartedUsers.valueAt(i);
13295                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13296                        pw.print(": "); uss.dump("", pw);
13297            }
13298            pw.print("  mStartedUserArray: [");
13299            for (int i=0; i<mStartedUserArray.length; i++) {
13300                if (i > 0) pw.print(", ");
13301                pw.print(mStartedUserArray[i]);
13302            }
13303            pw.println("]");
13304            pw.print("  mUserLru: [");
13305            for (int i=0; i<mUserLru.size(); i++) {
13306                if (i > 0) pw.print(", ");
13307                pw.print(mUserLru.get(i));
13308            }
13309            pw.println("]");
13310            if (dumpAll) {
13311                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13312            }
13313            synchronized (mUserProfileGroupIdsSelfLocked) {
13314                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13315                    pw.println("  mUserProfileGroupIds:");
13316                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13317                        pw.print("    User #");
13318                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13319                        pw.print(" -> profile #");
13320                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13321                    }
13322                }
13323            }
13324        }
13325        if (mHomeProcess != null && (dumpPackage == null
13326                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13327            if (needSep) {
13328                pw.println();
13329                needSep = false;
13330            }
13331            pw.println("  mHomeProcess: " + mHomeProcess);
13332        }
13333        if (mPreviousProcess != null && (dumpPackage == null
13334                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13335            if (needSep) {
13336                pw.println();
13337                needSep = false;
13338            }
13339            pw.println("  mPreviousProcess: " + mPreviousProcess);
13340        }
13341        if (dumpAll) {
13342            StringBuilder sb = new StringBuilder(128);
13343            sb.append("  mPreviousProcessVisibleTime: ");
13344            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13345            pw.println(sb);
13346        }
13347        if (mHeavyWeightProcess != null && (dumpPackage == null
13348                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13349            if (needSep) {
13350                pw.println();
13351                needSep = false;
13352            }
13353            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13354        }
13355        if (dumpPackage == null) {
13356            pw.println("  mConfiguration: " + mConfiguration);
13357        }
13358        if (dumpAll) {
13359            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13360            if (mCompatModePackages.getPackages().size() > 0) {
13361                boolean printed = false;
13362                for (Map.Entry<String, Integer> entry
13363                        : mCompatModePackages.getPackages().entrySet()) {
13364                    String pkg = entry.getKey();
13365                    int mode = entry.getValue();
13366                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13367                        continue;
13368                    }
13369                    if (!printed) {
13370                        pw.println("  mScreenCompatPackages:");
13371                        printed = true;
13372                    }
13373                    pw.print("    "); pw.print(pkg); pw.print(": ");
13374                            pw.print(mode); pw.println();
13375                }
13376            }
13377        }
13378        if (dumpPackage == null) {
13379            pw.println("  mWakefulness="
13380                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13381            pw.println("  mSleepTokens=" + mSleepTokens);
13382            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13383                    + lockScreenShownToString());
13384            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13385            if (mRunningVoice != null) {
13386                pw.println("  mRunningVoice=" + mRunningVoice);
13387                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13388            }
13389        }
13390        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13391                || mOrigWaitForDebugger) {
13392            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13393                    || dumpPackage.equals(mOrigDebugApp)) {
13394                if (needSep) {
13395                    pw.println();
13396                    needSep = false;
13397                }
13398                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13399                        + " mDebugTransient=" + mDebugTransient
13400                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13401            }
13402        }
13403        if (mCurAppTimeTracker != null) {
13404            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13405        }
13406        if (mMemWatchProcesses.getMap().size() > 0) {
13407            pw.println("  Mem watch processes:");
13408            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13409                    = mMemWatchProcesses.getMap();
13410            for (int i=0; i<procs.size(); i++) {
13411                final String proc = procs.keyAt(i);
13412                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13413                for (int j=0; j<uids.size(); j++) {
13414                    if (needSep) {
13415                        pw.println();
13416                        needSep = false;
13417                    }
13418                    StringBuilder sb = new StringBuilder();
13419                    sb.append("    ").append(proc).append('/');
13420                    UserHandle.formatUid(sb, uids.keyAt(j));
13421                    Pair<Long, String> val = uids.valueAt(j);
13422                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13423                    if (val.second != null) {
13424                        sb.append(", report to ").append(val.second);
13425                    }
13426                    pw.println(sb.toString());
13427                }
13428            }
13429            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13430            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13431            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13432                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13433        }
13434        if (mOpenGlTraceApp != null) {
13435            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13436                if (needSep) {
13437                    pw.println();
13438                    needSep = false;
13439                }
13440                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13441            }
13442        }
13443        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13444                || mProfileFd != null) {
13445            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13446                if (needSep) {
13447                    pw.println();
13448                    needSep = false;
13449                }
13450                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13451                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13452                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13453                        + mAutoStopProfiler);
13454                pw.println("  mProfileType=" + mProfileType);
13455            }
13456        }
13457        if (dumpPackage == null) {
13458            if (mAlwaysFinishActivities || mController != null) {
13459                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13460                        + " mController=" + mController);
13461            }
13462            if (dumpAll) {
13463                pw.println("  Total persistent processes: " + numPers);
13464                pw.println("  mProcessesReady=" + mProcessesReady
13465                        + " mSystemReady=" + mSystemReady
13466                        + " mBooted=" + mBooted
13467                        + " mFactoryTest=" + mFactoryTest);
13468                pw.println("  mBooting=" + mBooting
13469                        + " mCallFinishBooting=" + mCallFinishBooting
13470                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13471                pw.print("  mLastPowerCheckRealtime=");
13472                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13473                        pw.println("");
13474                pw.print("  mLastPowerCheckUptime=");
13475                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13476                        pw.println("");
13477                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13478                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13479                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13480                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13481                        + " (" + mLruProcesses.size() + " total)"
13482                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13483                        + " mNumServiceProcs=" + mNumServiceProcs
13484                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13485                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13486                        + " mLastMemoryLevel" + mLastMemoryLevel
13487                        + " mLastNumProcesses" + mLastNumProcesses);
13488                long now = SystemClock.uptimeMillis();
13489                pw.print("  mLastIdleTime=");
13490                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13491                        pw.print(" mLowRamSinceLastIdle=");
13492                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13493                        pw.println();
13494            }
13495        }
13496
13497        if (!printedAnything) {
13498            pw.println("  (nothing)");
13499        }
13500    }
13501
13502    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13503            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13504        if (mProcessesToGc.size() > 0) {
13505            boolean printed = false;
13506            long now = SystemClock.uptimeMillis();
13507            for (int i=0; i<mProcessesToGc.size(); i++) {
13508                ProcessRecord proc = mProcessesToGc.get(i);
13509                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13510                    continue;
13511                }
13512                if (!printed) {
13513                    if (needSep) pw.println();
13514                    needSep = true;
13515                    pw.println("  Processes that are waiting to GC:");
13516                    printed = true;
13517                }
13518                pw.print("    Process "); pw.println(proc);
13519                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13520                        pw.print(", last gced=");
13521                        pw.print(now-proc.lastRequestedGc);
13522                        pw.print(" ms ago, last lowMem=");
13523                        pw.print(now-proc.lastLowMemory);
13524                        pw.println(" ms ago");
13525
13526            }
13527        }
13528        return needSep;
13529    }
13530
13531    void printOomLevel(PrintWriter pw, String name, int adj) {
13532        pw.print("    ");
13533        if (adj >= 0) {
13534            pw.print(' ');
13535            if (adj < 10) pw.print(' ');
13536        } else {
13537            if (adj > -10) pw.print(' ');
13538        }
13539        pw.print(adj);
13540        pw.print(": ");
13541        pw.print(name);
13542        pw.print(" (");
13543        pw.print(mProcessList.getMemLevel(adj)/1024);
13544        pw.println(" kB)");
13545    }
13546
13547    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13548            int opti, boolean dumpAll) {
13549        boolean needSep = false;
13550
13551        if (mLruProcesses.size() > 0) {
13552            if (needSep) pw.println();
13553            needSep = true;
13554            pw.println("  OOM levels:");
13555            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13556            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13557            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13558            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13559            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13560            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13561            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13562            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13563            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13564            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13565            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13566            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13567            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13568            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13569
13570            if (needSep) pw.println();
13571            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13572                    pw.print(" total, non-act at ");
13573                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13574                    pw.print(", non-svc at ");
13575                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13576                    pw.println("):");
13577            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13578            needSep = true;
13579        }
13580
13581        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13582
13583        pw.println();
13584        pw.println("  mHomeProcess: " + mHomeProcess);
13585        pw.println("  mPreviousProcess: " + mPreviousProcess);
13586        if (mHeavyWeightProcess != null) {
13587            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13588        }
13589
13590        return true;
13591    }
13592
13593    /**
13594     * There are three ways to call this:
13595     *  - no provider specified: dump all the providers
13596     *  - a flattened component name that matched an existing provider was specified as the
13597     *    first arg: dump that one provider
13598     *  - the first arg isn't the flattened component name of an existing provider:
13599     *    dump all providers whose component contains the first arg as a substring
13600     */
13601    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13602            int opti, boolean dumpAll) {
13603        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13604    }
13605
13606    static class ItemMatcher {
13607        ArrayList<ComponentName> components;
13608        ArrayList<String> strings;
13609        ArrayList<Integer> objects;
13610        boolean all;
13611
13612        ItemMatcher() {
13613            all = true;
13614        }
13615
13616        void build(String name) {
13617            ComponentName componentName = ComponentName.unflattenFromString(name);
13618            if (componentName != null) {
13619                if (components == null) {
13620                    components = new ArrayList<ComponentName>();
13621                }
13622                components.add(componentName);
13623                all = false;
13624            } else {
13625                int objectId = 0;
13626                // Not a '/' separated full component name; maybe an object ID?
13627                try {
13628                    objectId = Integer.parseInt(name, 16);
13629                    if (objects == null) {
13630                        objects = new ArrayList<Integer>();
13631                    }
13632                    objects.add(objectId);
13633                    all = false;
13634                } catch (RuntimeException e) {
13635                    // Not an integer; just do string match.
13636                    if (strings == null) {
13637                        strings = new ArrayList<String>();
13638                    }
13639                    strings.add(name);
13640                    all = false;
13641                }
13642            }
13643        }
13644
13645        int build(String[] args, int opti) {
13646            for (; opti<args.length; opti++) {
13647                String name = args[opti];
13648                if ("--".equals(name)) {
13649                    return opti+1;
13650                }
13651                build(name);
13652            }
13653            return opti;
13654        }
13655
13656        boolean match(Object object, ComponentName comp) {
13657            if (all) {
13658                return true;
13659            }
13660            if (components != null) {
13661                for (int i=0; i<components.size(); i++) {
13662                    if (components.get(i).equals(comp)) {
13663                        return true;
13664                    }
13665                }
13666            }
13667            if (objects != null) {
13668                for (int i=0; i<objects.size(); i++) {
13669                    if (System.identityHashCode(object) == objects.get(i)) {
13670                        return true;
13671                    }
13672                }
13673            }
13674            if (strings != null) {
13675                String flat = comp.flattenToString();
13676                for (int i=0; i<strings.size(); i++) {
13677                    if (flat.contains(strings.get(i))) {
13678                        return true;
13679                    }
13680                }
13681            }
13682            return false;
13683        }
13684    }
13685
13686    /**
13687     * There are three things that cmd can be:
13688     *  - a flattened component name that matches an existing activity
13689     *  - the cmd arg isn't the flattened component name of an existing activity:
13690     *    dump all activity whose component contains the cmd as a substring
13691     *  - A hex number of the ActivityRecord object instance.
13692     */
13693    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13694            int opti, boolean dumpAll) {
13695        ArrayList<ActivityRecord> activities;
13696
13697        synchronized (this) {
13698            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13699        }
13700
13701        if (activities.size() <= 0) {
13702            return false;
13703        }
13704
13705        String[] newArgs = new String[args.length - opti];
13706        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13707
13708        TaskRecord lastTask = null;
13709        boolean needSep = false;
13710        for (int i=activities.size()-1; i>=0; i--) {
13711            ActivityRecord r = activities.get(i);
13712            if (needSep) {
13713                pw.println();
13714            }
13715            needSep = true;
13716            synchronized (this) {
13717                if (lastTask != r.task) {
13718                    lastTask = r.task;
13719                    pw.print("TASK "); pw.print(lastTask.affinity);
13720                            pw.print(" id="); pw.println(lastTask.taskId);
13721                    if (dumpAll) {
13722                        lastTask.dump(pw, "  ");
13723                    }
13724                }
13725            }
13726            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13727        }
13728        return true;
13729    }
13730
13731    /**
13732     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13733     * there is a thread associated with the activity.
13734     */
13735    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13736            final ActivityRecord r, String[] args, boolean dumpAll) {
13737        String innerPrefix = prefix + "  ";
13738        synchronized (this) {
13739            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13740                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13741                    pw.print(" pid=");
13742                    if (r.app != null) pw.println(r.app.pid);
13743                    else pw.println("(not running)");
13744            if (dumpAll) {
13745                r.dump(pw, innerPrefix);
13746            }
13747        }
13748        if (r.app != null && r.app.thread != null) {
13749            // flush anything that is already in the PrintWriter since the thread is going
13750            // to write to the file descriptor directly
13751            pw.flush();
13752            try {
13753                TransferPipe tp = new TransferPipe();
13754                try {
13755                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13756                            r.appToken, innerPrefix, args);
13757                    tp.go(fd);
13758                } finally {
13759                    tp.kill();
13760                }
13761            } catch (IOException e) {
13762                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13763            } catch (RemoteException e) {
13764                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13765            }
13766        }
13767    }
13768
13769    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13770            int opti, boolean dumpAll, String dumpPackage) {
13771        boolean needSep = false;
13772        boolean onlyHistory = false;
13773        boolean printedAnything = false;
13774
13775        if ("history".equals(dumpPackage)) {
13776            if (opti < args.length && "-s".equals(args[opti])) {
13777                dumpAll = false;
13778            }
13779            onlyHistory = true;
13780            dumpPackage = null;
13781        }
13782
13783        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13784        if (!onlyHistory && dumpAll) {
13785            if (mRegisteredReceivers.size() > 0) {
13786                boolean printed = false;
13787                Iterator it = mRegisteredReceivers.values().iterator();
13788                while (it.hasNext()) {
13789                    ReceiverList r = (ReceiverList)it.next();
13790                    if (dumpPackage != null && (r.app == null ||
13791                            !dumpPackage.equals(r.app.info.packageName))) {
13792                        continue;
13793                    }
13794                    if (!printed) {
13795                        pw.println("  Registered Receivers:");
13796                        needSep = true;
13797                        printed = true;
13798                        printedAnything = true;
13799                    }
13800                    pw.print("  * "); pw.println(r);
13801                    r.dump(pw, "    ");
13802                }
13803            }
13804
13805            if (mReceiverResolver.dump(pw, needSep ?
13806                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13807                    "    ", dumpPackage, false, false)) {
13808                needSep = true;
13809                printedAnything = true;
13810            }
13811        }
13812
13813        for (BroadcastQueue q : mBroadcastQueues) {
13814            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13815            printedAnything |= needSep;
13816        }
13817
13818        needSep = true;
13819
13820        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13821            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13822                if (needSep) {
13823                    pw.println();
13824                }
13825                needSep = true;
13826                printedAnything = true;
13827                pw.print("  Sticky broadcasts for user ");
13828                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13829                StringBuilder sb = new StringBuilder(128);
13830                for (Map.Entry<String, ArrayList<Intent>> ent
13831                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13832                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13833                    if (dumpAll) {
13834                        pw.println(":");
13835                        ArrayList<Intent> intents = ent.getValue();
13836                        final int N = intents.size();
13837                        for (int i=0; i<N; i++) {
13838                            sb.setLength(0);
13839                            sb.append("    Intent: ");
13840                            intents.get(i).toShortString(sb, false, true, false, false);
13841                            pw.println(sb.toString());
13842                            Bundle bundle = intents.get(i).getExtras();
13843                            if (bundle != null) {
13844                                pw.print("      ");
13845                                pw.println(bundle.toString());
13846                            }
13847                        }
13848                    } else {
13849                        pw.println("");
13850                    }
13851                }
13852            }
13853        }
13854
13855        if (!onlyHistory && dumpAll) {
13856            pw.println();
13857            for (BroadcastQueue queue : mBroadcastQueues) {
13858                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13859                        + queue.mBroadcastsScheduled);
13860            }
13861            pw.println("  mHandler:");
13862            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13863            needSep = true;
13864            printedAnything = true;
13865        }
13866
13867        if (!printedAnything) {
13868            pw.println("  (nothing)");
13869        }
13870    }
13871
13872    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13873            int opti, boolean dumpAll, String dumpPackage) {
13874        boolean needSep;
13875        boolean printedAnything = false;
13876
13877        ItemMatcher matcher = new ItemMatcher();
13878        matcher.build(args, opti);
13879
13880        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13881
13882        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13883        printedAnything |= needSep;
13884
13885        if (mLaunchingProviders.size() > 0) {
13886            boolean printed = false;
13887            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13888                ContentProviderRecord r = mLaunchingProviders.get(i);
13889                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13890                    continue;
13891                }
13892                if (!printed) {
13893                    if (needSep) pw.println();
13894                    needSep = true;
13895                    pw.println("  Launching content providers:");
13896                    printed = true;
13897                    printedAnything = true;
13898                }
13899                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13900                        pw.println(r);
13901            }
13902        }
13903
13904        if (mGrantedUriPermissions.size() > 0) {
13905            boolean printed = false;
13906            int dumpUid = -2;
13907            if (dumpPackage != null) {
13908                try {
13909                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13910                } catch (NameNotFoundException e) {
13911                    dumpUid = -1;
13912                }
13913            }
13914            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13915                int uid = mGrantedUriPermissions.keyAt(i);
13916                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13917                    continue;
13918                }
13919                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13920                if (!printed) {
13921                    if (needSep) pw.println();
13922                    needSep = true;
13923                    pw.println("  Granted Uri Permissions:");
13924                    printed = true;
13925                    printedAnything = true;
13926                }
13927                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13928                for (UriPermission perm : perms.values()) {
13929                    pw.print("    "); pw.println(perm);
13930                    if (dumpAll) {
13931                        perm.dump(pw, "      ");
13932                    }
13933                }
13934            }
13935        }
13936
13937        if (!printedAnything) {
13938            pw.println("  (nothing)");
13939        }
13940    }
13941
13942    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13943            int opti, boolean dumpAll, String dumpPackage) {
13944        boolean printed = false;
13945
13946        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13947
13948        if (mIntentSenderRecords.size() > 0) {
13949            Iterator<WeakReference<PendingIntentRecord>> it
13950                    = mIntentSenderRecords.values().iterator();
13951            while (it.hasNext()) {
13952                WeakReference<PendingIntentRecord> ref = it.next();
13953                PendingIntentRecord rec = ref != null ? ref.get(): null;
13954                if (dumpPackage != null && (rec == null
13955                        || !dumpPackage.equals(rec.key.packageName))) {
13956                    continue;
13957                }
13958                printed = true;
13959                if (rec != null) {
13960                    pw.print("  * "); pw.println(rec);
13961                    if (dumpAll) {
13962                        rec.dump(pw, "    ");
13963                    }
13964                } else {
13965                    pw.print("  * "); pw.println(ref);
13966                }
13967            }
13968        }
13969
13970        if (!printed) {
13971            pw.println("  (nothing)");
13972        }
13973    }
13974
13975    private static final int dumpProcessList(PrintWriter pw,
13976            ActivityManagerService service, List list,
13977            String prefix, String normalLabel, String persistentLabel,
13978            String dumpPackage) {
13979        int numPers = 0;
13980        final int N = list.size()-1;
13981        for (int i=N; i>=0; i--) {
13982            ProcessRecord r = (ProcessRecord)list.get(i);
13983            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13984                continue;
13985            }
13986            pw.println(String.format("%s%s #%2d: %s",
13987                    prefix, (r.persistent ? persistentLabel : normalLabel),
13988                    i, r.toString()));
13989            if (r.persistent) {
13990                numPers++;
13991            }
13992        }
13993        return numPers;
13994    }
13995
13996    private static final boolean dumpProcessOomList(PrintWriter pw,
13997            ActivityManagerService service, List<ProcessRecord> origList,
13998            String prefix, String normalLabel, String persistentLabel,
13999            boolean inclDetails, String dumpPackage) {
14000
14001        ArrayList<Pair<ProcessRecord, Integer>> list
14002                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14003        for (int i=0; i<origList.size(); i++) {
14004            ProcessRecord r = origList.get(i);
14005            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14006                continue;
14007            }
14008            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14009        }
14010
14011        if (list.size() <= 0) {
14012            return false;
14013        }
14014
14015        Comparator<Pair<ProcessRecord, Integer>> comparator
14016                = new Comparator<Pair<ProcessRecord, Integer>>() {
14017            @Override
14018            public int compare(Pair<ProcessRecord, Integer> object1,
14019                    Pair<ProcessRecord, Integer> object2) {
14020                if (object1.first.setAdj != object2.first.setAdj) {
14021                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14022                }
14023                if (object1.second.intValue() != object2.second.intValue()) {
14024                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14025                }
14026                return 0;
14027            }
14028        };
14029
14030        Collections.sort(list, comparator);
14031
14032        final long curRealtime = SystemClock.elapsedRealtime();
14033        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14034        final long curUptime = SystemClock.uptimeMillis();
14035        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14036
14037        for (int i=list.size()-1; i>=0; i--) {
14038            ProcessRecord r = list.get(i).first;
14039            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14040            char schedGroup;
14041            switch (r.setSchedGroup) {
14042                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14043                    schedGroup = 'B';
14044                    break;
14045                case Process.THREAD_GROUP_DEFAULT:
14046                    schedGroup = 'F';
14047                    break;
14048                default:
14049                    schedGroup = '?';
14050                    break;
14051            }
14052            char foreground;
14053            if (r.foregroundActivities) {
14054                foreground = 'A';
14055            } else if (r.foregroundServices) {
14056                foreground = 'S';
14057            } else {
14058                foreground = ' ';
14059            }
14060            String procState = ProcessList.makeProcStateString(r.curProcState);
14061            pw.print(prefix);
14062            pw.print(r.persistent ? persistentLabel : normalLabel);
14063            pw.print(" #");
14064            int num = (origList.size()-1)-list.get(i).second;
14065            if (num < 10) pw.print(' ');
14066            pw.print(num);
14067            pw.print(": ");
14068            pw.print(oomAdj);
14069            pw.print(' ');
14070            pw.print(schedGroup);
14071            pw.print('/');
14072            pw.print(foreground);
14073            pw.print('/');
14074            pw.print(procState);
14075            pw.print(" trm:");
14076            if (r.trimMemoryLevel < 10) pw.print(' ');
14077            pw.print(r.trimMemoryLevel);
14078            pw.print(' ');
14079            pw.print(r.toShortString());
14080            pw.print(" (");
14081            pw.print(r.adjType);
14082            pw.println(')');
14083            if (r.adjSource != null || r.adjTarget != null) {
14084                pw.print(prefix);
14085                pw.print("    ");
14086                if (r.adjTarget instanceof ComponentName) {
14087                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14088                } else if (r.adjTarget != null) {
14089                    pw.print(r.adjTarget.toString());
14090                } else {
14091                    pw.print("{null}");
14092                }
14093                pw.print("<=");
14094                if (r.adjSource instanceof ProcessRecord) {
14095                    pw.print("Proc{");
14096                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14097                    pw.println("}");
14098                } else if (r.adjSource != null) {
14099                    pw.println(r.adjSource.toString());
14100                } else {
14101                    pw.println("{null}");
14102                }
14103            }
14104            if (inclDetails) {
14105                pw.print(prefix);
14106                pw.print("    ");
14107                pw.print("oom: max="); pw.print(r.maxAdj);
14108                pw.print(" curRaw="); pw.print(r.curRawAdj);
14109                pw.print(" setRaw="); pw.print(r.setRawAdj);
14110                pw.print(" cur="); pw.print(r.curAdj);
14111                pw.print(" set="); pw.println(r.setAdj);
14112                pw.print(prefix);
14113                pw.print("    ");
14114                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14115                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14116                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14117                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14118                pw.println();
14119                pw.print(prefix);
14120                pw.print("    ");
14121                pw.print("cached="); pw.print(r.cached);
14122                pw.print(" empty="); pw.print(r.empty);
14123                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14124
14125                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14126                    if (r.lastWakeTime != 0) {
14127                        long wtime;
14128                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14129                        synchronized (stats) {
14130                            wtime = stats.getProcessWakeTime(r.info.uid,
14131                                    r.pid, curRealtime);
14132                        }
14133                        long timeUsed = wtime - r.lastWakeTime;
14134                        pw.print(prefix);
14135                        pw.print("    ");
14136                        pw.print("keep awake over ");
14137                        TimeUtils.formatDuration(realtimeSince, pw);
14138                        pw.print(" used ");
14139                        TimeUtils.formatDuration(timeUsed, pw);
14140                        pw.print(" (");
14141                        pw.print((timeUsed*100)/realtimeSince);
14142                        pw.println("%)");
14143                    }
14144                    if (r.lastCpuTime != 0) {
14145                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14146                        pw.print(prefix);
14147                        pw.print("    ");
14148                        pw.print("run cpu over ");
14149                        TimeUtils.formatDuration(uptimeSince, pw);
14150                        pw.print(" used ");
14151                        TimeUtils.formatDuration(timeUsed, pw);
14152                        pw.print(" (");
14153                        pw.print((timeUsed*100)/uptimeSince);
14154                        pw.println("%)");
14155                    }
14156                }
14157            }
14158        }
14159        return true;
14160    }
14161
14162    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14163            String[] args) {
14164        ArrayList<ProcessRecord> procs;
14165        synchronized (this) {
14166            if (args != null && args.length > start
14167                    && args[start].charAt(0) != '-') {
14168                procs = new ArrayList<ProcessRecord>();
14169                int pid = -1;
14170                try {
14171                    pid = Integer.parseInt(args[start]);
14172                } catch (NumberFormatException e) {
14173                }
14174                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14175                    ProcessRecord proc = mLruProcesses.get(i);
14176                    if (proc.pid == pid) {
14177                        procs.add(proc);
14178                    } else if (allPkgs && proc.pkgList != null
14179                            && proc.pkgList.containsKey(args[start])) {
14180                        procs.add(proc);
14181                    } else if (proc.processName.equals(args[start])) {
14182                        procs.add(proc);
14183                    }
14184                }
14185                if (procs.size() <= 0) {
14186                    return null;
14187                }
14188            } else {
14189                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14190            }
14191        }
14192        return procs;
14193    }
14194
14195    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14196            PrintWriter pw, String[] args) {
14197        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14198        if (procs == null) {
14199            pw.println("No process found for: " + args[0]);
14200            return;
14201        }
14202
14203        long uptime = SystemClock.uptimeMillis();
14204        long realtime = SystemClock.elapsedRealtime();
14205        pw.println("Applications Graphics Acceleration Info:");
14206        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14207
14208        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14209            ProcessRecord r = procs.get(i);
14210            if (r.thread != null) {
14211                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14212                pw.flush();
14213                try {
14214                    TransferPipe tp = new TransferPipe();
14215                    try {
14216                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14217                        tp.go(fd);
14218                    } finally {
14219                        tp.kill();
14220                    }
14221                } catch (IOException e) {
14222                    pw.println("Failure while dumping the app: " + r);
14223                    pw.flush();
14224                } catch (RemoteException e) {
14225                    pw.println("Got a RemoteException while dumping the app " + r);
14226                    pw.flush();
14227                }
14228            }
14229        }
14230    }
14231
14232    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14233        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14234        if (procs == null) {
14235            pw.println("No process found for: " + args[0]);
14236            return;
14237        }
14238
14239        pw.println("Applications Database Info:");
14240
14241        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14242            ProcessRecord r = procs.get(i);
14243            if (r.thread != null) {
14244                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14245                pw.flush();
14246                try {
14247                    TransferPipe tp = new TransferPipe();
14248                    try {
14249                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14250                        tp.go(fd);
14251                    } finally {
14252                        tp.kill();
14253                    }
14254                } catch (IOException e) {
14255                    pw.println("Failure while dumping the app: " + r);
14256                    pw.flush();
14257                } catch (RemoteException e) {
14258                    pw.println("Got a RemoteException while dumping the app " + r);
14259                    pw.flush();
14260                }
14261            }
14262        }
14263    }
14264
14265    final static class MemItem {
14266        final boolean isProc;
14267        final String label;
14268        final String shortLabel;
14269        final long pss;
14270        final int id;
14271        final boolean hasActivities;
14272        ArrayList<MemItem> subitems;
14273
14274        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14275                boolean _hasActivities) {
14276            isProc = true;
14277            label = _label;
14278            shortLabel = _shortLabel;
14279            pss = _pss;
14280            id = _id;
14281            hasActivities = _hasActivities;
14282        }
14283
14284        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14285            isProc = false;
14286            label = _label;
14287            shortLabel = _shortLabel;
14288            pss = _pss;
14289            id = _id;
14290            hasActivities = false;
14291        }
14292    }
14293
14294    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14295            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14296        if (sort && !isCompact) {
14297            Collections.sort(items, new Comparator<MemItem>() {
14298                @Override
14299                public int compare(MemItem lhs, MemItem rhs) {
14300                    if (lhs.pss < rhs.pss) {
14301                        return 1;
14302                    } else if (lhs.pss > rhs.pss) {
14303                        return -1;
14304                    }
14305                    return 0;
14306                }
14307            });
14308        }
14309
14310        for (int i=0; i<items.size(); i++) {
14311            MemItem mi = items.get(i);
14312            if (!isCompact) {
14313                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14314            } else if (mi.isProc) {
14315                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14316                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14317                pw.println(mi.hasActivities ? ",a" : ",e");
14318            } else {
14319                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14320                pw.println(mi.pss);
14321            }
14322            if (mi.subitems != null) {
14323                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14324                        true, isCompact);
14325            }
14326        }
14327    }
14328
14329    // These are in KB.
14330    static final long[] DUMP_MEM_BUCKETS = new long[] {
14331        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14332        120*1024, 160*1024, 200*1024,
14333        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14334        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14335    };
14336
14337    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14338            boolean stackLike) {
14339        int start = label.lastIndexOf('.');
14340        if (start >= 0) start++;
14341        else start = 0;
14342        int end = label.length();
14343        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14344            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14345                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14346                out.append(bucket);
14347                out.append(stackLike ? "MB." : "MB ");
14348                out.append(label, start, end);
14349                return;
14350            }
14351        }
14352        out.append(memKB/1024);
14353        out.append(stackLike ? "MB." : "MB ");
14354        out.append(label, start, end);
14355    }
14356
14357    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14358            ProcessList.NATIVE_ADJ,
14359            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14360            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14361            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14362            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14363            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14364            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14365    };
14366    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14367            "Native",
14368            "System", "Persistent", "Persistent Service", "Foreground",
14369            "Visible", "Perceptible",
14370            "Heavy Weight", "Backup",
14371            "A Services", "Home",
14372            "Previous", "B Services", "Cached"
14373    };
14374    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14375            "native",
14376            "sys", "pers", "persvc", "fore",
14377            "vis", "percept",
14378            "heavy", "backup",
14379            "servicea", "home",
14380            "prev", "serviceb", "cached"
14381    };
14382
14383    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14384            long realtime, boolean isCheckinRequest, boolean isCompact) {
14385        if (isCheckinRequest || isCompact) {
14386            // short checkin version
14387            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14388        } else {
14389            pw.println("Applications Memory Usage (kB):");
14390            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14391        }
14392    }
14393
14394    private static final int KSM_SHARED = 0;
14395    private static final int KSM_SHARING = 1;
14396    private static final int KSM_UNSHARED = 2;
14397    private static final int KSM_VOLATILE = 3;
14398
14399    private final long[] getKsmInfo() {
14400        long[] longOut = new long[4];
14401        final int[] SINGLE_LONG_FORMAT = new int[] {
14402            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14403        };
14404        long[] longTmp = new long[1];
14405        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14406                SINGLE_LONG_FORMAT, null, longTmp, null);
14407        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14408        longTmp[0] = 0;
14409        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14410                SINGLE_LONG_FORMAT, null, longTmp, null);
14411        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14412        longTmp[0] = 0;
14413        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14414                SINGLE_LONG_FORMAT, null, longTmp, null);
14415        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14416        longTmp[0] = 0;
14417        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14418                SINGLE_LONG_FORMAT, null, longTmp, null);
14419        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14420        return longOut;
14421    }
14422
14423    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14424            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14425        boolean dumpDetails = false;
14426        boolean dumpFullDetails = false;
14427        boolean dumpDalvik = false;
14428        boolean dumpSummaryOnly = false;
14429        boolean oomOnly = false;
14430        boolean isCompact = false;
14431        boolean localOnly = false;
14432        boolean packages = false;
14433
14434        int opti = 0;
14435        while (opti < args.length) {
14436            String opt = args[opti];
14437            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14438                break;
14439            }
14440            opti++;
14441            if ("-a".equals(opt)) {
14442                dumpDetails = true;
14443                dumpFullDetails = true;
14444                dumpDalvik = true;
14445            } else if ("-d".equals(opt)) {
14446                dumpDalvik = true;
14447            } else if ("-c".equals(opt)) {
14448                isCompact = true;
14449            } else if ("-s".equals(opt)) {
14450                dumpDetails = true;
14451                dumpSummaryOnly = true;
14452            } else if ("--oom".equals(opt)) {
14453                oomOnly = true;
14454            } else if ("--local".equals(opt)) {
14455                localOnly = true;
14456            } else if ("--package".equals(opt)) {
14457                packages = true;
14458            } else if ("-h".equals(opt)) {
14459                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14460                pw.println("  -a: include all available information for each process.");
14461                pw.println("  -d: include dalvik details.");
14462                pw.println("  -c: dump in a compact machine-parseable representation.");
14463                pw.println("  -s: dump only summary of application memory usage.");
14464                pw.println("  --oom: only show processes organized by oom adj.");
14465                pw.println("  --local: only collect details locally, don't call process.");
14466                pw.println("  --package: interpret process arg as package, dumping all");
14467                pw.println("             processes that have loaded that package.");
14468                pw.println("If [process] is specified it can be the name or ");
14469                pw.println("pid of a specific process to dump.");
14470                return;
14471            } else {
14472                pw.println("Unknown argument: " + opt + "; use -h for help");
14473            }
14474        }
14475
14476        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14477        long uptime = SystemClock.uptimeMillis();
14478        long realtime = SystemClock.elapsedRealtime();
14479        final long[] tmpLong = new long[1];
14480
14481        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14482        if (procs == null) {
14483            // No Java processes.  Maybe they want to print a native process.
14484            if (args != null && args.length > opti
14485                    && args[opti].charAt(0) != '-') {
14486                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14487                        = new ArrayList<ProcessCpuTracker.Stats>();
14488                updateCpuStatsNow();
14489                int findPid = -1;
14490                try {
14491                    findPid = Integer.parseInt(args[opti]);
14492                } catch (NumberFormatException e) {
14493                }
14494                synchronized (mProcessCpuTracker) {
14495                    final int N = mProcessCpuTracker.countStats();
14496                    for (int i=0; i<N; i++) {
14497                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14498                        if (st.pid == findPid || (st.baseName != null
14499                                && st.baseName.equals(args[opti]))) {
14500                            nativeProcs.add(st);
14501                        }
14502                    }
14503                }
14504                if (nativeProcs.size() > 0) {
14505                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14506                            isCompact);
14507                    Debug.MemoryInfo mi = null;
14508                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14509                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14510                        final int pid = r.pid;
14511                        if (!isCheckinRequest && dumpDetails) {
14512                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14513                        }
14514                        if (mi == null) {
14515                            mi = new Debug.MemoryInfo();
14516                        }
14517                        if (dumpDetails || (!brief && !oomOnly)) {
14518                            Debug.getMemoryInfo(pid, mi);
14519                        } else {
14520                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14521                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14522                        }
14523                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14524                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14525                        if (isCheckinRequest) {
14526                            pw.println();
14527                        }
14528                    }
14529                    return;
14530                }
14531            }
14532            pw.println("No process found for: " + args[opti]);
14533            return;
14534        }
14535
14536        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14537            dumpDetails = true;
14538        }
14539
14540        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14541
14542        String[] innerArgs = new String[args.length-opti];
14543        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14544
14545        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14546        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14547        long nativePss = 0;
14548        long dalvikPss = 0;
14549        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14550                EmptyArray.LONG;
14551        long otherPss = 0;
14552        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14553
14554        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14555        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14556                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14557
14558        long totalPss = 0;
14559        long cachedPss = 0;
14560
14561        Debug.MemoryInfo mi = null;
14562        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14563            final ProcessRecord r = procs.get(i);
14564            final IApplicationThread thread;
14565            final int pid;
14566            final int oomAdj;
14567            final boolean hasActivities;
14568            synchronized (this) {
14569                thread = r.thread;
14570                pid = r.pid;
14571                oomAdj = r.getSetAdjWithServices();
14572                hasActivities = r.activities.size() > 0;
14573            }
14574            if (thread != null) {
14575                if (!isCheckinRequest && dumpDetails) {
14576                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14577                }
14578                if (mi == null) {
14579                    mi = new Debug.MemoryInfo();
14580                }
14581                if (dumpDetails || (!brief && !oomOnly)) {
14582                    Debug.getMemoryInfo(pid, mi);
14583                } else {
14584                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14585                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14586                }
14587                if (dumpDetails) {
14588                    if (localOnly) {
14589                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14590                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14591                        if (isCheckinRequest) {
14592                            pw.println();
14593                        }
14594                    } else {
14595                        try {
14596                            pw.flush();
14597                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14598                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14599                        } catch (RemoteException e) {
14600                            if (!isCheckinRequest) {
14601                                pw.println("Got RemoteException!");
14602                                pw.flush();
14603                            }
14604                        }
14605                    }
14606                }
14607
14608                final long myTotalPss = mi.getTotalPss();
14609                final long myTotalUss = mi.getTotalUss();
14610
14611                synchronized (this) {
14612                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14613                        // Record this for posterity if the process has been stable.
14614                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14615                    }
14616                }
14617
14618                if (!isCheckinRequest && mi != null) {
14619                    totalPss += myTotalPss;
14620                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14621                            (hasActivities ? " / activities)" : ")"),
14622                            r.processName, myTotalPss, pid, hasActivities);
14623                    procMems.add(pssItem);
14624                    procMemsMap.put(pid, pssItem);
14625
14626                    nativePss += mi.nativePss;
14627                    dalvikPss += mi.dalvikPss;
14628                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14629                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14630                    }
14631                    otherPss += mi.otherPss;
14632                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14633                        long mem = mi.getOtherPss(j);
14634                        miscPss[j] += mem;
14635                        otherPss -= mem;
14636                    }
14637
14638                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14639                        cachedPss += myTotalPss;
14640                    }
14641
14642                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14643                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14644                                || oomIndex == (oomPss.length-1)) {
14645                            oomPss[oomIndex] += myTotalPss;
14646                            if (oomProcs[oomIndex] == null) {
14647                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14648                            }
14649                            oomProcs[oomIndex].add(pssItem);
14650                            break;
14651                        }
14652                    }
14653                }
14654            }
14655        }
14656
14657        long nativeProcTotalPss = 0;
14658
14659        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14660            // If we are showing aggregations, also look for native processes to
14661            // include so that our aggregations are more accurate.
14662            updateCpuStatsNow();
14663            mi = null;
14664            synchronized (mProcessCpuTracker) {
14665                final int N = mProcessCpuTracker.countStats();
14666                for (int i=0; i<N; i++) {
14667                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14668                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14669                        if (mi == null) {
14670                            mi = new Debug.MemoryInfo();
14671                        }
14672                        if (!brief && !oomOnly) {
14673                            Debug.getMemoryInfo(st.pid, mi);
14674                        } else {
14675                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14676                            mi.nativePrivateDirty = (int)tmpLong[0];
14677                        }
14678
14679                        final long myTotalPss = mi.getTotalPss();
14680                        totalPss += myTotalPss;
14681                        nativeProcTotalPss += myTotalPss;
14682
14683                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14684                                st.name, myTotalPss, st.pid, false);
14685                        procMems.add(pssItem);
14686
14687                        nativePss += mi.nativePss;
14688                        dalvikPss += mi.dalvikPss;
14689                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14690                            dalvikSubitemPss[j] += mi.getOtherPss(
14691                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14692                        }
14693                        otherPss += mi.otherPss;
14694                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14695                            long mem = mi.getOtherPss(j);
14696                            miscPss[j] += mem;
14697                            otherPss -= mem;
14698                        }
14699                        oomPss[0] += myTotalPss;
14700                        if (oomProcs[0] == null) {
14701                            oomProcs[0] = new ArrayList<MemItem>();
14702                        }
14703                        oomProcs[0].add(pssItem);
14704                    }
14705                }
14706            }
14707
14708            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14709
14710            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14711            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14712            if (dalvikSubitemPss.length > 0) {
14713                dalvikItem.subitems = new ArrayList<MemItem>();
14714                for (int j=0; j<dalvikSubitemPss.length; j++) {
14715                    final String name = Debug.MemoryInfo.getOtherLabel(
14716                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14717                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14718                }
14719            }
14720            catMems.add(dalvikItem);
14721            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14722            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14723                String label = Debug.MemoryInfo.getOtherLabel(j);
14724                catMems.add(new MemItem(label, label, miscPss[j], j));
14725            }
14726
14727            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14728            for (int j=0; j<oomPss.length; j++) {
14729                if (oomPss[j] != 0) {
14730                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14731                            : DUMP_MEM_OOM_LABEL[j];
14732                    MemItem item = new MemItem(label, label, oomPss[j],
14733                            DUMP_MEM_OOM_ADJ[j]);
14734                    item.subitems = oomProcs[j];
14735                    oomMems.add(item);
14736                }
14737            }
14738
14739            if (!brief && !oomOnly && !isCompact) {
14740                pw.println();
14741                pw.println("Total PSS by process:");
14742                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14743                pw.println();
14744            }
14745            if (!isCompact) {
14746                pw.println("Total PSS by OOM adjustment:");
14747            }
14748            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14749            if (!brief && !oomOnly) {
14750                PrintWriter out = categoryPw != null ? categoryPw : pw;
14751                if (!isCompact) {
14752                    out.println();
14753                    out.println("Total PSS by category:");
14754                }
14755                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14756            }
14757            if (!isCompact) {
14758                pw.println();
14759            }
14760            MemInfoReader memInfo = new MemInfoReader();
14761            memInfo.readMemInfo();
14762            if (nativeProcTotalPss > 0) {
14763                synchronized (this) {
14764                    final long cachedKb = memInfo.getCachedSizeKb();
14765                    final long freeKb = memInfo.getFreeSizeKb();
14766                    final long zramKb = memInfo.getZramTotalSizeKb();
14767                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14768                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14769                            kernelKb*1024, nativeProcTotalPss*1024);
14770                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14771                            nativeProcTotalPss);
14772                }
14773            }
14774            if (!brief) {
14775                if (!isCompact) {
14776                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14777                    pw.print(" kB (status ");
14778                    switch (mLastMemoryLevel) {
14779                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14780                            pw.println("normal)");
14781                            break;
14782                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14783                            pw.println("moderate)");
14784                            break;
14785                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14786                            pw.println("low)");
14787                            break;
14788                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14789                            pw.println("critical)");
14790                            break;
14791                        default:
14792                            pw.print(mLastMemoryLevel);
14793                            pw.println(")");
14794                            break;
14795                    }
14796                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14797                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14798                            pw.print(cachedPss); pw.print(" cached pss + ");
14799                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14800                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14801                } else {
14802                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14803                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14804                            + memInfo.getFreeSizeKb()); pw.print(",");
14805                    pw.println(totalPss - cachedPss);
14806                }
14807            }
14808            if (!isCompact) {
14809                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14810                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14811                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14812                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14813                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14814                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14815                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14816            }
14817            if (!brief) {
14818                if (memInfo.getZramTotalSizeKb() != 0) {
14819                    if (!isCompact) {
14820                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14821                                pw.print(" kB physical used for ");
14822                                pw.print(memInfo.getSwapTotalSizeKb()
14823                                        - memInfo.getSwapFreeSizeKb());
14824                                pw.print(" kB in swap (");
14825                                pw.print(memInfo.getSwapTotalSizeKb());
14826                                pw.println(" kB total swap)");
14827                    } else {
14828                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14829                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14830                                pw.println(memInfo.getSwapFreeSizeKb());
14831                    }
14832                }
14833                final long[] ksm = getKsmInfo();
14834                if (!isCompact) {
14835                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14836                            || ksm[KSM_VOLATILE] != 0) {
14837                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14838                                pw.print(" kB saved from shared ");
14839                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14840                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14841                                pw.print(" kB unshared; ");
14842                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14843                    }
14844                    pw.print("   Tuning: ");
14845                    pw.print(ActivityManager.staticGetMemoryClass());
14846                    pw.print(" (large ");
14847                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14848                    pw.print("), oom ");
14849                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14850                    pw.print(" kB");
14851                    pw.print(", restore limit ");
14852                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14853                    pw.print(" kB");
14854                    if (ActivityManager.isLowRamDeviceStatic()) {
14855                        pw.print(" (low-ram)");
14856                    }
14857                    if (ActivityManager.isHighEndGfx()) {
14858                        pw.print(" (high-end-gfx)");
14859                    }
14860                    pw.println();
14861                } else {
14862                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14863                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14864                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14865                    pw.print("tuning,");
14866                    pw.print(ActivityManager.staticGetMemoryClass());
14867                    pw.print(',');
14868                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14869                    pw.print(',');
14870                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14871                    if (ActivityManager.isLowRamDeviceStatic()) {
14872                        pw.print(",low-ram");
14873                    }
14874                    if (ActivityManager.isHighEndGfx()) {
14875                        pw.print(",high-end-gfx");
14876                    }
14877                    pw.println();
14878                }
14879            }
14880        }
14881    }
14882
14883    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14884            long memtrack, String name) {
14885        sb.append("  ");
14886        sb.append(ProcessList.makeOomAdjString(oomAdj));
14887        sb.append(' ');
14888        sb.append(ProcessList.makeProcStateString(procState));
14889        sb.append(' ');
14890        ProcessList.appendRamKb(sb, pss);
14891        sb.append(" kB: ");
14892        sb.append(name);
14893        if (memtrack > 0) {
14894            sb.append(" (");
14895            sb.append(memtrack);
14896            sb.append(" kB memtrack)");
14897        }
14898    }
14899
14900    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14901        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14902        sb.append(" (pid ");
14903        sb.append(mi.pid);
14904        sb.append(") ");
14905        sb.append(mi.adjType);
14906        sb.append('\n');
14907        if (mi.adjReason != null) {
14908            sb.append("                      ");
14909            sb.append(mi.adjReason);
14910            sb.append('\n');
14911        }
14912    }
14913
14914    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14915        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14916        for (int i=0, N=memInfos.size(); i<N; i++) {
14917            ProcessMemInfo mi = memInfos.get(i);
14918            infoMap.put(mi.pid, mi);
14919        }
14920        updateCpuStatsNow();
14921        long[] memtrackTmp = new long[1];
14922        synchronized (mProcessCpuTracker) {
14923            final int N = mProcessCpuTracker.countStats();
14924            for (int i=0; i<N; i++) {
14925                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14926                if (st.vsize > 0) {
14927                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14928                    if (pss > 0) {
14929                        if (infoMap.indexOfKey(st.pid) < 0) {
14930                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14931                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14932                            mi.pss = pss;
14933                            mi.memtrack = memtrackTmp[0];
14934                            memInfos.add(mi);
14935                        }
14936                    }
14937                }
14938            }
14939        }
14940
14941        long totalPss = 0;
14942        long totalMemtrack = 0;
14943        for (int i=0, N=memInfos.size(); i<N; i++) {
14944            ProcessMemInfo mi = memInfos.get(i);
14945            if (mi.pss == 0) {
14946                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14947                mi.memtrack = memtrackTmp[0];
14948            }
14949            totalPss += mi.pss;
14950            totalMemtrack += mi.memtrack;
14951        }
14952        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14953            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14954                if (lhs.oomAdj != rhs.oomAdj) {
14955                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14956                }
14957                if (lhs.pss != rhs.pss) {
14958                    return lhs.pss < rhs.pss ? 1 : -1;
14959                }
14960                return 0;
14961            }
14962        });
14963
14964        StringBuilder tag = new StringBuilder(128);
14965        StringBuilder stack = new StringBuilder(128);
14966        tag.append("Low on memory -- ");
14967        appendMemBucket(tag, totalPss, "total", false);
14968        appendMemBucket(stack, totalPss, "total", true);
14969
14970        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14971        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14972        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14973
14974        boolean firstLine = true;
14975        int lastOomAdj = Integer.MIN_VALUE;
14976        long extraNativeRam = 0;
14977        long extraNativeMemtrack = 0;
14978        long cachedPss = 0;
14979        for (int i=0, N=memInfos.size(); i<N; i++) {
14980            ProcessMemInfo mi = memInfos.get(i);
14981
14982            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14983                cachedPss += mi.pss;
14984            }
14985
14986            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14987                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14988                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14989                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14990                if (lastOomAdj != mi.oomAdj) {
14991                    lastOomAdj = mi.oomAdj;
14992                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14993                        tag.append(" / ");
14994                    }
14995                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14996                        if (firstLine) {
14997                            stack.append(":");
14998                            firstLine = false;
14999                        }
15000                        stack.append("\n\t at ");
15001                    } else {
15002                        stack.append("$");
15003                    }
15004                } else {
15005                    tag.append(" ");
15006                    stack.append("$");
15007                }
15008                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15009                    appendMemBucket(tag, mi.pss, mi.name, false);
15010                }
15011                appendMemBucket(stack, mi.pss, mi.name, true);
15012                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15013                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15014                    stack.append("(");
15015                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15016                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15017                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15018                            stack.append(":");
15019                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15020                        }
15021                    }
15022                    stack.append(")");
15023                }
15024            }
15025
15026            appendMemInfo(fullNativeBuilder, mi);
15027            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15028                // The short form only has native processes that are >= 512K.
15029                if (mi.pss >= 512) {
15030                    appendMemInfo(shortNativeBuilder, mi);
15031                } else {
15032                    extraNativeRam += mi.pss;
15033                    extraNativeMemtrack += mi.memtrack;
15034                }
15035            } else {
15036                // Short form has all other details, but if we have collected RAM
15037                // from smaller native processes let's dump a summary of that.
15038                if (extraNativeRam > 0) {
15039                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15040                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15041                    shortNativeBuilder.append('\n');
15042                    extraNativeRam = 0;
15043                }
15044                appendMemInfo(fullJavaBuilder, mi);
15045            }
15046        }
15047
15048        fullJavaBuilder.append("           ");
15049        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15050        fullJavaBuilder.append(" kB: TOTAL");
15051        if (totalMemtrack > 0) {
15052            fullJavaBuilder.append(" (");
15053            fullJavaBuilder.append(totalMemtrack);
15054            fullJavaBuilder.append(" kB memtrack)");
15055        } else {
15056        }
15057        fullJavaBuilder.append("\n");
15058
15059        MemInfoReader memInfo = new MemInfoReader();
15060        memInfo.readMemInfo();
15061        final long[] infos = memInfo.getRawInfo();
15062
15063        StringBuilder memInfoBuilder = new StringBuilder(1024);
15064        Debug.getMemInfo(infos);
15065        memInfoBuilder.append("  MemInfo: ");
15066        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15067        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15068        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15069        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15070        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15071        memInfoBuilder.append("           ");
15072        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15073        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15074        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15075        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15076        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15077            memInfoBuilder.append("  ZRAM: ");
15078            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15079            memInfoBuilder.append(" kB RAM, ");
15080            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15081            memInfoBuilder.append(" kB swap total, ");
15082            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15083            memInfoBuilder.append(" kB swap free\n");
15084        }
15085        final long[] ksm = getKsmInfo();
15086        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15087                || ksm[KSM_VOLATILE] != 0) {
15088            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15089            memInfoBuilder.append(" kB saved from shared ");
15090            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15091            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15092            memInfoBuilder.append(" kB unshared; ");
15093            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15094        }
15095        memInfoBuilder.append("  Free RAM: ");
15096        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15097                + memInfo.getFreeSizeKb());
15098        memInfoBuilder.append(" kB\n");
15099        memInfoBuilder.append("  Used RAM: ");
15100        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15101        memInfoBuilder.append(" kB\n");
15102        memInfoBuilder.append("  Lost RAM: ");
15103        memInfoBuilder.append(memInfo.getTotalSizeKb()
15104                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15105                - memInfo.getKernelUsedSizeKb());
15106        memInfoBuilder.append(" kB\n");
15107        Slog.i(TAG, "Low on memory:");
15108        Slog.i(TAG, shortNativeBuilder.toString());
15109        Slog.i(TAG, fullJavaBuilder.toString());
15110        Slog.i(TAG, memInfoBuilder.toString());
15111
15112        StringBuilder dropBuilder = new StringBuilder(1024);
15113        /*
15114        StringWriter oomSw = new StringWriter();
15115        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15116        StringWriter catSw = new StringWriter();
15117        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15118        String[] emptyArgs = new String[] { };
15119        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15120        oomPw.flush();
15121        String oomString = oomSw.toString();
15122        */
15123        dropBuilder.append("Low on memory:");
15124        dropBuilder.append(stack);
15125        dropBuilder.append('\n');
15126        dropBuilder.append(fullNativeBuilder);
15127        dropBuilder.append(fullJavaBuilder);
15128        dropBuilder.append('\n');
15129        dropBuilder.append(memInfoBuilder);
15130        dropBuilder.append('\n');
15131        /*
15132        dropBuilder.append(oomString);
15133        dropBuilder.append('\n');
15134        */
15135        StringWriter catSw = new StringWriter();
15136        synchronized (ActivityManagerService.this) {
15137            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15138            String[] emptyArgs = new String[] { };
15139            catPw.println();
15140            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15141            catPw.println();
15142            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15143                    false, false, null);
15144            catPw.println();
15145            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15146            catPw.flush();
15147        }
15148        dropBuilder.append(catSw.toString());
15149        addErrorToDropBox("lowmem", null, "system_server", null,
15150                null, tag.toString(), dropBuilder.toString(), null, null);
15151        //Slog.i(TAG, "Sent to dropbox:");
15152        //Slog.i(TAG, dropBuilder.toString());
15153        synchronized (ActivityManagerService.this) {
15154            long now = SystemClock.uptimeMillis();
15155            if (mLastMemUsageReportTime < now) {
15156                mLastMemUsageReportTime = now;
15157            }
15158        }
15159    }
15160
15161    /**
15162     * Searches array of arguments for the specified string
15163     * @param args array of argument strings
15164     * @param value value to search for
15165     * @return true if the value is contained in the array
15166     */
15167    private static boolean scanArgs(String[] args, String value) {
15168        if (args != null) {
15169            for (String arg : args) {
15170                if (value.equals(arg)) {
15171                    return true;
15172                }
15173            }
15174        }
15175        return false;
15176    }
15177
15178    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15179            ContentProviderRecord cpr, boolean always) {
15180        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15181
15182        if (!inLaunching || always) {
15183            synchronized (cpr) {
15184                cpr.launchingApp = null;
15185                cpr.notifyAll();
15186            }
15187            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15188            String names[] = cpr.info.authority.split(";");
15189            for (int j = 0; j < names.length; j++) {
15190                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15191            }
15192        }
15193
15194        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15195            ContentProviderConnection conn = cpr.connections.get(i);
15196            if (conn.waiting) {
15197                // If this connection is waiting for the provider, then we don't
15198                // need to mess with its process unless we are always removing
15199                // or for some reason the provider is not currently launching.
15200                if (inLaunching && !always) {
15201                    continue;
15202                }
15203            }
15204            ProcessRecord capp = conn.client;
15205            conn.dead = true;
15206            if (conn.stableCount > 0) {
15207                if (!capp.persistent && capp.thread != null
15208                        && capp.pid != 0
15209                        && capp.pid != MY_PID) {
15210                    capp.kill("depends on provider "
15211                            + cpr.name.flattenToShortString()
15212                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15213                }
15214            } else if (capp.thread != null && conn.provider.provider != null) {
15215                try {
15216                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15217                } catch (RemoteException e) {
15218                }
15219                // In the protocol here, we don't expect the client to correctly
15220                // clean up this connection, we'll just remove it.
15221                cpr.connections.remove(i);
15222                if (conn.client.conProviders.remove(conn)) {
15223                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15224                }
15225            }
15226        }
15227
15228        if (inLaunching && always) {
15229            mLaunchingProviders.remove(cpr);
15230        }
15231        return inLaunching;
15232    }
15233
15234    /**
15235     * Main code for cleaning up a process when it has gone away.  This is
15236     * called both as a result of the process dying, or directly when stopping
15237     * a process when running in single process mode.
15238     *
15239     * @return Returns true if the given process has been restarted, so the
15240     * app that was passed in must remain on the process lists.
15241     */
15242    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15243            boolean restarting, boolean allowRestart, int index) {
15244        if (index >= 0) {
15245            removeLruProcessLocked(app);
15246            ProcessList.remove(app.pid);
15247        }
15248
15249        mProcessesToGc.remove(app);
15250        mPendingPssProcesses.remove(app);
15251
15252        // Dismiss any open dialogs.
15253        if (app.crashDialog != null && !app.forceCrashReport) {
15254            app.crashDialog.dismiss();
15255            app.crashDialog = null;
15256        }
15257        if (app.anrDialog != null) {
15258            app.anrDialog.dismiss();
15259            app.anrDialog = null;
15260        }
15261        if (app.waitDialog != null) {
15262            app.waitDialog.dismiss();
15263            app.waitDialog = null;
15264        }
15265
15266        app.crashing = false;
15267        app.notResponding = false;
15268
15269        app.resetPackageList(mProcessStats);
15270        app.unlinkDeathRecipient();
15271        app.makeInactive(mProcessStats);
15272        app.waitingToKill = null;
15273        app.forcingToForeground = null;
15274        updateProcessForegroundLocked(app, false, false);
15275        app.foregroundActivities = false;
15276        app.hasShownUi = false;
15277        app.treatLikeActivity = false;
15278        app.hasAboveClient = false;
15279        app.hasClientActivities = false;
15280
15281        mServices.killServicesLocked(app, allowRestart);
15282
15283        boolean restart = false;
15284
15285        // Remove published content providers.
15286        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15287            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15288            final boolean always = app.bad || !allowRestart;
15289            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15290            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15291                // We left the provider in the launching list, need to
15292                // restart it.
15293                restart = true;
15294            }
15295
15296            cpr.provider = null;
15297            cpr.proc = null;
15298        }
15299        app.pubProviders.clear();
15300
15301        // Take care of any launching providers waiting for this process.
15302        if (checkAppInLaunchingProvidersLocked(app, false)) {
15303            restart = true;
15304        }
15305
15306        // Unregister from connected content providers.
15307        if (!app.conProviders.isEmpty()) {
15308            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15309                ContentProviderConnection conn = app.conProviders.get(i);
15310                conn.provider.connections.remove(conn);
15311                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15312                        conn.provider.name);
15313            }
15314            app.conProviders.clear();
15315        }
15316
15317        // At this point there may be remaining entries in mLaunchingProviders
15318        // where we were the only one waiting, so they are no longer of use.
15319        // Look for these and clean up if found.
15320        // XXX Commented out for now.  Trying to figure out a way to reproduce
15321        // the actual situation to identify what is actually going on.
15322        if (false) {
15323            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15324                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15325                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15326                    synchronized (cpr) {
15327                        cpr.launchingApp = null;
15328                        cpr.notifyAll();
15329                    }
15330                }
15331            }
15332        }
15333
15334        skipCurrentReceiverLocked(app);
15335
15336        // Unregister any receivers.
15337        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15338            removeReceiverLocked(app.receivers.valueAt(i));
15339        }
15340        app.receivers.clear();
15341
15342        // If the app is undergoing backup, tell the backup manager about it
15343        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15344            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15345                    + mBackupTarget.appInfo + " died during backup");
15346            try {
15347                IBackupManager bm = IBackupManager.Stub.asInterface(
15348                        ServiceManager.getService(Context.BACKUP_SERVICE));
15349                bm.agentDisconnected(app.info.packageName);
15350            } catch (RemoteException e) {
15351                // can't happen; backup manager is local
15352            }
15353        }
15354
15355        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15356            ProcessChangeItem item = mPendingProcessChanges.get(i);
15357            if (item.pid == app.pid) {
15358                mPendingProcessChanges.remove(i);
15359                mAvailProcessChanges.add(item);
15360            }
15361        }
15362        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15363
15364        // If the caller is restarting this app, then leave it in its
15365        // current lists and let the caller take care of it.
15366        if (restarting) {
15367            return false;
15368        }
15369
15370        if (!app.persistent || app.isolated) {
15371            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15372                    "Removing non-persistent process during cleanup: " + app);
15373            removeProcessNameLocked(app.processName, app.uid);
15374            if (mHeavyWeightProcess == app) {
15375                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15376                        mHeavyWeightProcess.userId, 0));
15377                mHeavyWeightProcess = null;
15378            }
15379        } else if (!app.removed) {
15380            // This app is persistent, so we need to keep its record around.
15381            // If it is not already on the pending app list, add it there
15382            // and start a new process for it.
15383            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15384                mPersistentStartingProcesses.add(app);
15385                restart = true;
15386            }
15387        }
15388        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15389                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15390        mProcessesOnHold.remove(app);
15391
15392        if (app == mHomeProcess) {
15393            mHomeProcess = null;
15394        }
15395        if (app == mPreviousProcess) {
15396            mPreviousProcess = null;
15397        }
15398
15399        if (restart && !app.isolated) {
15400            // We have components that still need to be running in the
15401            // process, so re-launch it.
15402            if (index < 0) {
15403                ProcessList.remove(app.pid);
15404            }
15405            addProcessNameLocked(app);
15406            startProcessLocked(app, "restart", app.processName);
15407            return true;
15408        } else if (app.pid > 0 && app.pid != MY_PID) {
15409            // Goodbye!
15410            boolean removed;
15411            synchronized (mPidsSelfLocked) {
15412                mPidsSelfLocked.remove(app.pid);
15413                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15414            }
15415            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15416            if (app.isolated) {
15417                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15418            }
15419            app.setPid(0);
15420        }
15421        return false;
15422    }
15423
15424    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15425        // Look through the content providers we are waiting to have launched,
15426        // and if any run in this process then either schedule a restart of
15427        // the process or kill the client waiting for it if this process has
15428        // gone bad.
15429        boolean restart = false;
15430        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15431            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15432            if (cpr.launchingApp == app) {
15433                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15434                    restart = true;
15435                } else {
15436                    removeDyingProviderLocked(app, cpr, true);
15437                }
15438            }
15439        }
15440        return restart;
15441    }
15442
15443    // =========================================================
15444    // SERVICES
15445    // =========================================================
15446
15447    @Override
15448    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15449            int flags) {
15450        enforceNotIsolatedCaller("getServices");
15451        synchronized (this) {
15452            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15453        }
15454    }
15455
15456    @Override
15457    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15458        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15459        synchronized (this) {
15460            return mServices.getRunningServiceControlPanelLocked(name);
15461        }
15462    }
15463
15464    @Override
15465    public ComponentName startService(IApplicationThread caller, Intent service,
15466            String resolvedType, int userId) throws TransactionTooLargeException {
15467        enforceNotIsolatedCaller("startService");
15468        // Refuse possible leaked file descriptors
15469        if (service != null && service.hasFileDescriptors() == true) {
15470            throw new IllegalArgumentException("File descriptors passed in Intent");
15471        }
15472
15473        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15474                "startService: " + service + " type=" + resolvedType);
15475        synchronized(this) {
15476            final int callingPid = Binder.getCallingPid();
15477            final int callingUid = Binder.getCallingUid();
15478            final long origId = Binder.clearCallingIdentity();
15479            ComponentName res = mServices.startServiceLocked(caller, service,
15480                    resolvedType, callingPid, callingUid, userId);
15481            Binder.restoreCallingIdentity(origId);
15482            return res;
15483        }
15484    }
15485
15486    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15487            throws TransactionTooLargeException {
15488        synchronized(this) {
15489            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15490                    "startServiceInPackage: " + service + " type=" + resolvedType);
15491            final long origId = Binder.clearCallingIdentity();
15492            ComponentName res = mServices.startServiceLocked(null, service,
15493                    resolvedType, -1, uid, userId);
15494            Binder.restoreCallingIdentity(origId);
15495            return res;
15496        }
15497    }
15498
15499    @Override
15500    public int stopService(IApplicationThread caller, Intent service,
15501            String resolvedType, int userId) {
15502        enforceNotIsolatedCaller("stopService");
15503        // Refuse possible leaked file descriptors
15504        if (service != null && service.hasFileDescriptors() == true) {
15505            throw new IllegalArgumentException("File descriptors passed in Intent");
15506        }
15507
15508        synchronized(this) {
15509            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15510        }
15511    }
15512
15513    @Override
15514    public IBinder peekService(Intent service, String resolvedType) {
15515        enforceNotIsolatedCaller("peekService");
15516        // Refuse possible leaked file descriptors
15517        if (service != null && service.hasFileDescriptors() == true) {
15518            throw new IllegalArgumentException("File descriptors passed in Intent");
15519        }
15520        synchronized(this) {
15521            return mServices.peekServiceLocked(service, resolvedType);
15522        }
15523    }
15524
15525    @Override
15526    public boolean stopServiceToken(ComponentName className, IBinder token,
15527            int startId) {
15528        synchronized(this) {
15529            return mServices.stopServiceTokenLocked(className, token, startId);
15530        }
15531    }
15532
15533    @Override
15534    public void setServiceForeground(ComponentName className, IBinder token,
15535            int id, Notification notification, boolean removeNotification) {
15536        synchronized(this) {
15537            mServices.setServiceForegroundLocked(className, token, id, notification,
15538                    removeNotification);
15539        }
15540    }
15541
15542    @Override
15543    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15544            boolean requireFull, String name, String callerPackage) {
15545        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15546                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15547    }
15548
15549    int unsafeConvertIncomingUser(int userId) {
15550        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15551                ? mCurrentUserId : userId;
15552    }
15553
15554    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15555            int allowMode, String name, String callerPackage) {
15556        final int callingUserId = UserHandle.getUserId(callingUid);
15557        if (callingUserId == userId) {
15558            return userId;
15559        }
15560
15561        // Note that we may be accessing mCurrentUserId outside of a lock...
15562        // shouldn't be a big deal, if this is being called outside
15563        // of a locked context there is intrinsically a race with
15564        // the value the caller will receive and someone else changing it.
15565        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15566        // we will switch to the calling user if access to the current user fails.
15567        int targetUserId = unsafeConvertIncomingUser(userId);
15568
15569        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15570            final boolean allow;
15571            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15572                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15573                // If the caller has this permission, they always pass go.  And collect $200.
15574                allow = true;
15575            } else if (allowMode == ALLOW_FULL_ONLY) {
15576                // We require full access, sucks to be you.
15577                allow = false;
15578            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15579                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15580                // If the caller does not have either permission, they are always doomed.
15581                allow = false;
15582            } else if (allowMode == ALLOW_NON_FULL) {
15583                // We are blanket allowing non-full access, you lucky caller!
15584                allow = true;
15585            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15586                // We may or may not allow this depending on whether the two users are
15587                // in the same profile.
15588                synchronized (mUserProfileGroupIdsSelfLocked) {
15589                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15590                            UserInfo.NO_PROFILE_GROUP_ID);
15591                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15592                            UserInfo.NO_PROFILE_GROUP_ID);
15593                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15594                            && callingProfile == targetProfile;
15595                }
15596            } else {
15597                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15598            }
15599            if (!allow) {
15600                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15601                    // In this case, they would like to just execute as their
15602                    // owner user instead of failing.
15603                    targetUserId = callingUserId;
15604                } else {
15605                    StringBuilder builder = new StringBuilder(128);
15606                    builder.append("Permission Denial: ");
15607                    builder.append(name);
15608                    if (callerPackage != null) {
15609                        builder.append(" from ");
15610                        builder.append(callerPackage);
15611                    }
15612                    builder.append(" asks to run as user ");
15613                    builder.append(userId);
15614                    builder.append(" but is calling from user ");
15615                    builder.append(UserHandle.getUserId(callingUid));
15616                    builder.append("; this requires ");
15617                    builder.append(INTERACT_ACROSS_USERS_FULL);
15618                    if (allowMode != ALLOW_FULL_ONLY) {
15619                        builder.append(" or ");
15620                        builder.append(INTERACT_ACROSS_USERS);
15621                    }
15622                    String msg = builder.toString();
15623                    Slog.w(TAG, msg);
15624                    throw new SecurityException(msg);
15625                }
15626            }
15627        }
15628        if (!allowAll && targetUserId < 0) {
15629            throw new IllegalArgumentException(
15630                    "Call does not support special user #" + targetUserId);
15631        }
15632        // Check shell permission
15633        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15634            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15635                    targetUserId)) {
15636                throw new SecurityException("Shell does not have permission to access user "
15637                        + targetUserId + "\n " + Debug.getCallers(3));
15638            }
15639        }
15640        return targetUserId;
15641    }
15642
15643    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15644            String className, int flags) {
15645        boolean result = false;
15646        // For apps that don't have pre-defined UIDs, check for permission
15647        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15648            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15649                if (ActivityManager.checkUidPermission(
15650                        INTERACT_ACROSS_USERS,
15651                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15652                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15653                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15654                            + " requests FLAG_SINGLE_USER, but app does not hold "
15655                            + INTERACT_ACROSS_USERS;
15656                    Slog.w(TAG, msg);
15657                    throw new SecurityException(msg);
15658                }
15659                // Permission passed
15660                result = true;
15661            }
15662        } else if ("system".equals(componentProcessName)) {
15663            result = true;
15664        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15665            // Phone app and persistent apps are allowed to export singleuser providers.
15666            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15667                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15668        }
15669        if (DEBUG_MU) Slog.v(TAG_MU,
15670                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15671                + Integer.toHexString(flags) + ") = " + result);
15672        return result;
15673    }
15674
15675    /**
15676     * Checks to see if the caller is in the same app as the singleton
15677     * component, or the component is in a special app. It allows special apps
15678     * to export singleton components but prevents exporting singleton
15679     * components for regular apps.
15680     */
15681    boolean isValidSingletonCall(int callingUid, int componentUid) {
15682        int componentAppId = UserHandle.getAppId(componentUid);
15683        return UserHandle.isSameApp(callingUid, componentUid)
15684                || componentAppId == Process.SYSTEM_UID
15685                || componentAppId == Process.PHONE_UID
15686                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15687                        == PackageManager.PERMISSION_GRANTED;
15688    }
15689
15690    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15691            String resolvedType, IServiceConnection connection, int flags, int userId)
15692            throws TransactionTooLargeException {
15693        enforceNotIsolatedCaller("bindService");
15694
15695        // Refuse possible leaked file descriptors
15696        if (service != null && service.hasFileDescriptors() == true) {
15697            throw new IllegalArgumentException("File descriptors passed in Intent");
15698        }
15699
15700        synchronized(this) {
15701            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15702                    connection, flags, userId);
15703        }
15704    }
15705
15706    public boolean unbindService(IServiceConnection connection) {
15707        synchronized (this) {
15708            return mServices.unbindServiceLocked(connection);
15709        }
15710    }
15711
15712    public void publishService(IBinder token, Intent intent, IBinder service) {
15713        // Refuse possible leaked file descriptors
15714        if (intent != null && intent.hasFileDescriptors() == true) {
15715            throw new IllegalArgumentException("File descriptors passed in Intent");
15716        }
15717
15718        synchronized(this) {
15719            if (!(token instanceof ServiceRecord)) {
15720                throw new IllegalArgumentException("Invalid service token");
15721            }
15722            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15723        }
15724    }
15725
15726    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15727        // Refuse possible leaked file descriptors
15728        if (intent != null && intent.hasFileDescriptors() == true) {
15729            throw new IllegalArgumentException("File descriptors passed in Intent");
15730        }
15731
15732        synchronized(this) {
15733            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15734        }
15735    }
15736
15737    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15738        synchronized(this) {
15739            if (!(token instanceof ServiceRecord)) {
15740                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15741                throw new IllegalArgumentException("Invalid service token");
15742            }
15743            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15744        }
15745    }
15746
15747    // =========================================================
15748    // BACKUP AND RESTORE
15749    // =========================================================
15750
15751    // Cause the target app to be launched if necessary and its backup agent
15752    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15753    // activity manager to announce its creation.
15754    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15755        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15756                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15757        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15758
15759        synchronized(this) {
15760            // !!! TODO: currently no check here that we're already bound
15761            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15762            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15763            synchronized (stats) {
15764                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15765            }
15766
15767            // Backup agent is now in use, its package can't be stopped.
15768            try {
15769                AppGlobals.getPackageManager().setPackageStoppedState(
15770                        app.packageName, false, UserHandle.getUserId(app.uid));
15771            } catch (RemoteException e) {
15772            } catch (IllegalArgumentException e) {
15773                Slog.w(TAG, "Failed trying to unstop package "
15774                        + app.packageName + ": " + e);
15775            }
15776
15777            BackupRecord r = new BackupRecord(ss, app, backupMode);
15778            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15779                    ? new ComponentName(app.packageName, app.backupAgentName)
15780                    : new ComponentName("android", "FullBackupAgent");
15781            // startProcessLocked() returns existing proc's record if it's already running
15782            ProcessRecord proc = startProcessLocked(app.processName, app,
15783                    false, 0, "backup", hostingName, false, false, false);
15784            if (proc == null) {
15785                Slog.e(TAG, "Unable to start backup agent process " + r);
15786                return false;
15787            }
15788
15789            r.app = proc;
15790            mBackupTarget = r;
15791            mBackupAppName = app.packageName;
15792
15793            // Try not to kill the process during backup
15794            updateOomAdjLocked(proc);
15795
15796            // If the process is already attached, schedule the creation of the backup agent now.
15797            // If it is not yet live, this will be done when it attaches to the framework.
15798            if (proc.thread != null) {
15799                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15800                try {
15801                    proc.thread.scheduleCreateBackupAgent(app,
15802                            compatibilityInfoForPackageLocked(app), backupMode);
15803                } catch (RemoteException e) {
15804                    // Will time out on the backup manager side
15805                }
15806            } else {
15807                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15808            }
15809            // Invariants: at this point, the target app process exists and the application
15810            // is either already running or in the process of coming up.  mBackupTarget and
15811            // mBackupAppName describe the app, so that when it binds back to the AM we
15812            // know that it's scheduled for a backup-agent operation.
15813        }
15814
15815        return true;
15816    }
15817
15818    @Override
15819    public void clearPendingBackup() {
15820        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15821        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15822
15823        synchronized (this) {
15824            mBackupTarget = null;
15825            mBackupAppName = null;
15826        }
15827    }
15828
15829    // A backup agent has just come up
15830    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15831        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15832                + " = " + agent);
15833
15834        synchronized(this) {
15835            if (!agentPackageName.equals(mBackupAppName)) {
15836                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15837                return;
15838            }
15839        }
15840
15841        long oldIdent = Binder.clearCallingIdentity();
15842        try {
15843            IBackupManager bm = IBackupManager.Stub.asInterface(
15844                    ServiceManager.getService(Context.BACKUP_SERVICE));
15845            bm.agentConnected(agentPackageName, agent);
15846        } catch (RemoteException e) {
15847            // can't happen; the backup manager service is local
15848        } catch (Exception e) {
15849            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15850            e.printStackTrace();
15851        } finally {
15852            Binder.restoreCallingIdentity(oldIdent);
15853        }
15854    }
15855
15856    // done with this agent
15857    public void unbindBackupAgent(ApplicationInfo appInfo) {
15858        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15859        if (appInfo == null) {
15860            Slog.w(TAG, "unbind backup agent for null app");
15861            return;
15862        }
15863
15864        synchronized(this) {
15865            try {
15866                if (mBackupAppName == null) {
15867                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15868                    return;
15869                }
15870
15871                if (!mBackupAppName.equals(appInfo.packageName)) {
15872                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15873                    return;
15874                }
15875
15876                // Not backing this app up any more; reset its OOM adjustment
15877                final ProcessRecord proc = mBackupTarget.app;
15878                updateOomAdjLocked(proc);
15879
15880                // If the app crashed during backup, 'thread' will be null here
15881                if (proc.thread != null) {
15882                    try {
15883                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15884                                compatibilityInfoForPackageLocked(appInfo));
15885                    } catch (Exception e) {
15886                        Slog.e(TAG, "Exception when unbinding backup agent:");
15887                        e.printStackTrace();
15888                    }
15889                }
15890            } finally {
15891                mBackupTarget = null;
15892                mBackupAppName = null;
15893            }
15894        }
15895    }
15896    // =========================================================
15897    // BROADCASTS
15898    // =========================================================
15899
15900    boolean isPendingBroadcastProcessLocked(int pid) {
15901        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15902                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15903    }
15904
15905    void skipPendingBroadcastLocked(int pid) {
15906            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15907            for (BroadcastQueue queue : mBroadcastQueues) {
15908                queue.skipPendingBroadcastLocked(pid);
15909            }
15910    }
15911
15912    // The app just attached; send any pending broadcasts that it should receive
15913    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15914        boolean didSomething = false;
15915        for (BroadcastQueue queue : mBroadcastQueues) {
15916            didSomething |= queue.sendPendingBroadcastsLocked(app);
15917        }
15918        return didSomething;
15919    }
15920
15921    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15922            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15923        enforceNotIsolatedCaller("registerReceiver");
15924        ArrayList<Intent> stickyIntents = null;
15925        ProcessRecord callerApp = null;
15926        int callingUid;
15927        int callingPid;
15928        synchronized(this) {
15929            if (caller != null) {
15930                callerApp = getRecordForAppLocked(caller);
15931                if (callerApp == null) {
15932                    throw new SecurityException(
15933                            "Unable to find app for caller " + caller
15934                            + " (pid=" + Binder.getCallingPid()
15935                            + ") when registering receiver " + receiver);
15936                }
15937                if (callerApp.info.uid != Process.SYSTEM_UID &&
15938                        !callerApp.pkgList.containsKey(callerPackage) &&
15939                        !"android".equals(callerPackage)) {
15940                    throw new SecurityException("Given caller package " + callerPackage
15941                            + " is not running in process " + callerApp);
15942                }
15943                callingUid = callerApp.info.uid;
15944                callingPid = callerApp.pid;
15945            } else {
15946                callerPackage = null;
15947                callingUid = Binder.getCallingUid();
15948                callingPid = Binder.getCallingPid();
15949            }
15950
15951            userId = handleIncomingUser(callingPid, callingUid, userId,
15952                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15953
15954            Iterator<String> actions = filter.actionsIterator();
15955            if (actions == null) {
15956                ArrayList<String> noAction = new ArrayList<String>(1);
15957                noAction.add(null);
15958                actions = noAction.iterator();
15959            }
15960
15961            // Collect stickies of users
15962            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15963            while (actions.hasNext()) {
15964                String action = actions.next();
15965                for (int id : userIds) {
15966                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15967                    if (stickies != null) {
15968                        ArrayList<Intent> intents = stickies.get(action);
15969                        if (intents != null) {
15970                            if (stickyIntents == null) {
15971                                stickyIntents = new ArrayList<Intent>();
15972                            }
15973                            stickyIntents.addAll(intents);
15974                        }
15975                    }
15976                }
15977            }
15978        }
15979
15980        ArrayList<Intent> allSticky = null;
15981        if (stickyIntents != null) {
15982            final ContentResolver resolver = mContext.getContentResolver();
15983            // Look for any matching sticky broadcasts...
15984            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15985                Intent intent = stickyIntents.get(i);
15986                // If intent has scheme "content", it will need to acccess
15987                // provider that needs to lock mProviderMap in ActivityThread
15988                // and also it may need to wait application response, so we
15989                // cannot lock ActivityManagerService here.
15990                if (filter.match(resolver, intent, true, TAG) >= 0) {
15991                    if (allSticky == null) {
15992                        allSticky = new ArrayList<Intent>();
15993                    }
15994                    allSticky.add(intent);
15995                }
15996            }
15997        }
15998
15999        // The first sticky in the list is returned directly back to the client.
16000        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16001        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16002        if (receiver == null) {
16003            return sticky;
16004        }
16005
16006        synchronized (this) {
16007            if (callerApp != null && (callerApp.thread == null
16008                    || callerApp.thread.asBinder() != caller.asBinder())) {
16009                // Original caller already died
16010                return null;
16011            }
16012            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16013            if (rl == null) {
16014                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16015                        userId, receiver);
16016                if (rl.app != null) {
16017                    rl.app.receivers.add(rl);
16018                } else {
16019                    try {
16020                        receiver.asBinder().linkToDeath(rl, 0);
16021                    } catch (RemoteException e) {
16022                        return sticky;
16023                    }
16024                    rl.linkedToDeath = true;
16025                }
16026                mRegisteredReceivers.put(receiver.asBinder(), rl);
16027            } else if (rl.uid != callingUid) {
16028                throw new IllegalArgumentException(
16029                        "Receiver requested to register for uid " + callingUid
16030                        + " was previously registered for uid " + rl.uid);
16031            } else if (rl.pid != callingPid) {
16032                throw new IllegalArgumentException(
16033                        "Receiver requested to register for pid " + callingPid
16034                        + " was previously registered for pid " + rl.pid);
16035            } else if (rl.userId != userId) {
16036                throw new IllegalArgumentException(
16037                        "Receiver requested to register for user " + userId
16038                        + " was previously registered for user " + rl.userId);
16039            }
16040            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16041                    permission, callingUid, userId);
16042            rl.add(bf);
16043            if (!bf.debugCheck()) {
16044                Slog.w(TAG, "==> For Dynamic broadcast");
16045            }
16046            mReceiverResolver.addFilter(bf);
16047
16048            // Enqueue broadcasts for all existing stickies that match
16049            // this filter.
16050            if (allSticky != null) {
16051                ArrayList receivers = new ArrayList();
16052                receivers.add(bf);
16053
16054                final int stickyCount = allSticky.size();
16055                for (int i = 0; i < stickyCount; i++) {
16056                    Intent intent = allSticky.get(i);
16057                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16058                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16059                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
16060                            null, null, false, true, true, -1);
16061                    queue.enqueueParallelBroadcastLocked(r);
16062                    queue.scheduleBroadcastsLocked();
16063                }
16064            }
16065
16066            return sticky;
16067        }
16068    }
16069
16070    public void unregisterReceiver(IIntentReceiver receiver) {
16071        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16072
16073        final long origId = Binder.clearCallingIdentity();
16074        try {
16075            boolean doTrim = false;
16076
16077            synchronized(this) {
16078                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16079                if (rl != null) {
16080                    final BroadcastRecord r = rl.curBroadcast;
16081                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16082                        final boolean doNext = r.queue.finishReceiverLocked(
16083                                r, r.resultCode, r.resultData, r.resultExtras,
16084                                r.resultAbort, false);
16085                        if (doNext) {
16086                            doTrim = true;
16087                            r.queue.processNextBroadcast(false);
16088                        }
16089                    }
16090
16091                    if (rl.app != null) {
16092                        rl.app.receivers.remove(rl);
16093                    }
16094                    removeReceiverLocked(rl);
16095                    if (rl.linkedToDeath) {
16096                        rl.linkedToDeath = false;
16097                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16098                    }
16099                }
16100            }
16101
16102            // If we actually concluded any broadcasts, we might now be able
16103            // to trim the recipients' apps from our working set
16104            if (doTrim) {
16105                trimApplications();
16106                return;
16107            }
16108
16109        } finally {
16110            Binder.restoreCallingIdentity(origId);
16111        }
16112    }
16113
16114    void removeReceiverLocked(ReceiverList rl) {
16115        mRegisteredReceivers.remove(rl.receiver.asBinder());
16116        for (int i = rl.size() - 1; i >= 0; i--) {
16117            mReceiverResolver.removeFilter(rl.get(i));
16118        }
16119    }
16120
16121    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16122        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16123            ProcessRecord r = mLruProcesses.get(i);
16124            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16125                try {
16126                    r.thread.dispatchPackageBroadcast(cmd, packages);
16127                } catch (RemoteException ex) {
16128                }
16129            }
16130        }
16131    }
16132
16133    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16134            int callingUid, int[] users) {
16135        List<ResolveInfo> receivers = null;
16136        try {
16137            HashSet<ComponentName> singleUserReceivers = null;
16138            boolean scannedFirstReceivers = false;
16139            for (int user : users) {
16140                // Skip users that have Shell restrictions
16141                if (callingUid == Process.SHELL_UID
16142                        && getUserManagerLocked().hasUserRestriction(
16143                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16144                    continue;
16145                }
16146                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16147                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16148                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16149                    // If this is not the primary user, we need to check for
16150                    // any receivers that should be filtered out.
16151                    for (int i=0; i<newReceivers.size(); i++) {
16152                        ResolveInfo ri = newReceivers.get(i);
16153                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16154                            newReceivers.remove(i);
16155                            i--;
16156                        }
16157                    }
16158                }
16159                if (newReceivers != null && newReceivers.size() == 0) {
16160                    newReceivers = null;
16161                }
16162                if (receivers == null) {
16163                    receivers = newReceivers;
16164                } else if (newReceivers != null) {
16165                    // We need to concatenate the additional receivers
16166                    // found with what we have do far.  This would be easy,
16167                    // but we also need to de-dup any receivers that are
16168                    // singleUser.
16169                    if (!scannedFirstReceivers) {
16170                        // Collect any single user receivers we had already retrieved.
16171                        scannedFirstReceivers = true;
16172                        for (int i=0; i<receivers.size(); i++) {
16173                            ResolveInfo ri = receivers.get(i);
16174                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16175                                ComponentName cn = new ComponentName(
16176                                        ri.activityInfo.packageName, ri.activityInfo.name);
16177                                if (singleUserReceivers == null) {
16178                                    singleUserReceivers = new HashSet<ComponentName>();
16179                                }
16180                                singleUserReceivers.add(cn);
16181                            }
16182                        }
16183                    }
16184                    // Add the new results to the existing results, tracking
16185                    // and de-dupping single user receivers.
16186                    for (int i=0; i<newReceivers.size(); i++) {
16187                        ResolveInfo ri = newReceivers.get(i);
16188                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16189                            ComponentName cn = new ComponentName(
16190                                    ri.activityInfo.packageName, ri.activityInfo.name);
16191                            if (singleUserReceivers == null) {
16192                                singleUserReceivers = new HashSet<ComponentName>();
16193                            }
16194                            if (!singleUserReceivers.contains(cn)) {
16195                                singleUserReceivers.add(cn);
16196                                receivers.add(ri);
16197                            }
16198                        } else {
16199                            receivers.add(ri);
16200                        }
16201                    }
16202                }
16203            }
16204        } catch (RemoteException ex) {
16205            // pm is in same process, this will never happen.
16206        }
16207        return receivers;
16208    }
16209
16210    private final int broadcastIntentLocked(ProcessRecord callerApp,
16211            String callerPackage, Intent intent, String resolvedType,
16212            IIntentReceiver resultTo, int resultCode, String resultData,
16213            Bundle map, String requiredPermission, int appOp,
16214            boolean ordered, boolean sticky, int callingPid, int callingUid,
16215            int userId) {
16216        intent = new Intent(intent);
16217
16218        // By default broadcasts do not go to stopped apps.
16219        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16220
16221        // If we have not finished booting, don't allow this to launch new processes.
16222        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16223            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16224        }
16225
16226        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16227                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16228                + " ordered=" + ordered + " userid=" + userId);
16229        if ((resultTo != null) && !ordered) {
16230            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16231        }
16232
16233        userId = handleIncomingUser(callingPid, callingUid, userId,
16234                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16235
16236        // Make sure that the user who is receiving this broadcast is running.
16237        // If not, we will just skip it. Make an exception for shutdown broadcasts
16238        // and upgrade steps.
16239
16240        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16241            if ((callingUid != Process.SYSTEM_UID
16242                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16243                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16244                Slog.w(TAG, "Skipping broadcast of " + intent
16245                        + ": user " + userId + " is stopped");
16246                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16247            }
16248        }
16249
16250        /*
16251         * Prevent non-system code (defined here to be non-persistent
16252         * processes) from sending protected broadcasts.
16253         */
16254        int callingAppId = UserHandle.getAppId(callingUid);
16255        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16256            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16257            || callingAppId == Process.NFC_UID || callingUid == 0) {
16258            // Always okay.
16259        } else if (callerApp == null || !callerApp.persistent) {
16260            try {
16261                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16262                        intent.getAction())) {
16263                    String msg = "Permission Denial: not allowed to send broadcast "
16264                            + intent.getAction() + " from pid="
16265                            + callingPid + ", uid=" + callingUid;
16266                    Slog.w(TAG, msg);
16267                    throw new SecurityException(msg);
16268                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16269                    // Special case for compatibility: we don't want apps to send this,
16270                    // but historically it has not been protected and apps may be using it
16271                    // to poke their own app widget.  So, instead of making it protected,
16272                    // just limit it to the caller.
16273                    if (callerApp == null) {
16274                        String msg = "Permission Denial: not allowed to send broadcast "
16275                                + intent.getAction() + " from unknown caller.";
16276                        Slog.w(TAG, msg);
16277                        throw new SecurityException(msg);
16278                    } else if (intent.getComponent() != null) {
16279                        // They are good enough to send to an explicit component...  verify
16280                        // it is being sent to the calling app.
16281                        if (!intent.getComponent().getPackageName().equals(
16282                                callerApp.info.packageName)) {
16283                            String msg = "Permission Denial: not allowed to send broadcast "
16284                                    + intent.getAction() + " to "
16285                                    + intent.getComponent().getPackageName() + " from "
16286                                    + callerApp.info.packageName;
16287                            Slog.w(TAG, msg);
16288                            throw new SecurityException(msg);
16289                        }
16290                    } else {
16291                        // Limit broadcast to their own package.
16292                        intent.setPackage(callerApp.info.packageName);
16293                    }
16294                }
16295            } catch (RemoteException e) {
16296                Slog.w(TAG, "Remote exception", e);
16297                return ActivityManager.BROADCAST_SUCCESS;
16298            }
16299        }
16300
16301        final String action = intent.getAction();
16302        if (action != null) {
16303            switch (action) {
16304                case Intent.ACTION_UID_REMOVED:
16305                case Intent.ACTION_PACKAGE_REMOVED:
16306                case Intent.ACTION_PACKAGE_CHANGED:
16307                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16308                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16309                    // Handle special intents: if this broadcast is from the package
16310                    // manager about a package being removed, we need to remove all of
16311                    // its activities from the history stack.
16312                    if (checkComponentPermission(
16313                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16314                            callingPid, callingUid, -1, true)
16315                            != PackageManager.PERMISSION_GRANTED) {
16316                        String msg = "Permission Denial: " + intent.getAction()
16317                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16318                                + ", uid=" + callingUid + ")"
16319                                + " requires "
16320                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16321                        Slog.w(TAG, msg);
16322                        throw new SecurityException(msg);
16323                    }
16324                    switch (action) {
16325                        case Intent.ACTION_UID_REMOVED:
16326                            final Bundle intentExtras = intent.getExtras();
16327                            final int uid = intentExtras != null
16328                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16329                            if (uid >= 0) {
16330                                mBatteryStatsService.removeUid(uid);
16331                                mAppOpsService.uidRemoved(uid);
16332                            }
16333                            break;
16334                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16335                            // If resources are unavailable just force stop all those packages
16336                            // and flush the attribute cache as well.
16337                            String list[] =
16338                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16339                            if (list != null && list.length > 0) {
16340                                for (int i = 0; i < list.length; i++) {
16341                                    forceStopPackageLocked(list[i], -1, false, true, true,
16342                                            false, false, userId, "storage unmount");
16343                                }
16344                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16345                                sendPackageBroadcastLocked(
16346                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16347                                        userId);
16348                            }
16349                            break;
16350                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16351                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16352                            break;
16353                        case Intent.ACTION_PACKAGE_REMOVED:
16354                        case Intent.ACTION_PACKAGE_CHANGED:
16355                            Uri data = intent.getData();
16356                            String ssp;
16357                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16358                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16359                                boolean fullUninstall = removed &&
16360                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16361                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16362                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16363                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16364                                            false, true, true, false, fullUninstall, userId,
16365                                            removed ? "pkg removed" : "pkg changed");
16366                                }
16367                                if (removed) {
16368                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16369                                            new String[] {ssp}, userId);
16370                                    if (fullUninstall) {
16371                                        mAppOpsService.packageRemoved(
16372                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16373
16374                                        // Remove all permissions granted from/to this package
16375                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16376
16377                                        removeTasksByPackageNameLocked(ssp, userId);
16378                                        mBatteryStatsService.notePackageUninstalled(ssp);
16379                                    }
16380                                } else {
16381                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16382                                            intent.getStringArrayExtra(
16383                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16384                                }
16385                            }
16386                            break;
16387                    }
16388                    break;
16389                case Intent.ACTION_PACKAGE_ADDED:
16390                    // Special case for adding a package: by default turn on compatibility mode.
16391                    Uri data = intent.getData();
16392                    String ssp;
16393                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16394                        final boolean replacing =
16395                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16396                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16397
16398                        try {
16399                            ApplicationInfo ai = AppGlobals.getPackageManager().
16400                                    getApplicationInfo(ssp, 0, 0);
16401                            mBatteryStatsService.notePackageInstalled(ssp,
16402                                    ai != null ? ai.versionCode : 0);
16403                        } catch (RemoteException e) {
16404                        }
16405                    }
16406                    break;
16407                case Intent.ACTION_TIMEZONE_CHANGED:
16408                    // If this is the time zone changed action, queue up a message that will reset
16409                    // the timezone of all currently running processes. This message will get
16410                    // queued up before the broadcast happens.
16411                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16412                    break;
16413                case Intent.ACTION_TIME_CHANGED:
16414                    // If the user set the time, let all running processes know.
16415                    final int is24Hour =
16416                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16417                                    : 0;
16418                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16419                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16420                    synchronized (stats) {
16421                        stats.noteCurrentTimeChangedLocked();
16422                    }
16423                    break;
16424                case Intent.ACTION_CLEAR_DNS_CACHE:
16425                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16426                    break;
16427                case Proxy.PROXY_CHANGE_ACTION:
16428                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16429                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16430                    break;
16431            }
16432        }
16433
16434        // Add to the sticky list if requested.
16435        if (sticky) {
16436            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16437                    callingPid, callingUid)
16438                    != PackageManager.PERMISSION_GRANTED) {
16439                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16440                        + callingPid + ", uid=" + callingUid
16441                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16442                Slog.w(TAG, msg);
16443                throw new SecurityException(msg);
16444            }
16445            if (requiredPermission != null) {
16446                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16447                        + " and enforce permission " + requiredPermission);
16448                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16449            }
16450            if (intent.getComponent() != null) {
16451                throw new SecurityException(
16452                        "Sticky broadcasts can't target a specific component");
16453            }
16454            // We use userId directly here, since the "all" target is maintained
16455            // as a separate set of sticky broadcasts.
16456            if (userId != UserHandle.USER_ALL) {
16457                // But first, if this is not a broadcast to all users, then
16458                // make sure it doesn't conflict with an existing broadcast to
16459                // all users.
16460                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16461                        UserHandle.USER_ALL);
16462                if (stickies != null) {
16463                    ArrayList<Intent> list = stickies.get(intent.getAction());
16464                    if (list != null) {
16465                        int N = list.size();
16466                        int i;
16467                        for (i=0; i<N; i++) {
16468                            if (intent.filterEquals(list.get(i))) {
16469                                throw new IllegalArgumentException(
16470                                        "Sticky broadcast " + intent + " for user "
16471                                        + userId + " conflicts with existing global broadcast");
16472                            }
16473                        }
16474                    }
16475                }
16476            }
16477            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16478            if (stickies == null) {
16479                stickies = new ArrayMap<>();
16480                mStickyBroadcasts.put(userId, stickies);
16481            }
16482            ArrayList<Intent> list = stickies.get(intent.getAction());
16483            if (list == null) {
16484                list = new ArrayList<>();
16485                stickies.put(intent.getAction(), list);
16486            }
16487            final int stickiesCount = list.size();
16488            int i;
16489            for (i = 0; i < stickiesCount; i++) {
16490                if (intent.filterEquals(list.get(i))) {
16491                    // This sticky already exists, replace it.
16492                    list.set(i, new Intent(intent));
16493                    break;
16494                }
16495            }
16496            if (i >= stickiesCount) {
16497                list.add(new Intent(intent));
16498            }
16499        }
16500
16501        int[] users;
16502        if (userId == UserHandle.USER_ALL) {
16503            // Caller wants broadcast to go to all started users.
16504            users = mStartedUserArray;
16505        } else {
16506            // Caller wants broadcast to go to one specific user.
16507            users = new int[] {userId};
16508        }
16509
16510        // Figure out who all will receive this broadcast.
16511        List receivers = null;
16512        List<BroadcastFilter> registeredReceivers = null;
16513        // Need to resolve the intent to interested receivers...
16514        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16515                 == 0) {
16516            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16517        }
16518        if (intent.getComponent() == null) {
16519            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16520                // Query one target user at a time, excluding shell-restricted users
16521                UserManagerService ums = getUserManagerLocked();
16522                for (int i = 0; i < users.length; i++) {
16523                    if (ums.hasUserRestriction(
16524                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16525                        continue;
16526                    }
16527                    List<BroadcastFilter> registeredReceiversForUser =
16528                            mReceiverResolver.queryIntent(intent,
16529                                    resolvedType, false, users[i]);
16530                    if (registeredReceivers == null) {
16531                        registeredReceivers = registeredReceiversForUser;
16532                    } else if (registeredReceiversForUser != null) {
16533                        registeredReceivers.addAll(registeredReceiversForUser);
16534                    }
16535                }
16536            } else {
16537                registeredReceivers = mReceiverResolver.queryIntent(intent,
16538                        resolvedType, false, userId);
16539            }
16540        }
16541
16542        final boolean replacePending =
16543                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16544
16545        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16546                + " replacePending=" + replacePending);
16547
16548        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16549        if (!ordered && NR > 0) {
16550            // If we are not serializing this broadcast, then send the
16551            // registered receivers separately so they don't wait for the
16552            // components to be launched.
16553            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16554            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16555                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16556                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16557                    ordered, sticky, false, userId);
16558            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16559            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16560            if (!replaced) {
16561                queue.enqueueParallelBroadcastLocked(r);
16562                queue.scheduleBroadcastsLocked();
16563            }
16564            registeredReceivers = null;
16565            NR = 0;
16566        }
16567
16568        // Merge into one list.
16569        int ir = 0;
16570        if (receivers != null) {
16571            // A special case for PACKAGE_ADDED: do not allow the package
16572            // being added to see this broadcast.  This prevents them from
16573            // using this as a back door to get run as soon as they are
16574            // installed.  Maybe in the future we want to have a special install
16575            // broadcast or such for apps, but we'd like to deliberately make
16576            // this decision.
16577            String skipPackages[] = null;
16578            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16579                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16580                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16581                Uri data = intent.getData();
16582                if (data != null) {
16583                    String pkgName = data.getSchemeSpecificPart();
16584                    if (pkgName != null) {
16585                        skipPackages = new String[] { pkgName };
16586                    }
16587                }
16588            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16589                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16590            }
16591            if (skipPackages != null && (skipPackages.length > 0)) {
16592                for (String skipPackage : skipPackages) {
16593                    if (skipPackage != null) {
16594                        int NT = receivers.size();
16595                        for (int it=0; it<NT; it++) {
16596                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16597                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16598                                receivers.remove(it);
16599                                it--;
16600                                NT--;
16601                            }
16602                        }
16603                    }
16604                }
16605            }
16606
16607            int NT = receivers != null ? receivers.size() : 0;
16608            int it = 0;
16609            ResolveInfo curt = null;
16610            BroadcastFilter curr = null;
16611            while (it < NT && ir < NR) {
16612                if (curt == null) {
16613                    curt = (ResolveInfo)receivers.get(it);
16614                }
16615                if (curr == null) {
16616                    curr = registeredReceivers.get(ir);
16617                }
16618                if (curr.getPriority() >= curt.priority) {
16619                    // Insert this broadcast record into the final list.
16620                    receivers.add(it, curr);
16621                    ir++;
16622                    curr = null;
16623                    it++;
16624                    NT++;
16625                } else {
16626                    // Skip to the next ResolveInfo in the final list.
16627                    it++;
16628                    curt = null;
16629                }
16630            }
16631        }
16632        while (ir < NR) {
16633            if (receivers == null) {
16634                receivers = new ArrayList();
16635            }
16636            receivers.add(registeredReceivers.get(ir));
16637            ir++;
16638        }
16639
16640        if ((receivers != null && receivers.size() > 0)
16641                || resultTo != null) {
16642            BroadcastQueue queue = broadcastQueueForIntent(intent);
16643            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16644                    callerPackage, callingPid, callingUid, resolvedType,
16645                    requiredPermission, appOp, receivers, resultTo, resultCode,
16646                    resultData, map, ordered, sticky, false, userId);
16647
16648            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16649                    + ": prev had " + queue.mOrderedBroadcasts.size());
16650            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16651                    "Enqueueing broadcast " + r.intent.getAction());
16652
16653            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16654            if (!replaced) {
16655                queue.enqueueOrderedBroadcastLocked(r);
16656                queue.scheduleBroadcastsLocked();
16657            }
16658        }
16659
16660        return ActivityManager.BROADCAST_SUCCESS;
16661    }
16662
16663    final Intent verifyBroadcastLocked(Intent intent) {
16664        // Refuse possible leaked file descriptors
16665        if (intent != null && intent.hasFileDescriptors() == true) {
16666            throw new IllegalArgumentException("File descriptors passed in Intent");
16667        }
16668
16669        int flags = intent.getFlags();
16670
16671        if (!mProcessesReady) {
16672            // if the caller really truly claims to know what they're doing, go
16673            // ahead and allow the broadcast without launching any receivers
16674            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16675                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16676            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16677                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16678                        + " before boot completion");
16679                throw new IllegalStateException("Cannot broadcast before boot completed");
16680            }
16681        }
16682
16683        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16684            throw new IllegalArgumentException(
16685                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16686        }
16687
16688        return intent;
16689    }
16690
16691    public final int broadcastIntent(IApplicationThread caller,
16692            Intent intent, String resolvedType, IIntentReceiver resultTo,
16693            int resultCode, String resultData, Bundle map,
16694            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16695        enforceNotIsolatedCaller("broadcastIntent");
16696        synchronized(this) {
16697            intent = verifyBroadcastLocked(intent);
16698
16699            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16700            final int callingPid = Binder.getCallingPid();
16701            final int callingUid = Binder.getCallingUid();
16702            final long origId = Binder.clearCallingIdentity();
16703            int res = broadcastIntentLocked(callerApp,
16704                    callerApp != null ? callerApp.info.packageName : null,
16705                    intent, resolvedType, resultTo,
16706                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16707                    callingPid, callingUid, userId);
16708            Binder.restoreCallingIdentity(origId);
16709            return res;
16710        }
16711    }
16712
16713    int broadcastIntentInPackage(String packageName, int uid,
16714            Intent intent, String resolvedType, IIntentReceiver resultTo,
16715            int resultCode, String resultData, Bundle map,
16716            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16717        synchronized(this) {
16718            intent = verifyBroadcastLocked(intent);
16719
16720            final long origId = Binder.clearCallingIdentity();
16721            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16722                    resultTo, resultCode, resultData, map, requiredPermission,
16723                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16724            Binder.restoreCallingIdentity(origId);
16725            return res;
16726        }
16727    }
16728
16729    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16730        // Refuse possible leaked file descriptors
16731        if (intent != null && intent.hasFileDescriptors() == true) {
16732            throw new IllegalArgumentException("File descriptors passed in Intent");
16733        }
16734
16735        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16736                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16737
16738        synchronized(this) {
16739            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16740                    != PackageManager.PERMISSION_GRANTED) {
16741                String msg = "Permission Denial: unbroadcastIntent() from pid="
16742                        + Binder.getCallingPid()
16743                        + ", uid=" + Binder.getCallingUid()
16744                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16745                Slog.w(TAG, msg);
16746                throw new SecurityException(msg);
16747            }
16748            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16749            if (stickies != null) {
16750                ArrayList<Intent> list = stickies.get(intent.getAction());
16751                if (list != null) {
16752                    int N = list.size();
16753                    int i;
16754                    for (i=0; i<N; i++) {
16755                        if (intent.filterEquals(list.get(i))) {
16756                            list.remove(i);
16757                            break;
16758                        }
16759                    }
16760                    if (list.size() <= 0) {
16761                        stickies.remove(intent.getAction());
16762                    }
16763                }
16764                if (stickies.size() <= 0) {
16765                    mStickyBroadcasts.remove(userId);
16766                }
16767            }
16768        }
16769    }
16770
16771    void backgroundServicesFinishedLocked(int userId) {
16772        for (BroadcastQueue queue : mBroadcastQueues) {
16773            queue.backgroundServicesFinishedLocked(userId);
16774        }
16775    }
16776
16777    public void finishReceiver(IBinder who, int resultCode, String resultData,
16778            Bundle resultExtras, boolean resultAbort, int flags) {
16779        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16780
16781        // Refuse possible leaked file descriptors
16782        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16783            throw new IllegalArgumentException("File descriptors passed in Bundle");
16784        }
16785
16786        final long origId = Binder.clearCallingIdentity();
16787        try {
16788            boolean doNext = false;
16789            BroadcastRecord r;
16790
16791            synchronized(this) {
16792                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16793                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16794                r = queue.getMatchingOrderedReceiver(who);
16795                if (r != null) {
16796                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16797                        resultData, resultExtras, resultAbort, true);
16798                }
16799            }
16800
16801            if (doNext) {
16802                r.queue.processNextBroadcast(false);
16803            }
16804            trimApplications();
16805        } finally {
16806            Binder.restoreCallingIdentity(origId);
16807        }
16808    }
16809
16810    // =========================================================
16811    // INSTRUMENTATION
16812    // =========================================================
16813
16814    public boolean startInstrumentation(ComponentName className,
16815            String profileFile, int flags, Bundle arguments,
16816            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16817            int userId, String abiOverride) {
16818        enforceNotIsolatedCaller("startInstrumentation");
16819        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16820                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16821        // Refuse possible leaked file descriptors
16822        if (arguments != null && arguments.hasFileDescriptors()) {
16823            throw new IllegalArgumentException("File descriptors passed in Bundle");
16824        }
16825
16826        synchronized(this) {
16827            InstrumentationInfo ii = null;
16828            ApplicationInfo ai = null;
16829            try {
16830                ii = mContext.getPackageManager().getInstrumentationInfo(
16831                    className, STOCK_PM_FLAGS);
16832                ai = AppGlobals.getPackageManager().getApplicationInfo(
16833                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16834            } catch (PackageManager.NameNotFoundException e) {
16835            } catch (RemoteException e) {
16836            }
16837            if (ii == null) {
16838                reportStartInstrumentationFailure(watcher, className,
16839                        "Unable to find instrumentation info for: " + className);
16840                return false;
16841            }
16842            if (ai == null) {
16843                reportStartInstrumentationFailure(watcher, className,
16844                        "Unable to find instrumentation target package: " + ii.targetPackage);
16845                return false;
16846            }
16847
16848            int match = mContext.getPackageManager().checkSignatures(
16849                    ii.targetPackage, ii.packageName);
16850            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16851                String msg = "Permission Denial: starting instrumentation "
16852                        + className + " from pid="
16853                        + Binder.getCallingPid()
16854                        + ", uid=" + Binder.getCallingPid()
16855                        + " not allowed because package " + ii.packageName
16856                        + " does not have a signature matching the target "
16857                        + ii.targetPackage;
16858                reportStartInstrumentationFailure(watcher, className, msg);
16859                throw new SecurityException(msg);
16860            }
16861
16862            final long origId = Binder.clearCallingIdentity();
16863            // Instrumentation can kill and relaunch even persistent processes
16864            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16865                    "start instr");
16866            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16867            app.instrumentationClass = className;
16868            app.instrumentationInfo = ai;
16869            app.instrumentationProfileFile = profileFile;
16870            app.instrumentationArguments = arguments;
16871            app.instrumentationWatcher = watcher;
16872            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16873            app.instrumentationResultClass = className;
16874            Binder.restoreCallingIdentity(origId);
16875        }
16876
16877        return true;
16878    }
16879
16880    /**
16881     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16882     * error to the logs, but if somebody is watching, send the report there too.  This enables
16883     * the "am" command to report errors with more information.
16884     *
16885     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16886     * @param cn The component name of the instrumentation.
16887     * @param report The error report.
16888     */
16889    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16890            ComponentName cn, String report) {
16891        Slog.w(TAG, report);
16892        try {
16893            if (watcher != null) {
16894                Bundle results = new Bundle();
16895                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16896                results.putString("Error", report);
16897                watcher.instrumentationStatus(cn, -1, results);
16898            }
16899        } catch (RemoteException e) {
16900            Slog.w(TAG, e);
16901        }
16902    }
16903
16904    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16905        if (app.instrumentationWatcher != null) {
16906            try {
16907                // NOTE:  IInstrumentationWatcher *must* be oneway here
16908                app.instrumentationWatcher.instrumentationFinished(
16909                    app.instrumentationClass,
16910                    resultCode,
16911                    results);
16912            } catch (RemoteException e) {
16913            }
16914        }
16915        if (app.instrumentationUiAutomationConnection != null) {
16916            try {
16917                app.instrumentationUiAutomationConnection.shutdown();
16918            } catch (RemoteException re) {
16919                /* ignore */
16920            }
16921            // Only a UiAutomation can set this flag and now that
16922            // it is finished we make sure it is reset to its default.
16923            mUserIsMonkey = false;
16924        }
16925        app.instrumentationWatcher = null;
16926        app.instrumentationUiAutomationConnection = null;
16927        app.instrumentationClass = null;
16928        app.instrumentationInfo = null;
16929        app.instrumentationProfileFile = null;
16930        app.instrumentationArguments = null;
16931
16932        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16933                "finished inst");
16934    }
16935
16936    public void finishInstrumentation(IApplicationThread target,
16937            int resultCode, Bundle results) {
16938        int userId = UserHandle.getCallingUserId();
16939        // Refuse possible leaked file descriptors
16940        if (results != null && results.hasFileDescriptors()) {
16941            throw new IllegalArgumentException("File descriptors passed in Intent");
16942        }
16943
16944        synchronized(this) {
16945            ProcessRecord app = getRecordForAppLocked(target);
16946            if (app == null) {
16947                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16948                return;
16949            }
16950            final long origId = Binder.clearCallingIdentity();
16951            finishInstrumentationLocked(app, resultCode, results);
16952            Binder.restoreCallingIdentity(origId);
16953        }
16954    }
16955
16956    // =========================================================
16957    // CONFIGURATION
16958    // =========================================================
16959
16960    public ConfigurationInfo getDeviceConfigurationInfo() {
16961        ConfigurationInfo config = new ConfigurationInfo();
16962        synchronized (this) {
16963            config.reqTouchScreen = mConfiguration.touchscreen;
16964            config.reqKeyboardType = mConfiguration.keyboard;
16965            config.reqNavigation = mConfiguration.navigation;
16966            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16967                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16968                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16969            }
16970            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16971                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16972                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16973            }
16974            config.reqGlEsVersion = GL_ES_VERSION;
16975        }
16976        return config;
16977    }
16978
16979    ActivityStack getFocusedStack() {
16980        return mStackSupervisor.getFocusedStack();
16981    }
16982
16983    @Override
16984    public int getFocusedStackId() throws RemoteException {
16985        ActivityStack focusedStack = getFocusedStack();
16986        if (focusedStack != null) {
16987            return focusedStack.getStackId();
16988        }
16989        return -1;
16990    }
16991
16992    public Configuration getConfiguration() {
16993        Configuration ci;
16994        synchronized(this) {
16995            ci = new Configuration(mConfiguration);
16996            ci.userSetLocale = false;
16997        }
16998        return ci;
16999    }
17000
17001    public void updatePersistentConfiguration(Configuration values) {
17002        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17003                "updateConfiguration()");
17004        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17005                "updateConfiguration()");
17006        if (values == null) {
17007            throw new NullPointerException("Configuration must not be null");
17008        }
17009
17010        synchronized(this) {
17011            final long origId = Binder.clearCallingIdentity();
17012            updateConfigurationLocked(values, null, true, false);
17013            Binder.restoreCallingIdentity(origId);
17014        }
17015    }
17016
17017    public void updateConfiguration(Configuration values) {
17018        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17019                "updateConfiguration()");
17020
17021        synchronized(this) {
17022            if (values == null && mWindowManager != null) {
17023                // sentinel: fetch the current configuration from the window manager
17024                values = mWindowManager.computeNewConfiguration();
17025            }
17026
17027            if (mWindowManager != null) {
17028                mProcessList.applyDisplaySize(mWindowManager);
17029            }
17030
17031            final long origId = Binder.clearCallingIdentity();
17032            if (values != null) {
17033                Settings.System.clearConfiguration(values);
17034            }
17035            updateConfigurationLocked(values, null, false, false);
17036            Binder.restoreCallingIdentity(origId);
17037        }
17038    }
17039
17040    /**
17041     * Do either or both things: (1) change the current configuration, and (2)
17042     * make sure the given activity is running with the (now) current
17043     * configuration.  Returns true if the activity has been left running, or
17044     * false if <var>starting</var> is being destroyed to match the new
17045     * configuration.
17046     * @param persistent TODO
17047     */
17048    boolean updateConfigurationLocked(Configuration values,
17049            ActivityRecord starting, boolean persistent, boolean initLocale) {
17050        int changes = 0;
17051
17052        if (values != null) {
17053            Configuration newConfig = new Configuration(mConfiguration);
17054            changes = newConfig.updateFrom(values);
17055            if (changes != 0) {
17056                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17057                        "Updating configuration to: " + values);
17058
17059                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17060
17061                if (!initLocale && values.locale != null && values.userSetLocale) {
17062                    final String languageTag = values.locale.toLanguageTag();
17063                    SystemProperties.set("persist.sys.locale", languageTag);
17064                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17065                            values.locale));
17066                }
17067
17068                mConfigurationSeq++;
17069                if (mConfigurationSeq <= 0) {
17070                    mConfigurationSeq = 1;
17071                }
17072                newConfig.seq = mConfigurationSeq;
17073                mConfiguration = newConfig;
17074                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17075                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17076                //mUsageStatsService.noteStartConfig(newConfig);
17077
17078                final Configuration configCopy = new Configuration(mConfiguration);
17079
17080                // TODO: If our config changes, should we auto dismiss any currently
17081                // showing dialogs?
17082                mShowDialogs = shouldShowDialogs(newConfig);
17083
17084                AttributeCache ac = AttributeCache.instance();
17085                if (ac != null) {
17086                    ac.updateConfiguration(configCopy);
17087                }
17088
17089                // Make sure all resources in our process are updated
17090                // right now, so that anyone who is going to retrieve
17091                // resource values after we return will be sure to get
17092                // the new ones.  This is especially important during
17093                // boot, where the first config change needs to guarantee
17094                // all resources have that config before following boot
17095                // code is executed.
17096                mSystemThread.applyConfigurationToResources(configCopy);
17097
17098                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17099                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17100                    msg.obj = new Configuration(configCopy);
17101                    mHandler.sendMessage(msg);
17102                }
17103
17104                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17105                    ProcessRecord app = mLruProcesses.get(i);
17106                    try {
17107                        if (app.thread != null) {
17108                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17109                                    + app.processName + " new config " + mConfiguration);
17110                            app.thread.scheduleConfigurationChanged(configCopy);
17111                        }
17112                    } catch (Exception e) {
17113                    }
17114                }
17115                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17116                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17117                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17118                        | Intent.FLAG_RECEIVER_FOREGROUND);
17119                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17120                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
17121                        Process.SYSTEM_UID, UserHandle.USER_ALL);
17122                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17123                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17124                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17125                    if (!mProcessesReady) {
17126                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17127                    }
17128                    broadcastIntentLocked(null, null, intent,
17129                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17130                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17131                }
17132            }
17133        }
17134
17135        boolean kept = true;
17136        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17137        // mainStack is null during startup.
17138        if (mainStack != null) {
17139            if (changes != 0 && starting == null) {
17140                // If the configuration changed, and the caller is not already
17141                // in the process of starting an activity, then find the top
17142                // activity to check if its configuration needs to change.
17143                starting = mainStack.topRunningActivityLocked(null);
17144            }
17145
17146            if (starting != null) {
17147                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17148                // And we need to make sure at this point that all other activities
17149                // are made visible with the correct configuration.
17150                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17151            }
17152        }
17153
17154        if (values != null && mWindowManager != null) {
17155            mWindowManager.setNewConfiguration(mConfiguration);
17156        }
17157
17158        return kept;
17159    }
17160
17161    /**
17162     * Decide based on the configuration whether we should shouw the ANR,
17163     * crash, etc dialogs.  The idea is that if there is no affordnace to
17164     * press the on-screen buttons, we shouldn't show the dialog.
17165     *
17166     * A thought: SystemUI might also want to get told about this, the Power
17167     * dialog / global actions also might want different behaviors.
17168     */
17169    private static final boolean shouldShowDialogs(Configuration config) {
17170        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17171                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17172                && config.navigation == Configuration.NAVIGATION_NONAV);
17173    }
17174
17175    @Override
17176    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17177        synchronized (this) {
17178            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17179            if (srec != null) {
17180                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17181            }
17182        }
17183        return false;
17184    }
17185
17186    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17187            Intent resultData) {
17188
17189        synchronized (this) {
17190            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17191            if (r != null) {
17192                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17193            }
17194            return false;
17195        }
17196    }
17197
17198    public int getLaunchedFromUid(IBinder activityToken) {
17199        ActivityRecord srec;
17200        synchronized (this) {
17201            srec = ActivityRecord.forTokenLocked(activityToken);
17202        }
17203        if (srec == null) {
17204            return -1;
17205        }
17206        return srec.launchedFromUid;
17207    }
17208
17209    public String getLaunchedFromPackage(IBinder activityToken) {
17210        ActivityRecord srec;
17211        synchronized (this) {
17212            srec = ActivityRecord.forTokenLocked(activityToken);
17213        }
17214        if (srec == null) {
17215            return null;
17216        }
17217        return srec.launchedFromPackage;
17218    }
17219
17220    // =========================================================
17221    // LIFETIME MANAGEMENT
17222    // =========================================================
17223
17224    // Returns which broadcast queue the app is the current [or imminent] receiver
17225    // on, or 'null' if the app is not an active broadcast recipient.
17226    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17227        BroadcastRecord r = app.curReceiver;
17228        if (r != null) {
17229            return r.queue;
17230        }
17231
17232        // It's not the current receiver, but it might be starting up to become one
17233        synchronized (this) {
17234            for (BroadcastQueue queue : mBroadcastQueues) {
17235                r = queue.mPendingBroadcast;
17236                if (r != null && r.curApp == app) {
17237                    // found it; report which queue it's in
17238                    return queue;
17239                }
17240            }
17241        }
17242
17243        return null;
17244    }
17245
17246    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17247            ComponentName targetComponent, String targetProcess) {
17248        if (!mTrackingAssociations) {
17249            return null;
17250        }
17251        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17252                = mAssociations.get(targetUid);
17253        if (components == null) {
17254            components = new ArrayMap<>();
17255            mAssociations.put(targetUid, components);
17256        }
17257        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17258        if (sourceUids == null) {
17259            sourceUids = new SparseArray<>();
17260            components.put(targetComponent, sourceUids);
17261        }
17262        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17263        if (sourceProcesses == null) {
17264            sourceProcesses = new ArrayMap<>();
17265            sourceUids.put(sourceUid, sourceProcesses);
17266        }
17267        Association ass = sourceProcesses.get(sourceProcess);
17268        if (ass == null) {
17269            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17270                    targetProcess);
17271            sourceProcesses.put(sourceProcess, ass);
17272        }
17273        ass.mCount++;
17274        ass.mNesting++;
17275        if (ass.mNesting == 1) {
17276            ass.mStartTime = SystemClock.uptimeMillis();
17277        }
17278        return ass;
17279    }
17280
17281    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17282            ComponentName targetComponent) {
17283        if (!mTrackingAssociations) {
17284            return;
17285        }
17286        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17287                = mAssociations.get(targetUid);
17288        if (components == null) {
17289            return;
17290        }
17291        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17292        if (sourceUids == null) {
17293            return;
17294        }
17295        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17296        if (sourceProcesses == null) {
17297            return;
17298        }
17299        Association ass = sourceProcesses.get(sourceProcess);
17300        if (ass == null || ass.mNesting <= 0) {
17301            return;
17302        }
17303        ass.mNesting--;
17304        if (ass.mNesting == 0) {
17305            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17306        }
17307    }
17308
17309    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17310            boolean doingAll, long now) {
17311        if (mAdjSeq == app.adjSeq) {
17312            // This adjustment has already been computed.
17313            return app.curRawAdj;
17314        }
17315
17316        if (app.thread == null) {
17317            app.adjSeq = mAdjSeq;
17318            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17319            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17320            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17321        }
17322
17323        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17324        app.adjSource = null;
17325        app.adjTarget = null;
17326        app.empty = false;
17327        app.cached = false;
17328
17329        final int activitiesSize = app.activities.size();
17330
17331        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17332            // The max adjustment doesn't allow this app to be anything
17333            // below foreground, so it is not worth doing work for it.
17334            app.adjType = "fixed";
17335            app.adjSeq = mAdjSeq;
17336            app.curRawAdj = app.maxAdj;
17337            app.foregroundActivities = false;
17338            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17339            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17340            // System processes can do UI, and when they do we want to have
17341            // them trim their memory after the user leaves the UI.  To
17342            // facilitate this, here we need to determine whether or not it
17343            // is currently showing UI.
17344            app.systemNoUi = true;
17345            if (app == TOP_APP) {
17346                app.systemNoUi = false;
17347            } else if (activitiesSize > 0) {
17348                for (int j = 0; j < activitiesSize; j++) {
17349                    final ActivityRecord r = app.activities.get(j);
17350                    if (r.visible) {
17351                        app.systemNoUi = false;
17352                    }
17353                }
17354            }
17355            if (!app.systemNoUi) {
17356                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17357            }
17358            return (app.curAdj=app.maxAdj);
17359        }
17360
17361        app.systemNoUi = false;
17362
17363        final int PROCESS_STATE_TOP = mTopProcessState;
17364
17365        // Determine the importance of the process, starting with most
17366        // important to least, and assign an appropriate OOM adjustment.
17367        int adj;
17368        int schedGroup;
17369        int procState;
17370        boolean foregroundActivities = false;
17371        BroadcastQueue queue;
17372        if (app == TOP_APP) {
17373            // The last app on the list is the foreground app.
17374            adj = ProcessList.FOREGROUND_APP_ADJ;
17375            schedGroup = Process.THREAD_GROUP_DEFAULT;
17376            app.adjType = "top-activity";
17377            foregroundActivities = true;
17378            procState = PROCESS_STATE_TOP;
17379        } else if (app.instrumentationClass != null) {
17380            // Don't want to kill running instrumentation.
17381            adj = ProcessList.FOREGROUND_APP_ADJ;
17382            schedGroup = Process.THREAD_GROUP_DEFAULT;
17383            app.adjType = "instrumentation";
17384            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17385        } else if ((queue = isReceivingBroadcast(app)) != null) {
17386            // An app that is currently receiving a broadcast also
17387            // counts as being in the foreground for OOM killer purposes.
17388            // It's placed in a sched group based on the nature of the
17389            // broadcast as reflected by which queue it's active in.
17390            adj = ProcessList.FOREGROUND_APP_ADJ;
17391            schedGroup = (queue == mFgBroadcastQueue)
17392                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17393            app.adjType = "broadcast";
17394            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17395        } else if (app.executingServices.size() > 0) {
17396            // An app that is currently executing a service callback also
17397            // counts as being in the foreground.
17398            adj = ProcessList.FOREGROUND_APP_ADJ;
17399            schedGroup = app.execServicesFg ?
17400                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17401            app.adjType = "exec-service";
17402            procState = ActivityManager.PROCESS_STATE_SERVICE;
17403            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17404        } else {
17405            // As far as we know the process is empty.  We may change our mind later.
17406            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17407            // At this point we don't actually know the adjustment.  Use the cached adj
17408            // value that the caller wants us to.
17409            adj = cachedAdj;
17410            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17411            app.cached = true;
17412            app.empty = true;
17413            app.adjType = "cch-empty";
17414        }
17415
17416        // Examine all activities if not already foreground.
17417        if (!foregroundActivities && activitiesSize > 0) {
17418            for (int j = 0; j < activitiesSize; j++) {
17419                final ActivityRecord r = app.activities.get(j);
17420                if (r.app != app) {
17421                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17422                            + app + "?!? Using " + r.app + " instead.");
17423                    continue;
17424                }
17425                if (r.visible) {
17426                    // App has a visible activity; only upgrade adjustment.
17427                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17428                        adj = ProcessList.VISIBLE_APP_ADJ;
17429                        app.adjType = "visible";
17430                    }
17431                    if (procState > PROCESS_STATE_TOP) {
17432                        procState = PROCESS_STATE_TOP;
17433                    }
17434                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17435                    app.cached = false;
17436                    app.empty = false;
17437                    foregroundActivities = true;
17438                    break;
17439                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17440                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17441                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17442                        app.adjType = "pausing";
17443                    }
17444                    if (procState > PROCESS_STATE_TOP) {
17445                        procState = PROCESS_STATE_TOP;
17446                    }
17447                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17448                    app.cached = false;
17449                    app.empty = false;
17450                    foregroundActivities = true;
17451                } else if (r.state == ActivityState.STOPPING) {
17452                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17453                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17454                        app.adjType = "stopping";
17455                    }
17456                    // For the process state, we will at this point consider the
17457                    // process to be cached.  It will be cached either as an activity
17458                    // or empty depending on whether the activity is finishing.  We do
17459                    // this so that we can treat the process as cached for purposes of
17460                    // memory trimming (determing current memory level, trim command to
17461                    // send to process) since there can be an arbitrary number of stopping
17462                    // processes and they should soon all go into the cached state.
17463                    if (!r.finishing) {
17464                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17465                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17466                        }
17467                    }
17468                    app.cached = false;
17469                    app.empty = false;
17470                    foregroundActivities = true;
17471                } else {
17472                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17473                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17474                        app.adjType = "cch-act";
17475                    }
17476                }
17477            }
17478        }
17479
17480        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17481            if (app.foregroundServices) {
17482                // The user is aware of this app, so make it visible.
17483                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17484                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17485                app.cached = false;
17486                app.adjType = "fg-service";
17487                schedGroup = Process.THREAD_GROUP_DEFAULT;
17488            } else if (app.forcingToForeground != null) {
17489                // The user is aware of this app, so make it visible.
17490                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17491                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17492                app.cached = false;
17493                app.adjType = "force-fg";
17494                app.adjSource = app.forcingToForeground;
17495                schedGroup = Process.THREAD_GROUP_DEFAULT;
17496            }
17497        }
17498
17499        if (app == mHeavyWeightProcess) {
17500            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17501                // We don't want to kill the current heavy-weight process.
17502                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17503                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17504                app.cached = false;
17505                app.adjType = "heavy";
17506            }
17507            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17508                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17509            }
17510        }
17511
17512        if (app == mHomeProcess) {
17513            if (adj > ProcessList.HOME_APP_ADJ) {
17514                // This process is hosting what we currently consider to be the
17515                // home app, so we don't want to let it go into the background.
17516                adj = ProcessList.HOME_APP_ADJ;
17517                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17518                app.cached = false;
17519                app.adjType = "home";
17520            }
17521            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17522                procState = ActivityManager.PROCESS_STATE_HOME;
17523            }
17524        }
17525
17526        if (app == mPreviousProcess && app.activities.size() > 0) {
17527            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17528                // This was the previous process that showed UI to the user.
17529                // We want to try to keep it around more aggressively, to give
17530                // a good experience around switching between two apps.
17531                adj = ProcessList.PREVIOUS_APP_ADJ;
17532                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17533                app.cached = false;
17534                app.adjType = "previous";
17535            }
17536            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17537                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17538            }
17539        }
17540
17541        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17542                + " reason=" + app.adjType);
17543
17544        // By default, we use the computed adjustment.  It may be changed if
17545        // there are applications dependent on our services or providers, but
17546        // this gives us a baseline and makes sure we don't get into an
17547        // infinite recursion.
17548        app.adjSeq = mAdjSeq;
17549        app.curRawAdj = adj;
17550        app.hasStartedServices = false;
17551
17552        if (mBackupTarget != null && app == mBackupTarget.app) {
17553            // If possible we want to avoid killing apps while they're being backed up
17554            if (adj > ProcessList.BACKUP_APP_ADJ) {
17555                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17556                adj = ProcessList.BACKUP_APP_ADJ;
17557                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17558                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17559                }
17560                app.adjType = "backup";
17561                app.cached = false;
17562            }
17563            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17564                procState = ActivityManager.PROCESS_STATE_BACKUP;
17565            }
17566        }
17567
17568        boolean mayBeTop = false;
17569
17570        for (int is = app.services.size()-1;
17571                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17572                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17573                        || procState > ActivityManager.PROCESS_STATE_TOP);
17574                is--) {
17575            ServiceRecord s = app.services.valueAt(is);
17576            if (s.startRequested) {
17577                app.hasStartedServices = true;
17578                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17579                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17580                }
17581                if (app.hasShownUi && app != mHomeProcess) {
17582                    // If this process has shown some UI, let it immediately
17583                    // go to the LRU list because it may be pretty heavy with
17584                    // UI stuff.  We'll tag it with a label just to help
17585                    // debug and understand what is going on.
17586                    if (adj > ProcessList.SERVICE_ADJ) {
17587                        app.adjType = "cch-started-ui-services";
17588                    }
17589                } else {
17590                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17591                        // This service has seen some activity within
17592                        // recent memory, so we will keep its process ahead
17593                        // of the background processes.
17594                        if (adj > ProcessList.SERVICE_ADJ) {
17595                            adj = ProcessList.SERVICE_ADJ;
17596                            app.adjType = "started-services";
17597                            app.cached = false;
17598                        }
17599                    }
17600                    // If we have let the service slide into the background
17601                    // state, still have some text describing what it is doing
17602                    // even though the service no longer has an impact.
17603                    if (adj > ProcessList.SERVICE_ADJ) {
17604                        app.adjType = "cch-started-services";
17605                    }
17606                }
17607            }
17608            for (int conni = s.connections.size()-1;
17609                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17610                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17611                            || procState > ActivityManager.PROCESS_STATE_TOP);
17612                    conni--) {
17613                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17614                for (int i = 0;
17615                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17616                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17617                                || procState > ActivityManager.PROCESS_STATE_TOP);
17618                        i++) {
17619                    // XXX should compute this based on the max of
17620                    // all connected clients.
17621                    ConnectionRecord cr = clist.get(i);
17622                    if (cr.binding.client == app) {
17623                        // Binding to ourself is not interesting.
17624                        continue;
17625                    }
17626                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17627                        ProcessRecord client = cr.binding.client;
17628                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17629                                TOP_APP, doingAll, now);
17630                        int clientProcState = client.curProcState;
17631                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17632                            // If the other app is cached for any reason, for purposes here
17633                            // we are going to consider it empty.  The specific cached state
17634                            // doesn't propagate except under certain conditions.
17635                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17636                        }
17637                        String adjType = null;
17638                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17639                            // Not doing bind OOM management, so treat
17640                            // this guy more like a started service.
17641                            if (app.hasShownUi && app != mHomeProcess) {
17642                                // If this process has shown some UI, let it immediately
17643                                // go to the LRU list because it may be pretty heavy with
17644                                // UI stuff.  We'll tag it with a label just to help
17645                                // debug and understand what is going on.
17646                                if (adj > clientAdj) {
17647                                    adjType = "cch-bound-ui-services";
17648                                }
17649                                app.cached = false;
17650                                clientAdj = adj;
17651                                clientProcState = procState;
17652                            } else {
17653                                if (now >= (s.lastActivity
17654                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17655                                    // This service has not seen activity within
17656                                    // recent memory, so allow it to drop to the
17657                                    // LRU list if there is no other reason to keep
17658                                    // it around.  We'll also tag it with a label just
17659                                    // to help debug and undertand what is going on.
17660                                    if (adj > clientAdj) {
17661                                        adjType = "cch-bound-services";
17662                                    }
17663                                    clientAdj = adj;
17664                                }
17665                            }
17666                        }
17667                        if (adj > clientAdj) {
17668                            // If this process has recently shown UI, and
17669                            // the process that is binding to it is less
17670                            // important than being visible, then we don't
17671                            // care about the binding as much as we care
17672                            // about letting this process get into the LRU
17673                            // list to be killed and restarted if needed for
17674                            // memory.
17675                            if (app.hasShownUi && app != mHomeProcess
17676                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17677                                adjType = "cch-bound-ui-services";
17678                            } else {
17679                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17680                                        |Context.BIND_IMPORTANT)) != 0) {
17681                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17682                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17683                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17684                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17685                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17686                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17687                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17688                                    adj = clientAdj;
17689                                } else {
17690                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17691                                        adj = ProcessList.VISIBLE_APP_ADJ;
17692                                    }
17693                                }
17694                                if (!client.cached) {
17695                                    app.cached = false;
17696                                }
17697                                adjType = "service";
17698                            }
17699                        }
17700                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17701                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17702                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17703                            }
17704                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17705                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17706                                    // Special handling of clients who are in the top state.
17707                                    // We *may* want to consider this process to be in the
17708                                    // top state as well, but only if there is not another
17709                                    // reason for it to be running.  Being on the top is a
17710                                    // special state, meaning you are specifically running
17711                                    // for the current top app.  If the process is already
17712                                    // running in the background for some other reason, it
17713                                    // is more important to continue considering it to be
17714                                    // in the background state.
17715                                    mayBeTop = true;
17716                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17717                                } else {
17718                                    // Special handling for above-top states (persistent
17719                                    // processes).  These should not bring the current process
17720                                    // into the top state, since they are not on top.  Instead
17721                                    // give them the best state after that.
17722                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17723                                        clientProcState =
17724                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17725                                    } else if (mWakefulness
17726                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17727                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17728                                                    != 0) {
17729                                        clientProcState =
17730                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17731                                    } else {
17732                                        clientProcState =
17733                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17734                                    }
17735                                }
17736                            }
17737                        } else {
17738                            if (clientProcState <
17739                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17740                                clientProcState =
17741                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17742                            }
17743                        }
17744                        if (procState > clientProcState) {
17745                            procState = clientProcState;
17746                        }
17747                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17748                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17749                            app.pendingUiClean = true;
17750                        }
17751                        if (adjType != null) {
17752                            app.adjType = adjType;
17753                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17754                                    .REASON_SERVICE_IN_USE;
17755                            app.adjSource = cr.binding.client;
17756                            app.adjSourceProcState = clientProcState;
17757                            app.adjTarget = s.name;
17758                        }
17759                    }
17760                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17761                        app.treatLikeActivity = true;
17762                    }
17763                    final ActivityRecord a = cr.activity;
17764                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17765                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17766                                (a.visible || a.state == ActivityState.RESUMED
17767                                 || a.state == ActivityState.PAUSING)) {
17768                            adj = ProcessList.FOREGROUND_APP_ADJ;
17769                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17770                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17771                            }
17772                            app.cached = false;
17773                            app.adjType = "service";
17774                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17775                                    .REASON_SERVICE_IN_USE;
17776                            app.adjSource = a;
17777                            app.adjSourceProcState = procState;
17778                            app.adjTarget = s.name;
17779                        }
17780                    }
17781                }
17782            }
17783        }
17784
17785        for (int provi = app.pubProviders.size()-1;
17786                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17787                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17788                        || procState > ActivityManager.PROCESS_STATE_TOP);
17789                provi--) {
17790            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17791            for (int i = cpr.connections.size()-1;
17792                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17793                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17794                            || procState > ActivityManager.PROCESS_STATE_TOP);
17795                    i--) {
17796                ContentProviderConnection conn = cpr.connections.get(i);
17797                ProcessRecord client = conn.client;
17798                if (client == app) {
17799                    // Being our own client is not interesting.
17800                    continue;
17801                }
17802                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17803                int clientProcState = client.curProcState;
17804                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17805                    // If the other app is cached for any reason, for purposes here
17806                    // we are going to consider it empty.
17807                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17808                }
17809                if (adj > clientAdj) {
17810                    if (app.hasShownUi && app != mHomeProcess
17811                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17812                        app.adjType = "cch-ui-provider";
17813                    } else {
17814                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17815                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17816                        app.adjType = "provider";
17817                    }
17818                    app.cached &= client.cached;
17819                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17820                            .REASON_PROVIDER_IN_USE;
17821                    app.adjSource = client;
17822                    app.adjSourceProcState = clientProcState;
17823                    app.adjTarget = cpr.name;
17824                }
17825                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17826                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17827                        // Special handling of clients who are in the top state.
17828                        // We *may* want to consider this process to be in the
17829                        // top state as well, but only if there is not another
17830                        // reason for it to be running.  Being on the top is a
17831                        // special state, meaning you are specifically running
17832                        // for the current top app.  If the process is already
17833                        // running in the background for some other reason, it
17834                        // is more important to continue considering it to be
17835                        // in the background state.
17836                        mayBeTop = true;
17837                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17838                    } else {
17839                        // Special handling for above-top states (persistent
17840                        // processes).  These should not bring the current process
17841                        // into the top state, since they are not on top.  Instead
17842                        // give them the best state after that.
17843                        clientProcState =
17844                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17845                    }
17846                }
17847                if (procState > clientProcState) {
17848                    procState = clientProcState;
17849                }
17850                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17851                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17852                }
17853            }
17854            // If the provider has external (non-framework) process
17855            // dependencies, ensure that its adjustment is at least
17856            // FOREGROUND_APP_ADJ.
17857            if (cpr.hasExternalProcessHandles()) {
17858                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17859                    adj = ProcessList.FOREGROUND_APP_ADJ;
17860                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17861                    app.cached = false;
17862                    app.adjType = "provider";
17863                    app.adjTarget = cpr.name;
17864                }
17865                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17866                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17867                }
17868            }
17869        }
17870
17871        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17872            // A client of one of our services or providers is in the top state.  We
17873            // *may* want to be in the top state, but not if we are already running in
17874            // the background for some other reason.  For the decision here, we are going
17875            // to pick out a few specific states that we want to remain in when a client
17876            // is top (states that tend to be longer-term) and otherwise allow it to go
17877            // to the top state.
17878            switch (procState) {
17879                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17880                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17881                case ActivityManager.PROCESS_STATE_SERVICE:
17882                    // These all are longer-term states, so pull them up to the top
17883                    // of the background states, but not all the way to the top state.
17884                    procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17885                    break;
17886                default:
17887                    // Otherwise, top is a better choice, so take it.
17888                    procState = ActivityManager.PROCESS_STATE_TOP;
17889                    break;
17890            }
17891        }
17892
17893        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17894            if (app.hasClientActivities) {
17895                // This is a cached process, but with client activities.  Mark it so.
17896                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17897                app.adjType = "cch-client-act";
17898            } else if (app.treatLikeActivity) {
17899                // This is a cached process, but somebody wants us to treat it like it has
17900                // an activity, okay!
17901                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17902                app.adjType = "cch-as-act";
17903            }
17904        }
17905
17906        if (adj == ProcessList.SERVICE_ADJ) {
17907            if (doingAll) {
17908                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17909                mNewNumServiceProcs++;
17910                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17911                if (!app.serviceb) {
17912                    // This service isn't far enough down on the LRU list to
17913                    // normally be a B service, but if we are low on RAM and it
17914                    // is large we want to force it down since we would prefer to
17915                    // keep launcher over it.
17916                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17917                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17918                        app.serviceHighRam = true;
17919                        app.serviceb = true;
17920                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17921                    } else {
17922                        mNewNumAServiceProcs++;
17923                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17924                    }
17925                } else {
17926                    app.serviceHighRam = false;
17927                }
17928            }
17929            if (app.serviceb) {
17930                adj = ProcessList.SERVICE_B_ADJ;
17931            }
17932        }
17933
17934        app.curRawAdj = adj;
17935
17936        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17937        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17938        if (adj > app.maxAdj) {
17939            adj = app.maxAdj;
17940            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17941                schedGroup = Process.THREAD_GROUP_DEFAULT;
17942            }
17943        }
17944
17945        // Do final modification to adj.  Everything we do between here and applying
17946        // the final setAdj must be done in this function, because we will also use
17947        // it when computing the final cached adj later.  Note that we don't need to
17948        // worry about this for max adj above, since max adj will always be used to
17949        // keep it out of the cached vaues.
17950        app.curAdj = app.modifyRawOomAdj(adj);
17951        app.curSchedGroup = schedGroup;
17952        app.curProcState = procState;
17953        app.foregroundActivities = foregroundActivities;
17954
17955        return app.curRawAdj;
17956    }
17957
17958    /**
17959     * Record new PSS sample for a process.
17960     */
17961    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17962        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
17963        proc.lastPssTime = now;
17964        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17965        if (DEBUG_PSS) Slog.d(TAG_PSS,
17966                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
17967                + " state=" + ProcessList.makeProcStateString(procState));
17968        if (proc.initialIdlePss == 0) {
17969            proc.initialIdlePss = pss;
17970        }
17971        proc.lastPss = pss;
17972        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17973            proc.lastCachedPss = pss;
17974        }
17975
17976        final SparseArray<Pair<Long, String>> watchUids
17977                = mMemWatchProcesses.getMap().get(proc.processName);
17978        Long check = null;
17979        if (watchUids != null) {
17980            Pair<Long, String> val = watchUids.get(proc.uid);
17981            if (val == null) {
17982                val = watchUids.get(0);
17983            }
17984            if (val != null) {
17985                check = val.first;
17986            }
17987        }
17988        if (check != null) {
17989            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17990                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17991                if (!isDebuggable) {
17992                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17993                        isDebuggable = true;
17994                    }
17995                }
17996                if (isDebuggable) {
17997                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17998                    final ProcessRecord myProc = proc;
17999                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18000                    mMemWatchDumpProcName = proc.processName;
18001                    mMemWatchDumpFile = heapdumpFile.toString();
18002                    mMemWatchDumpPid = proc.pid;
18003                    mMemWatchDumpUid = proc.uid;
18004                    BackgroundThread.getHandler().post(new Runnable() {
18005                        @Override
18006                        public void run() {
18007                            revokeUriPermission(ActivityThread.currentActivityThread()
18008                                            .getApplicationThread(),
18009                                    DumpHeapActivity.JAVA_URI,
18010                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18011                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18012                                    UserHandle.myUserId());
18013                            ParcelFileDescriptor fd = null;
18014                            try {
18015                                heapdumpFile.delete();
18016                                fd = ParcelFileDescriptor.open(heapdumpFile,
18017                                        ParcelFileDescriptor.MODE_CREATE |
18018                                                ParcelFileDescriptor.MODE_TRUNCATE |
18019                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18020                                                ParcelFileDescriptor.MODE_APPEND);
18021                                IApplicationThread thread = myProc.thread;
18022                                if (thread != null) {
18023                                    try {
18024                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18025                                                "Requesting dump heap from "
18026                                                + myProc + " to " + heapdumpFile);
18027                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18028                                    } catch (RemoteException e) {
18029                                    }
18030                                }
18031                            } catch (FileNotFoundException e) {
18032                                e.printStackTrace();
18033                            } finally {
18034                                if (fd != null) {
18035                                    try {
18036                                        fd.close();
18037                                    } catch (IOException e) {
18038                                    }
18039                                }
18040                            }
18041                        }
18042                    });
18043                } else {
18044                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18045                            + ", but debugging not enabled");
18046                }
18047            }
18048        }
18049    }
18050
18051    /**
18052     * Schedule PSS collection of a process.
18053     */
18054    void requestPssLocked(ProcessRecord proc, int procState) {
18055        if (mPendingPssProcesses.contains(proc)) {
18056            return;
18057        }
18058        if (mPendingPssProcesses.size() == 0) {
18059            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18060        }
18061        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18062        proc.pssProcState = procState;
18063        mPendingPssProcesses.add(proc);
18064    }
18065
18066    /**
18067     * Schedule PSS collection of all processes.
18068     */
18069    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18070        if (!always) {
18071            if (now < (mLastFullPssTime +
18072                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18073                return;
18074            }
18075        }
18076        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18077        mLastFullPssTime = now;
18078        mFullPssPending = true;
18079        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18080        mPendingPssProcesses.clear();
18081        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18082            ProcessRecord app = mLruProcesses.get(i);
18083            if (app.thread == null
18084                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18085                continue;
18086            }
18087            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18088                app.pssProcState = app.setProcState;
18089                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18090                        mTestPssMode, isSleeping(), now);
18091                mPendingPssProcesses.add(app);
18092            }
18093        }
18094        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18095    }
18096
18097    public void setTestPssMode(boolean enabled) {
18098        synchronized (this) {
18099            mTestPssMode = enabled;
18100            if (enabled) {
18101                // Whenever we enable the mode, we want to take a snapshot all of current
18102                // process mem use.
18103                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18104            }
18105        }
18106    }
18107
18108    /**
18109     * Ask a given process to GC right now.
18110     */
18111    final void performAppGcLocked(ProcessRecord app) {
18112        try {
18113            app.lastRequestedGc = SystemClock.uptimeMillis();
18114            if (app.thread != null) {
18115                if (app.reportLowMemory) {
18116                    app.reportLowMemory = false;
18117                    app.thread.scheduleLowMemory();
18118                } else {
18119                    app.thread.processInBackground();
18120                }
18121            }
18122        } catch (Exception e) {
18123            // whatever.
18124        }
18125    }
18126
18127    /**
18128     * Returns true if things are idle enough to perform GCs.
18129     */
18130    private final boolean canGcNowLocked() {
18131        boolean processingBroadcasts = false;
18132        for (BroadcastQueue q : mBroadcastQueues) {
18133            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18134                processingBroadcasts = true;
18135            }
18136        }
18137        return !processingBroadcasts
18138                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18139    }
18140
18141    /**
18142     * Perform GCs on all processes that are waiting for it, but only
18143     * if things are idle.
18144     */
18145    final void performAppGcsLocked() {
18146        final int N = mProcessesToGc.size();
18147        if (N <= 0) {
18148            return;
18149        }
18150        if (canGcNowLocked()) {
18151            while (mProcessesToGc.size() > 0) {
18152                ProcessRecord proc = mProcessesToGc.remove(0);
18153                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18154                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18155                            <= SystemClock.uptimeMillis()) {
18156                        // To avoid spamming the system, we will GC processes one
18157                        // at a time, waiting a few seconds between each.
18158                        performAppGcLocked(proc);
18159                        scheduleAppGcsLocked();
18160                        return;
18161                    } else {
18162                        // It hasn't been long enough since we last GCed this
18163                        // process...  put it in the list to wait for its time.
18164                        addProcessToGcListLocked(proc);
18165                        break;
18166                    }
18167                }
18168            }
18169
18170            scheduleAppGcsLocked();
18171        }
18172    }
18173
18174    /**
18175     * If all looks good, perform GCs on all processes waiting for them.
18176     */
18177    final void performAppGcsIfAppropriateLocked() {
18178        if (canGcNowLocked()) {
18179            performAppGcsLocked();
18180            return;
18181        }
18182        // Still not idle, wait some more.
18183        scheduleAppGcsLocked();
18184    }
18185
18186    /**
18187     * Schedule the execution of all pending app GCs.
18188     */
18189    final void scheduleAppGcsLocked() {
18190        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18191
18192        if (mProcessesToGc.size() > 0) {
18193            // Schedule a GC for the time to the next process.
18194            ProcessRecord proc = mProcessesToGc.get(0);
18195            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18196
18197            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18198            long now = SystemClock.uptimeMillis();
18199            if (when < (now+GC_TIMEOUT)) {
18200                when = now + GC_TIMEOUT;
18201            }
18202            mHandler.sendMessageAtTime(msg, when);
18203        }
18204    }
18205
18206    /**
18207     * Add a process to the array of processes waiting to be GCed.  Keeps the
18208     * list in sorted order by the last GC time.  The process can't already be
18209     * on the list.
18210     */
18211    final void addProcessToGcListLocked(ProcessRecord proc) {
18212        boolean added = false;
18213        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18214            if (mProcessesToGc.get(i).lastRequestedGc <
18215                    proc.lastRequestedGc) {
18216                added = true;
18217                mProcessesToGc.add(i+1, proc);
18218                break;
18219            }
18220        }
18221        if (!added) {
18222            mProcessesToGc.add(0, proc);
18223        }
18224    }
18225
18226    /**
18227     * Set up to ask a process to GC itself.  This will either do it
18228     * immediately, or put it on the list of processes to gc the next
18229     * time things are idle.
18230     */
18231    final void scheduleAppGcLocked(ProcessRecord app) {
18232        long now = SystemClock.uptimeMillis();
18233        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18234            return;
18235        }
18236        if (!mProcessesToGc.contains(app)) {
18237            addProcessToGcListLocked(app);
18238            scheduleAppGcsLocked();
18239        }
18240    }
18241
18242    final void checkExcessivePowerUsageLocked(boolean doKills) {
18243        updateCpuStatsNow();
18244
18245        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18246        boolean doWakeKills = doKills;
18247        boolean doCpuKills = doKills;
18248        if (mLastPowerCheckRealtime == 0) {
18249            doWakeKills = false;
18250        }
18251        if (mLastPowerCheckUptime == 0) {
18252            doCpuKills = false;
18253        }
18254        if (stats.isScreenOn()) {
18255            doWakeKills = false;
18256        }
18257        final long curRealtime = SystemClock.elapsedRealtime();
18258        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18259        final long curUptime = SystemClock.uptimeMillis();
18260        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18261        mLastPowerCheckRealtime = curRealtime;
18262        mLastPowerCheckUptime = curUptime;
18263        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18264            doWakeKills = false;
18265        }
18266        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18267            doCpuKills = false;
18268        }
18269        int i = mLruProcesses.size();
18270        while (i > 0) {
18271            i--;
18272            ProcessRecord app = mLruProcesses.get(i);
18273            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18274                long wtime;
18275                synchronized (stats) {
18276                    wtime = stats.getProcessWakeTime(app.info.uid,
18277                            app.pid, curRealtime);
18278                }
18279                long wtimeUsed = wtime - app.lastWakeTime;
18280                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18281                if (DEBUG_POWER) {
18282                    StringBuilder sb = new StringBuilder(128);
18283                    sb.append("Wake for ");
18284                    app.toShortString(sb);
18285                    sb.append(": over ");
18286                    TimeUtils.formatDuration(realtimeSince, sb);
18287                    sb.append(" used ");
18288                    TimeUtils.formatDuration(wtimeUsed, sb);
18289                    sb.append(" (");
18290                    sb.append((wtimeUsed*100)/realtimeSince);
18291                    sb.append("%)");
18292                    Slog.i(TAG_POWER, sb.toString());
18293                    sb.setLength(0);
18294                    sb.append("CPU for ");
18295                    app.toShortString(sb);
18296                    sb.append(": over ");
18297                    TimeUtils.formatDuration(uptimeSince, sb);
18298                    sb.append(" used ");
18299                    TimeUtils.formatDuration(cputimeUsed, sb);
18300                    sb.append(" (");
18301                    sb.append((cputimeUsed*100)/uptimeSince);
18302                    sb.append("%)");
18303                    Slog.i(TAG_POWER, sb.toString());
18304                }
18305                // If a process has held a wake lock for more
18306                // than 50% of the time during this period,
18307                // that sounds bad.  Kill!
18308                if (doWakeKills && realtimeSince > 0
18309                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18310                    synchronized (stats) {
18311                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18312                                realtimeSince, wtimeUsed);
18313                    }
18314                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18315                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18316                } else if (doCpuKills && uptimeSince > 0
18317                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18318                    synchronized (stats) {
18319                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18320                                uptimeSince, cputimeUsed);
18321                    }
18322                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18323                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18324                } else {
18325                    app.lastWakeTime = wtime;
18326                    app.lastCpuTime = app.curCpuTime;
18327                }
18328            }
18329        }
18330    }
18331
18332    private final boolean applyOomAdjLocked(ProcessRecord app,
18333            ProcessRecord TOP_APP, boolean doingAll, long now) {
18334        boolean success = true;
18335
18336        if (app.curRawAdj != app.setRawAdj) {
18337            app.setRawAdj = app.curRawAdj;
18338        }
18339
18340        int changes = 0;
18341
18342        if (app.curAdj != app.setAdj) {
18343            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18344            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18345                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18346                    + app.adjType);
18347            app.setAdj = app.curAdj;
18348        }
18349
18350        if (app.setSchedGroup != app.curSchedGroup) {
18351            app.setSchedGroup = app.curSchedGroup;
18352            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18353                    "Setting process group of " + app.processName
18354                    + " to " + app.curSchedGroup);
18355            if (app.waitingToKill != null &&
18356                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18357                app.kill(app.waitingToKill, true);
18358                success = false;
18359            } else {
18360                if (true) {
18361                    long oldId = Binder.clearCallingIdentity();
18362                    try {
18363                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18364                    } catch (Exception e) {
18365                        Slog.w(TAG, "Failed setting process group of " + app.pid
18366                                + " to " + app.curSchedGroup);
18367                        e.printStackTrace();
18368                    } finally {
18369                        Binder.restoreCallingIdentity(oldId);
18370                    }
18371                } else {
18372                    if (app.thread != null) {
18373                        try {
18374                            app.thread.setSchedulingGroup(app.curSchedGroup);
18375                        } catch (RemoteException e) {
18376                        }
18377                    }
18378                }
18379                Process.setSwappiness(app.pid,
18380                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18381            }
18382        }
18383        if (app.repForegroundActivities != app.foregroundActivities) {
18384            app.repForegroundActivities = app.foregroundActivities;
18385            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18386        }
18387        if (app.repProcState != app.curProcState) {
18388            app.repProcState = app.curProcState;
18389            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18390            if (app.thread != null) {
18391                try {
18392                    if (false) {
18393                        //RuntimeException h = new RuntimeException("here");
18394                        Slog.i(TAG, "Sending new process state " + app.repProcState
18395                                + " to " + app /*, h*/);
18396                    }
18397                    app.thread.setProcessState(app.repProcState);
18398                } catch (RemoteException e) {
18399                }
18400            }
18401        }
18402        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18403                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18404            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18405                // Experimental code to more aggressively collect pss while
18406                // running test...  the problem is that this tends to collect
18407                // the data right when a process is transitioning between process
18408                // states, which well tend to give noisy data.
18409                long start = SystemClock.uptimeMillis();
18410                long pss = Debug.getPss(app.pid, mTmpLong, null);
18411                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18412                mPendingPssProcesses.remove(app);
18413                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18414                        + " to " + app.curProcState + ": "
18415                        + (SystemClock.uptimeMillis()-start) + "ms");
18416            }
18417            app.lastStateTime = now;
18418            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18419                    mTestPssMode, isSleeping(), now);
18420            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18421                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18422                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18423                    + (app.nextPssTime-now) + ": " + app);
18424        } else {
18425            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18426                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18427                    mTestPssMode)))) {
18428                requestPssLocked(app, app.setProcState);
18429                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18430                        mTestPssMode, isSleeping(), now);
18431            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18432                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18433        }
18434        if (app.setProcState != app.curProcState) {
18435            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18436                    "Proc state change of " + app.processName
18437                    + " to " + app.curProcState);
18438            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18439            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18440            if (setImportant && !curImportant) {
18441                // This app is no longer something we consider important enough to allow to
18442                // use arbitrary amounts of battery power.  Note
18443                // its current wake lock time to later know to kill it if
18444                // it is not behaving well.
18445                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18446                synchronized (stats) {
18447                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18448                            app.pid, SystemClock.elapsedRealtime());
18449                }
18450                app.lastCpuTime = app.curCpuTime;
18451
18452            }
18453            // Inform UsageStats of important process state change
18454            // Must be called before updating setProcState
18455            maybeUpdateUsageStats(app);
18456
18457            app.setProcState = app.curProcState;
18458            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18459                app.notCachedSinceIdle = false;
18460            }
18461            if (!doingAll) {
18462                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18463            } else {
18464                app.procStateChanged = true;
18465            }
18466        }
18467
18468        if (changes != 0) {
18469            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18470                    "Changes in " + app + ": " + changes);
18471            int i = mPendingProcessChanges.size()-1;
18472            ProcessChangeItem item = null;
18473            while (i >= 0) {
18474                item = mPendingProcessChanges.get(i);
18475                if (item.pid == app.pid) {
18476                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18477                            "Re-using existing item: " + item);
18478                    break;
18479                }
18480                i--;
18481            }
18482            if (i < 0) {
18483                // No existing item in pending changes; need a new one.
18484                final int NA = mAvailProcessChanges.size();
18485                if (NA > 0) {
18486                    item = mAvailProcessChanges.remove(NA-1);
18487                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18488                            "Retrieving available item: " + item);
18489                } else {
18490                    item = new ProcessChangeItem();
18491                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18492                            "Allocating new item: " + item);
18493                }
18494                item.changes = 0;
18495                item.pid = app.pid;
18496                item.uid = app.info.uid;
18497                if (mPendingProcessChanges.size() == 0) {
18498                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18499                            "*** Enqueueing dispatch processes changed!");
18500                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18501                }
18502                mPendingProcessChanges.add(item);
18503            }
18504            item.changes |= changes;
18505            item.processState = app.repProcState;
18506            item.foregroundActivities = app.repForegroundActivities;
18507            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18508                    "Item " + Integer.toHexString(System.identityHashCode(item))
18509                    + " " + app.toShortString() + ": changes=" + item.changes
18510                    + " procState=" + item.processState
18511                    + " foreground=" + item.foregroundActivities
18512                    + " type=" + app.adjType + " source=" + app.adjSource
18513                    + " target=" + app.adjTarget);
18514        }
18515
18516        return success;
18517    }
18518
18519    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18520        if (uidRec.pendingChange == null) {
18521            if (mPendingUidChanges.size() == 0) {
18522                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18523                        "*** Enqueueing dispatch uid changed!");
18524                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18525            }
18526            final int NA = mAvailUidChanges.size();
18527            if (NA > 0) {
18528                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18529                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18530                        "Retrieving available item: " + uidRec.pendingChange);
18531            } else {
18532                uidRec.pendingChange = new UidRecord.ChangeItem();
18533                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18534                        "Allocating new item: " + uidRec.pendingChange);
18535            }
18536            uidRec.pendingChange.uidRecord = uidRec;
18537            uidRec.pendingChange.uid = uidRec.uid;
18538            mPendingUidChanges.add(uidRec.pendingChange);
18539        }
18540        uidRec.pendingChange.gone = gone;
18541        uidRec.pendingChange.processState = uidRec.setProcState;
18542    }
18543
18544    private void maybeUpdateUsageStats(ProcessRecord app) {
18545        if (DEBUG_USAGE_STATS) {
18546            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18547                    + "] state changes: old = " + app.setProcState + ", new = "
18548                    + app.curProcState);
18549        }
18550        if (mUsageStatsService == null) {
18551            return;
18552        }
18553        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18554                && (app.setProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18555                        || app.setProcState < 0)) {
18556            String[] packages = app.getPackageList();
18557            if (packages != null) {
18558                for (int i = 0; i < packages.length; i++) {
18559                    mUsageStatsService.reportEvent(packages[i], app.userId,
18560                            UsageEvents.Event.INTERACTION);
18561                }
18562            }
18563        }
18564    }
18565
18566    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18567        if (proc.thread != null) {
18568            if (proc.baseProcessTracker != null) {
18569                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18570            }
18571            if (proc.repProcState >= 0) {
18572                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18573                        proc.repProcState);
18574            }
18575        }
18576    }
18577
18578    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18579            ProcessRecord TOP_APP, boolean doingAll, long now) {
18580        if (app.thread == null) {
18581            return false;
18582        }
18583
18584        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18585
18586        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18587    }
18588
18589    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18590            boolean oomAdj) {
18591        if (isForeground != proc.foregroundServices) {
18592            proc.foregroundServices = isForeground;
18593            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18594                    proc.info.uid);
18595            if (isForeground) {
18596                if (curProcs == null) {
18597                    curProcs = new ArrayList<ProcessRecord>();
18598                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18599                }
18600                if (!curProcs.contains(proc)) {
18601                    curProcs.add(proc);
18602                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18603                            proc.info.packageName, proc.info.uid);
18604                }
18605            } else {
18606                if (curProcs != null) {
18607                    if (curProcs.remove(proc)) {
18608                        mBatteryStatsService.noteEvent(
18609                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18610                                proc.info.packageName, proc.info.uid);
18611                        if (curProcs.size() <= 0) {
18612                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18613                        }
18614                    }
18615                }
18616            }
18617            if (oomAdj) {
18618                updateOomAdjLocked();
18619            }
18620        }
18621    }
18622
18623    private final ActivityRecord resumedAppLocked() {
18624        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18625        String pkg;
18626        int uid;
18627        if (act != null) {
18628            pkg = act.packageName;
18629            uid = act.info.applicationInfo.uid;
18630        } else {
18631            pkg = null;
18632            uid = -1;
18633        }
18634        // Has the UID or resumed package name changed?
18635        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18636                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18637            if (mCurResumedPackage != null) {
18638                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18639                        mCurResumedPackage, mCurResumedUid);
18640            }
18641            mCurResumedPackage = pkg;
18642            mCurResumedUid = uid;
18643            if (mCurResumedPackage != null) {
18644                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18645                        mCurResumedPackage, mCurResumedUid);
18646            }
18647        }
18648        return act;
18649    }
18650
18651    final boolean updateOomAdjLocked(ProcessRecord app) {
18652        final ActivityRecord TOP_ACT = resumedAppLocked();
18653        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18654        final boolean wasCached = app.cached;
18655
18656        mAdjSeq++;
18657
18658        // This is the desired cached adjusment we want to tell it to use.
18659        // If our app is currently cached, we know it, and that is it.  Otherwise,
18660        // we don't know it yet, and it needs to now be cached we will then
18661        // need to do a complete oom adj.
18662        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18663                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18664        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18665                SystemClock.uptimeMillis());
18666        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18667            // Changed to/from cached state, so apps after it in the LRU
18668            // list may also be changed.
18669            updateOomAdjLocked();
18670        }
18671        return success;
18672    }
18673
18674    final void updateOomAdjLocked() {
18675        final ActivityRecord TOP_ACT = resumedAppLocked();
18676        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18677        final long now = SystemClock.uptimeMillis();
18678        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18679        final int N = mLruProcesses.size();
18680
18681        if (false) {
18682            RuntimeException e = new RuntimeException();
18683            e.fillInStackTrace();
18684            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18685        }
18686
18687        // Reset state in all uid records.
18688        for (int i=mActiveUids.size()-1; i>=0; i--) {
18689            final UidRecord uidRec = mActiveUids.valueAt(i);
18690            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18691                    "Starting update of " + uidRec);
18692            uidRec.reset();
18693        }
18694
18695        mAdjSeq++;
18696        mNewNumServiceProcs = 0;
18697        mNewNumAServiceProcs = 0;
18698
18699        final int emptyProcessLimit;
18700        final int cachedProcessLimit;
18701        if (mProcessLimit <= 0) {
18702            emptyProcessLimit = cachedProcessLimit = 0;
18703        } else if (mProcessLimit == 1) {
18704            emptyProcessLimit = 1;
18705            cachedProcessLimit = 0;
18706        } else {
18707            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18708            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18709        }
18710
18711        // Let's determine how many processes we have running vs.
18712        // how many slots we have for background processes; we may want
18713        // to put multiple processes in a slot of there are enough of
18714        // them.
18715        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18716                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18717        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18718        if (numEmptyProcs > cachedProcessLimit) {
18719            // If there are more empty processes than our limit on cached
18720            // processes, then use the cached process limit for the factor.
18721            // This ensures that the really old empty processes get pushed
18722            // down to the bottom, so if we are running low on memory we will
18723            // have a better chance at keeping around more cached processes
18724            // instead of a gazillion empty processes.
18725            numEmptyProcs = cachedProcessLimit;
18726        }
18727        int emptyFactor = numEmptyProcs/numSlots;
18728        if (emptyFactor < 1) emptyFactor = 1;
18729        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18730        if (cachedFactor < 1) cachedFactor = 1;
18731        int stepCached = 0;
18732        int stepEmpty = 0;
18733        int numCached = 0;
18734        int numEmpty = 0;
18735        int numTrimming = 0;
18736
18737        mNumNonCachedProcs = 0;
18738        mNumCachedHiddenProcs = 0;
18739
18740        // First update the OOM adjustment for each of the
18741        // application processes based on their current state.
18742        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18743        int nextCachedAdj = curCachedAdj+1;
18744        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18745        int nextEmptyAdj = curEmptyAdj+2;
18746        for (int i=N-1; i>=0; i--) {
18747            ProcessRecord app = mLruProcesses.get(i);
18748            if (!app.killedByAm && app.thread != null) {
18749                app.procStateChanged = false;
18750                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18751
18752                // If we haven't yet assigned the final cached adj
18753                // to the process, do that now.
18754                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18755                    switch (app.curProcState) {
18756                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18757                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18758                            // This process is a cached process holding activities...
18759                            // assign it the next cached value for that type, and then
18760                            // step that cached level.
18761                            app.curRawAdj = curCachedAdj;
18762                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18763                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18764                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18765                                    + ")");
18766                            if (curCachedAdj != nextCachedAdj) {
18767                                stepCached++;
18768                                if (stepCached >= cachedFactor) {
18769                                    stepCached = 0;
18770                                    curCachedAdj = nextCachedAdj;
18771                                    nextCachedAdj += 2;
18772                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18773                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18774                                    }
18775                                }
18776                            }
18777                            break;
18778                        default:
18779                            // For everything else, assign next empty cached process
18780                            // level and bump that up.  Note that this means that
18781                            // long-running services that have dropped down to the
18782                            // cached level will be treated as empty (since their process
18783                            // state is still as a service), which is what we want.
18784                            app.curRawAdj = curEmptyAdj;
18785                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18786                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18787                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18788                                    + ")");
18789                            if (curEmptyAdj != nextEmptyAdj) {
18790                                stepEmpty++;
18791                                if (stepEmpty >= emptyFactor) {
18792                                    stepEmpty = 0;
18793                                    curEmptyAdj = nextEmptyAdj;
18794                                    nextEmptyAdj += 2;
18795                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18796                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18797                                    }
18798                                }
18799                            }
18800                            break;
18801                    }
18802                }
18803
18804                applyOomAdjLocked(app, TOP_APP, true, now);
18805
18806                // Count the number of process types.
18807                switch (app.curProcState) {
18808                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18809                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18810                        mNumCachedHiddenProcs++;
18811                        numCached++;
18812                        if (numCached > cachedProcessLimit) {
18813                            app.kill("cached #" + numCached, true);
18814                        }
18815                        break;
18816                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18817                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18818                                && app.lastActivityTime < oldTime) {
18819                            app.kill("empty for "
18820                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18821                                    / 1000) + "s", true);
18822                        } else {
18823                            numEmpty++;
18824                            if (numEmpty > emptyProcessLimit) {
18825                                app.kill("empty #" + numEmpty, true);
18826                            }
18827                        }
18828                        break;
18829                    default:
18830                        mNumNonCachedProcs++;
18831                        break;
18832                }
18833
18834                if (app.isolated && app.services.size() <= 0) {
18835                    // If this is an isolated process, and there are no
18836                    // services running in it, then the process is no longer
18837                    // needed.  We agressively kill these because we can by
18838                    // definition not re-use the same process again, and it is
18839                    // good to avoid having whatever code was running in them
18840                    // left sitting around after no longer needed.
18841                    app.kill("isolated not needed", true);
18842                } else {
18843                    // Keeping this process, update its uid.
18844                    final UidRecord uidRec = app.uidRecord;
18845                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
18846                        uidRec.curProcState = app.curProcState;
18847                    }
18848                }
18849
18850                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18851                        && !app.killedByAm) {
18852                    numTrimming++;
18853                }
18854            }
18855        }
18856
18857        mNumServiceProcs = mNewNumServiceProcs;
18858
18859        // Now determine the memory trimming level of background processes.
18860        // Unfortunately we need to start at the back of the list to do this
18861        // properly.  We only do this if the number of background apps we
18862        // are managing to keep around is less than half the maximum we desire;
18863        // if we are keeping a good number around, we'll let them use whatever
18864        // memory they want.
18865        final int numCachedAndEmpty = numCached + numEmpty;
18866        int memFactor;
18867        if (numCached <= ProcessList.TRIM_CACHED_APPS
18868                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18869            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18870                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18871            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18872                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18873            } else {
18874                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18875            }
18876        } else {
18877            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18878        }
18879        // We always allow the memory level to go up (better).  We only allow it to go
18880        // down if we are in a state where that is allowed, *and* the total number of processes
18881        // has gone down since last time.
18882        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18883                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18884                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18885        if (memFactor > mLastMemoryLevel) {
18886            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18887                memFactor = mLastMemoryLevel;
18888                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18889            }
18890        }
18891        mLastMemoryLevel = memFactor;
18892        mLastNumProcesses = mLruProcesses.size();
18893        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18894        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18895        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18896            if (mLowRamStartTime == 0) {
18897                mLowRamStartTime = now;
18898            }
18899            int step = 0;
18900            int fgTrimLevel;
18901            switch (memFactor) {
18902                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18903                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18904                    break;
18905                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18906                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18907                    break;
18908                default:
18909                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18910                    break;
18911            }
18912            int factor = numTrimming/3;
18913            int minFactor = 2;
18914            if (mHomeProcess != null) minFactor++;
18915            if (mPreviousProcess != null) minFactor++;
18916            if (factor < minFactor) factor = minFactor;
18917            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18918            for (int i=N-1; i>=0; i--) {
18919                ProcessRecord app = mLruProcesses.get(i);
18920                if (allChanged || app.procStateChanged) {
18921                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18922                    app.procStateChanged = false;
18923                }
18924                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18925                        && !app.killedByAm) {
18926                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18927                        try {
18928                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18929                                    "Trimming memory of " + app.processName + " to " + curLevel);
18930                            app.thread.scheduleTrimMemory(curLevel);
18931                        } catch (RemoteException e) {
18932                        }
18933                        if (false) {
18934                            // For now we won't do this; our memory trimming seems
18935                            // to be good enough at this point that destroying
18936                            // activities causes more harm than good.
18937                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18938                                    && app != mHomeProcess && app != mPreviousProcess) {
18939                                // Need to do this on its own message because the stack may not
18940                                // be in a consistent state at this point.
18941                                // For these apps we will also finish their activities
18942                                // to help them free memory.
18943                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18944                            }
18945                        }
18946                    }
18947                    app.trimMemoryLevel = curLevel;
18948                    step++;
18949                    if (step >= factor) {
18950                        step = 0;
18951                        switch (curLevel) {
18952                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18953                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18954                                break;
18955                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18956                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18957                                break;
18958                        }
18959                    }
18960                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18961                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18962                            && app.thread != null) {
18963                        try {
18964                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18965                                    "Trimming memory of heavy-weight " + app.processName
18966                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18967                            app.thread.scheduleTrimMemory(
18968                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18969                        } catch (RemoteException e) {
18970                        }
18971                    }
18972                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18973                } else {
18974                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18975                            || app.systemNoUi) && app.pendingUiClean) {
18976                        // If this application is now in the background and it
18977                        // had done UI, then give it the special trim level to
18978                        // have it free UI resources.
18979                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18980                        if (app.trimMemoryLevel < level && app.thread != null) {
18981                            try {
18982                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18983                                        "Trimming memory of bg-ui " + app.processName
18984                                        + " to " + level);
18985                                app.thread.scheduleTrimMemory(level);
18986                            } catch (RemoteException e) {
18987                            }
18988                        }
18989                        app.pendingUiClean = false;
18990                    }
18991                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18992                        try {
18993                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18994                                    "Trimming memory of fg " + app.processName
18995                                    + " to " + fgTrimLevel);
18996                            app.thread.scheduleTrimMemory(fgTrimLevel);
18997                        } catch (RemoteException e) {
18998                        }
18999                    }
19000                    app.trimMemoryLevel = fgTrimLevel;
19001                }
19002            }
19003        } else {
19004            if (mLowRamStartTime != 0) {
19005                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19006                mLowRamStartTime = 0;
19007            }
19008            for (int i=N-1; i>=0; i--) {
19009                ProcessRecord app = mLruProcesses.get(i);
19010                if (allChanged || app.procStateChanged) {
19011                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19012                    app.procStateChanged = false;
19013                }
19014                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19015                        || app.systemNoUi) && app.pendingUiClean) {
19016                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19017                            && app.thread != null) {
19018                        try {
19019                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19020                                    "Trimming memory of ui hidden " + app.processName
19021                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19022                            app.thread.scheduleTrimMemory(
19023                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19024                        } catch (RemoteException e) {
19025                        }
19026                    }
19027                    app.pendingUiClean = false;
19028                }
19029                app.trimMemoryLevel = 0;
19030            }
19031        }
19032
19033        if (mAlwaysFinishActivities) {
19034            // Need to do this on its own message because the stack may not
19035            // be in a consistent state at this point.
19036            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19037        }
19038
19039        if (allChanged) {
19040            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19041        }
19042
19043        // Update from any uid changes.
19044        for (int i=mActiveUids.size()-1; i>=0; i--) {
19045            final UidRecord uidRec = mActiveUids.valueAt(i);
19046            if (uidRec.setProcState != uidRec.curProcState) {
19047                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19048                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19049                        + " to " + uidRec.curProcState);
19050                uidRec.setProcState = uidRec.curProcState;
19051                enqueueUidChangeLocked(uidRec, false);
19052            }
19053        }
19054
19055        if (mProcessStats.shouldWriteNowLocked(now)) {
19056            mHandler.post(new Runnable() {
19057                @Override public void run() {
19058                    synchronized (ActivityManagerService.this) {
19059                        mProcessStats.writeStateAsyncLocked();
19060                    }
19061                }
19062            });
19063        }
19064
19065        if (DEBUG_OOM_ADJ) {
19066            final long duration = SystemClock.uptimeMillis() - now;
19067            if (false) {
19068                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19069                        new RuntimeException("here").fillInStackTrace());
19070            } else {
19071                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19072            }
19073        }
19074    }
19075
19076    final void trimApplications() {
19077        synchronized (this) {
19078            int i;
19079
19080            // First remove any unused application processes whose package
19081            // has been removed.
19082            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19083                final ProcessRecord app = mRemovedProcesses.get(i);
19084                if (app.activities.size() == 0
19085                        && app.curReceiver == null && app.services.size() == 0) {
19086                    Slog.i(
19087                        TAG, "Exiting empty application process "
19088                        + app.processName + " ("
19089                        + (app.thread != null ? app.thread.asBinder() : null)
19090                        + ")\n");
19091                    if (app.pid > 0 && app.pid != MY_PID) {
19092                        app.kill("empty", false);
19093                    } else {
19094                        try {
19095                            app.thread.scheduleExit();
19096                        } catch (Exception e) {
19097                            // Ignore exceptions.
19098                        }
19099                    }
19100                    cleanUpApplicationRecordLocked(app, false, true, -1);
19101                    mRemovedProcesses.remove(i);
19102
19103                    if (app.persistent) {
19104                        addAppLocked(app.info, false, null /* ABI override */);
19105                    }
19106                }
19107            }
19108
19109            // Now update the oom adj for all processes.
19110            updateOomAdjLocked();
19111        }
19112    }
19113
19114    /** This method sends the specified signal to each of the persistent apps */
19115    public void signalPersistentProcesses(int sig) throws RemoteException {
19116        if (sig != Process.SIGNAL_USR1) {
19117            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19118        }
19119
19120        synchronized (this) {
19121            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19122                    != PackageManager.PERMISSION_GRANTED) {
19123                throw new SecurityException("Requires permission "
19124                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19125            }
19126
19127            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19128                ProcessRecord r = mLruProcesses.get(i);
19129                if (r.thread != null && r.persistent) {
19130                    Process.sendSignal(r.pid, sig);
19131                }
19132            }
19133        }
19134    }
19135
19136    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19137        if (proc == null || proc == mProfileProc) {
19138            proc = mProfileProc;
19139            profileType = mProfileType;
19140            clearProfilerLocked();
19141        }
19142        if (proc == null) {
19143            return;
19144        }
19145        try {
19146            proc.thread.profilerControl(false, null, profileType);
19147        } catch (RemoteException e) {
19148            throw new IllegalStateException("Process disappeared");
19149        }
19150    }
19151
19152    private void clearProfilerLocked() {
19153        if (mProfileFd != null) {
19154            try {
19155                mProfileFd.close();
19156            } catch (IOException e) {
19157            }
19158        }
19159        mProfileApp = null;
19160        mProfileProc = null;
19161        mProfileFile = null;
19162        mProfileType = 0;
19163        mAutoStopProfiler = false;
19164        mSamplingInterval = 0;
19165    }
19166
19167    public boolean profileControl(String process, int userId, boolean start,
19168            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19169
19170        try {
19171            synchronized (this) {
19172                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19173                // its own permission.
19174                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19175                        != PackageManager.PERMISSION_GRANTED) {
19176                    throw new SecurityException("Requires permission "
19177                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19178                }
19179
19180                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19181                    throw new IllegalArgumentException("null profile info or fd");
19182                }
19183
19184                ProcessRecord proc = null;
19185                if (process != null) {
19186                    proc = findProcessLocked(process, userId, "profileControl");
19187                }
19188
19189                if (start && (proc == null || proc.thread == null)) {
19190                    throw new IllegalArgumentException("Unknown process: " + process);
19191                }
19192
19193                if (start) {
19194                    stopProfilerLocked(null, 0);
19195                    setProfileApp(proc.info, proc.processName, profilerInfo);
19196                    mProfileProc = proc;
19197                    mProfileType = profileType;
19198                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19199                    try {
19200                        fd = fd.dup();
19201                    } catch (IOException e) {
19202                        fd = null;
19203                    }
19204                    profilerInfo.profileFd = fd;
19205                    proc.thread.profilerControl(start, profilerInfo, profileType);
19206                    fd = null;
19207                    mProfileFd = null;
19208                } else {
19209                    stopProfilerLocked(proc, profileType);
19210                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19211                        try {
19212                            profilerInfo.profileFd.close();
19213                        } catch (IOException e) {
19214                        }
19215                    }
19216                }
19217
19218                return true;
19219            }
19220        } catch (RemoteException e) {
19221            throw new IllegalStateException("Process disappeared");
19222        } finally {
19223            if (profilerInfo != null && profilerInfo.profileFd != null) {
19224                try {
19225                    profilerInfo.profileFd.close();
19226                } catch (IOException e) {
19227                }
19228            }
19229        }
19230    }
19231
19232    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19233        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19234                userId, true, ALLOW_FULL_ONLY, callName, null);
19235        ProcessRecord proc = null;
19236        try {
19237            int pid = Integer.parseInt(process);
19238            synchronized (mPidsSelfLocked) {
19239                proc = mPidsSelfLocked.get(pid);
19240            }
19241        } catch (NumberFormatException e) {
19242        }
19243
19244        if (proc == null) {
19245            ArrayMap<String, SparseArray<ProcessRecord>> all
19246                    = mProcessNames.getMap();
19247            SparseArray<ProcessRecord> procs = all.get(process);
19248            if (procs != null && procs.size() > 0) {
19249                proc = procs.valueAt(0);
19250                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19251                    for (int i=1; i<procs.size(); i++) {
19252                        ProcessRecord thisProc = procs.valueAt(i);
19253                        if (thisProc.userId == userId) {
19254                            proc = thisProc;
19255                            break;
19256                        }
19257                    }
19258                }
19259            }
19260        }
19261
19262        return proc;
19263    }
19264
19265    public boolean dumpHeap(String process, int userId, boolean managed,
19266            String path, ParcelFileDescriptor fd) throws RemoteException {
19267
19268        try {
19269            synchronized (this) {
19270                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19271                // its own permission (same as profileControl).
19272                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19273                        != PackageManager.PERMISSION_GRANTED) {
19274                    throw new SecurityException("Requires permission "
19275                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19276                }
19277
19278                if (fd == null) {
19279                    throw new IllegalArgumentException("null fd");
19280                }
19281
19282                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19283                if (proc == null || proc.thread == null) {
19284                    throw new IllegalArgumentException("Unknown process: " + process);
19285                }
19286
19287                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19288                if (!isDebuggable) {
19289                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19290                        throw new SecurityException("Process not debuggable: " + proc);
19291                    }
19292                }
19293
19294                proc.thread.dumpHeap(managed, path, fd);
19295                fd = null;
19296                return true;
19297            }
19298        } catch (RemoteException e) {
19299            throw new IllegalStateException("Process disappeared");
19300        } finally {
19301            if (fd != null) {
19302                try {
19303                    fd.close();
19304                } catch (IOException e) {
19305                }
19306            }
19307        }
19308    }
19309
19310    @Override
19311    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19312            String reportPackage) {
19313        if (processName != null) {
19314            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19315                    "setDumpHeapDebugLimit()");
19316        } else {
19317            if (!Build.IS_DEBUGGABLE) {
19318                throw new SecurityException("Not running a debuggable build");
19319            }
19320            synchronized (mPidsSelfLocked) {
19321                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19322                if (proc == null) {
19323                    throw new SecurityException("No process found for calling pid "
19324                            + Binder.getCallingPid());
19325                }
19326                processName = proc.processName;
19327                uid = proc.uid;
19328                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19329                    throw new SecurityException("Package " + reportPackage + " is not running in "
19330                            + proc);
19331                }
19332            }
19333        }
19334        synchronized (this) {
19335            if (maxMemSize > 0) {
19336                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19337            } else {
19338                if (uid != 0) {
19339                    mMemWatchProcesses.remove(processName, uid);
19340                } else {
19341                    mMemWatchProcesses.getMap().remove(processName);
19342                }
19343            }
19344        }
19345    }
19346
19347    @Override
19348    public void dumpHeapFinished(String path) {
19349        synchronized (this) {
19350            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19351                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19352                        + " does not match last pid " + mMemWatchDumpPid);
19353                return;
19354            }
19355            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19356                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19357                        + " does not match last path " + mMemWatchDumpFile);
19358                return;
19359            }
19360            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19361            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19362        }
19363    }
19364
19365    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19366    public void monitor() {
19367        synchronized (this) { }
19368    }
19369
19370    void onCoreSettingsChange(Bundle settings) {
19371        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19372            ProcessRecord processRecord = mLruProcesses.get(i);
19373            try {
19374                if (processRecord.thread != null) {
19375                    processRecord.thread.setCoreSettings(settings);
19376                }
19377            } catch (RemoteException re) {
19378                /* ignore */
19379            }
19380        }
19381    }
19382
19383    // Multi-user methods
19384
19385    /**
19386     * Start user, if its not already running, but don't bring it to foreground.
19387     */
19388    @Override
19389    public boolean startUserInBackground(final int userId) {
19390        return startUser(userId, /* foreground */ false);
19391    }
19392
19393    /**
19394     * Start user, if its not already running, and bring it to foreground.
19395     */
19396    boolean startUserInForeground(final int userId, Dialog dlg) {
19397        boolean result = startUser(userId, /* foreground */ true);
19398        dlg.dismiss();
19399        return result;
19400    }
19401
19402    /**
19403     * Refreshes the list of users related to the current user when either a
19404     * user switch happens or when a new related user is started in the
19405     * background.
19406     */
19407    private void updateCurrentProfileIdsLocked() {
19408        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19409                mCurrentUserId, false /* enabledOnly */);
19410        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19411        for (int i = 0; i < currentProfileIds.length; i++) {
19412            currentProfileIds[i] = profiles.get(i).id;
19413        }
19414        mCurrentProfileIds = currentProfileIds;
19415
19416        synchronized (mUserProfileGroupIdsSelfLocked) {
19417            mUserProfileGroupIdsSelfLocked.clear();
19418            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19419            for (int i = 0; i < users.size(); i++) {
19420                UserInfo user = users.get(i);
19421                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19422                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19423                }
19424            }
19425        }
19426    }
19427
19428    private Set<Integer> getProfileIdsLocked(int userId) {
19429        Set<Integer> userIds = new HashSet<Integer>();
19430        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19431                userId, false /* enabledOnly */);
19432        for (UserInfo user : profiles) {
19433            userIds.add(Integer.valueOf(user.id));
19434        }
19435        return userIds;
19436    }
19437
19438    @Override
19439    public boolean switchUser(final int userId) {
19440        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19441        String userName;
19442        synchronized (this) {
19443            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19444            if (userInfo == null) {
19445                Slog.w(TAG, "No user info for user #" + userId);
19446                return false;
19447            }
19448            if (userInfo.isManagedProfile()) {
19449                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19450                return false;
19451            }
19452            userName = userInfo.name;
19453            mTargetUserId = userId;
19454        }
19455        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19456        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19457        return true;
19458    }
19459
19460    private void showUserSwitchDialog(int userId, String userName) {
19461        // The dialog will show and then initiate the user switch by calling startUserInForeground
19462        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19463                true /* above system */);
19464        d.show();
19465    }
19466
19467    private boolean startUser(final int userId, final boolean foreground) {
19468        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19469                != PackageManager.PERMISSION_GRANTED) {
19470            String msg = "Permission Denial: switchUser() from pid="
19471                    + Binder.getCallingPid()
19472                    + ", uid=" + Binder.getCallingUid()
19473                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19474            Slog.w(TAG, msg);
19475            throw new SecurityException(msg);
19476        }
19477
19478        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19479
19480        final long ident = Binder.clearCallingIdentity();
19481        try {
19482            synchronized (this) {
19483                final int oldUserId = mCurrentUserId;
19484                if (oldUserId == userId) {
19485                    return true;
19486                }
19487
19488                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19489                        "startUser", false);
19490
19491                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19492                if (userInfo == null) {
19493                    Slog.w(TAG, "No user info for user #" + userId);
19494                    return false;
19495                }
19496                if (foreground && userInfo.isManagedProfile()) {
19497                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19498                    return false;
19499                }
19500
19501                if (foreground) {
19502                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19503                            R.anim.screen_user_enter);
19504                }
19505
19506                boolean needStart = false;
19507
19508                // If the user we are switching to is not currently started, then
19509                // we need to start it now.
19510                if (mStartedUsers.get(userId) == null) {
19511                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19512                    updateStartedUserArrayLocked();
19513                    needStart = true;
19514                }
19515
19516                final Integer userIdInt = Integer.valueOf(userId);
19517                mUserLru.remove(userIdInt);
19518                mUserLru.add(userIdInt);
19519
19520                if (foreground) {
19521                    mCurrentUserId = userId;
19522                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19523                    updateCurrentProfileIdsLocked();
19524                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19525                    // Once the internal notion of the active user has switched, we lock the device
19526                    // with the option to show the user switcher on the keyguard.
19527                    mWindowManager.lockNow(null);
19528                } else {
19529                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19530                    updateCurrentProfileIdsLocked();
19531                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19532                    mUserLru.remove(currentUserIdInt);
19533                    mUserLru.add(currentUserIdInt);
19534                }
19535
19536                final UserStartedState uss = mStartedUsers.get(userId);
19537
19538                // Make sure user is in the started state.  If it is currently
19539                // stopping, we need to knock that off.
19540                if (uss.mState == UserStartedState.STATE_STOPPING) {
19541                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19542                    // so we can just fairly silently bring the user back from
19543                    // the almost-dead.
19544                    uss.mState = UserStartedState.STATE_RUNNING;
19545                    updateStartedUserArrayLocked();
19546                    needStart = true;
19547                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19548                    // This means ACTION_SHUTDOWN has been sent, so we will
19549                    // need to treat this as a new boot of the user.
19550                    uss.mState = UserStartedState.STATE_BOOTING;
19551                    updateStartedUserArrayLocked();
19552                    needStart = true;
19553                }
19554
19555                if (uss.mState == UserStartedState.STATE_BOOTING) {
19556                    // Booting up a new user, need to tell system services about it.
19557                    // Note that this is on the same handler as scheduling of broadcasts,
19558                    // which is important because it needs to go first.
19559                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19560                }
19561
19562                if (foreground) {
19563                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19564                            oldUserId));
19565                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19566                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19567                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19568                            oldUserId, userId, uss));
19569                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19570                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19571                }
19572
19573                if (needStart) {
19574                    // Send USER_STARTED broadcast
19575                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19576                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19577                            | Intent.FLAG_RECEIVER_FOREGROUND);
19578                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19579                    broadcastIntentLocked(null, null, intent,
19580                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19581                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19582                }
19583
19584                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19585                    if (userId != UserHandle.USER_OWNER) {
19586                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19587                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19588                        broadcastIntentLocked(null, null, intent, null,
19589                                new IIntentReceiver.Stub() {
19590                                    public void performReceive(Intent intent, int resultCode,
19591                                            String data, Bundle extras, boolean ordered,
19592                                            boolean sticky, int sendingUser) {
19593                                        onUserInitialized(uss, foreground, oldUserId, userId);
19594                                    }
19595                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19596                                true, false, MY_PID, Process.SYSTEM_UID,
19597                                userId);
19598                        uss.initializing = true;
19599                    } else {
19600                        getUserManagerLocked().makeInitialized(userInfo.id);
19601                    }
19602                }
19603
19604                if (foreground) {
19605                    if (!uss.initializing) {
19606                        moveUserToForeground(uss, oldUserId, userId);
19607                    }
19608                } else {
19609                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19610                }
19611
19612                if (needStart) {
19613                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19614                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19615                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19616                    broadcastIntentLocked(null, null, intent,
19617                            null, new IIntentReceiver.Stub() {
19618                                @Override
19619                                public void performReceive(Intent intent, int resultCode, String data,
19620                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19621                                        throws RemoteException {
19622                                }
19623                            }, 0, null, null,
19624                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19625                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19626                }
19627            }
19628        } finally {
19629            Binder.restoreCallingIdentity(ident);
19630        }
19631
19632        return true;
19633    }
19634
19635    void dispatchForegroundProfileChanged(int userId) {
19636        final int N = mUserSwitchObservers.beginBroadcast();
19637        for (int i = 0; i < N; i++) {
19638            try {
19639                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19640            } catch (RemoteException e) {
19641                // Ignore
19642            }
19643        }
19644        mUserSwitchObservers.finishBroadcast();
19645    }
19646
19647    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19648        long ident = Binder.clearCallingIdentity();
19649        try {
19650            Intent intent;
19651            if (oldUserId >= 0) {
19652                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19653                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19654                int count = profiles.size();
19655                for (int i = 0; i < count; i++) {
19656                    int profileUserId = profiles.get(i).id;
19657                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19658                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19659                            | Intent.FLAG_RECEIVER_FOREGROUND);
19660                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19661                    broadcastIntentLocked(null, null, intent,
19662                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19663                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19664                }
19665            }
19666            if (newUserId >= 0) {
19667                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19668                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19669                int count = profiles.size();
19670                for (int i = 0; i < count; i++) {
19671                    int profileUserId = profiles.get(i).id;
19672                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19673                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19674                            | Intent.FLAG_RECEIVER_FOREGROUND);
19675                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19676                    broadcastIntentLocked(null, null, intent,
19677                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19678                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19679                }
19680                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19681                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19682                        | Intent.FLAG_RECEIVER_FOREGROUND);
19683                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19684                broadcastIntentLocked(null, null, intent,
19685                        null, null, 0, null, null,
19686                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19687                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19688            }
19689        } finally {
19690            Binder.restoreCallingIdentity(ident);
19691        }
19692    }
19693
19694    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19695            final int newUserId) {
19696        final int N = mUserSwitchObservers.beginBroadcast();
19697        if (N > 0) {
19698            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19699                int mCount = 0;
19700                @Override
19701                public void sendResult(Bundle data) throws RemoteException {
19702                    synchronized (ActivityManagerService.this) {
19703                        if (mCurUserSwitchCallback == this) {
19704                            mCount++;
19705                            if (mCount == N) {
19706                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19707                            }
19708                        }
19709                    }
19710                }
19711            };
19712            synchronized (this) {
19713                uss.switching = true;
19714                mCurUserSwitchCallback = callback;
19715            }
19716            for (int i=0; i<N; i++) {
19717                try {
19718                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19719                            newUserId, callback);
19720                } catch (RemoteException e) {
19721                }
19722            }
19723        } else {
19724            synchronized (this) {
19725                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19726            }
19727        }
19728        mUserSwitchObservers.finishBroadcast();
19729    }
19730
19731    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19732        synchronized (this) {
19733            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19734            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19735        }
19736    }
19737
19738    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19739        mCurUserSwitchCallback = null;
19740        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19741        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19742                oldUserId, newUserId, uss));
19743    }
19744
19745    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19746        synchronized (this) {
19747            if (foreground) {
19748                moveUserToForeground(uss, oldUserId, newUserId);
19749            }
19750        }
19751
19752        completeSwitchAndInitalize(uss, newUserId, true, false);
19753    }
19754
19755    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19756        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19757        if (homeInFront) {
19758            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19759        } else {
19760            mStackSupervisor.resumeTopActivitiesLocked();
19761        }
19762        EventLogTags.writeAmSwitchUser(newUserId);
19763        getUserManagerLocked().onUserForeground(newUserId);
19764        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19765    }
19766
19767    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19768        completeSwitchAndInitalize(uss, newUserId, false, true);
19769    }
19770
19771    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19772            boolean clearInitializing, boolean clearSwitching) {
19773        boolean unfrozen = false;
19774        synchronized (this) {
19775            if (clearInitializing) {
19776                uss.initializing = false;
19777                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19778            }
19779            if (clearSwitching) {
19780                uss.switching = false;
19781            }
19782            if (!uss.switching && !uss.initializing) {
19783                mWindowManager.stopFreezingScreen();
19784                unfrozen = true;
19785            }
19786        }
19787        if (unfrozen) {
19788            final int N = mUserSwitchObservers.beginBroadcast();
19789            for (int i=0; i<N; i++) {
19790                try {
19791                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19792                } catch (RemoteException e) {
19793                }
19794            }
19795            mUserSwitchObservers.finishBroadcast();
19796        }
19797        stopGuestUserIfBackground();
19798    }
19799
19800    /**
19801     * Stops the guest user if it has gone to the background.
19802     */
19803    private void stopGuestUserIfBackground() {
19804        synchronized (this) {
19805            final int num = mUserLru.size();
19806            for (int i = 0; i < num; i++) {
19807                Integer oldUserId = mUserLru.get(i);
19808                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19809                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19810                        || oldUss.mState == UserStartedState.STATE_STOPPING
19811                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19812                    continue;
19813                }
19814                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19815                if (userInfo.isGuest()) {
19816                    // This is a user to be stopped.
19817                    stopUserLocked(oldUserId, null);
19818                    break;
19819                }
19820            }
19821        }
19822    }
19823
19824    void scheduleStartProfilesLocked() {
19825        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19826            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19827                    DateUtils.SECOND_IN_MILLIS);
19828        }
19829    }
19830
19831    void startProfilesLocked() {
19832        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19833        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19834                mCurrentUserId, false /* enabledOnly */);
19835        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19836        for (UserInfo user : profiles) {
19837            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19838                    && user.id != mCurrentUserId) {
19839                toStart.add(user);
19840            }
19841        }
19842        final int n = toStart.size();
19843        int i = 0;
19844        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19845            startUserInBackground(toStart.get(i).id);
19846        }
19847        if (i < n) {
19848            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19849        }
19850    }
19851
19852    void finishUserBoot(UserStartedState uss) {
19853        synchronized (this) {
19854            if (uss.mState == UserStartedState.STATE_BOOTING
19855                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19856                uss.mState = UserStartedState.STATE_RUNNING;
19857                final int userId = uss.mHandle.getIdentifier();
19858                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19859                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19860                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19861                broadcastIntentLocked(null, null, intent,
19862                        null, null, 0, null, null,
19863                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19864                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19865            }
19866        }
19867    }
19868
19869    void finishUserSwitch(UserStartedState uss) {
19870        synchronized (this) {
19871            finishUserBoot(uss);
19872
19873            startProfilesLocked();
19874
19875            int num = mUserLru.size();
19876            int i = 0;
19877            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19878                Integer oldUserId = mUserLru.get(i);
19879                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19880                if (oldUss == null) {
19881                    // Shouldn't happen, but be sane if it does.
19882                    mUserLru.remove(i);
19883                    num--;
19884                    continue;
19885                }
19886                if (oldUss.mState == UserStartedState.STATE_STOPPING
19887                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19888                    // This user is already stopping, doesn't count.
19889                    num--;
19890                    i++;
19891                    continue;
19892                }
19893                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19894                    // Owner and current can't be stopped, but count as running.
19895                    i++;
19896                    continue;
19897                }
19898                // This is a user to be stopped.
19899                stopUserLocked(oldUserId, null);
19900                num--;
19901                i++;
19902            }
19903        }
19904    }
19905
19906    @Override
19907    public int stopUser(final int userId, final IStopUserCallback callback) {
19908        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19909                != PackageManager.PERMISSION_GRANTED) {
19910            String msg = "Permission Denial: switchUser() from pid="
19911                    + Binder.getCallingPid()
19912                    + ", uid=" + Binder.getCallingUid()
19913                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19914            Slog.w(TAG, msg);
19915            throw new SecurityException(msg);
19916        }
19917        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19918            throw new IllegalArgumentException("Can't stop primary user " + userId);
19919        }
19920        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19921        synchronized (this) {
19922            return stopUserLocked(userId, callback);
19923        }
19924    }
19925
19926    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19927        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19928        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19929            return ActivityManager.USER_OP_IS_CURRENT;
19930        }
19931
19932        final UserStartedState uss = mStartedUsers.get(userId);
19933        if (uss == null) {
19934            // User is not started, nothing to do...  but we do need to
19935            // callback if requested.
19936            if (callback != null) {
19937                mHandler.post(new Runnable() {
19938                    @Override
19939                    public void run() {
19940                        try {
19941                            callback.userStopped(userId);
19942                        } catch (RemoteException e) {
19943                        }
19944                    }
19945                });
19946            }
19947            return ActivityManager.USER_OP_SUCCESS;
19948        }
19949
19950        if (callback != null) {
19951            uss.mStopCallbacks.add(callback);
19952        }
19953
19954        if (uss.mState != UserStartedState.STATE_STOPPING
19955                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19956            uss.mState = UserStartedState.STATE_STOPPING;
19957            updateStartedUserArrayLocked();
19958
19959            long ident = Binder.clearCallingIdentity();
19960            try {
19961                // We are going to broadcast ACTION_USER_STOPPING and then
19962                // once that is done send a final ACTION_SHUTDOWN and then
19963                // stop the user.
19964                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19965                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19966                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19967                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19968                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19969                // This is the result receiver for the final shutdown broadcast.
19970                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19971                    @Override
19972                    public void performReceive(Intent intent, int resultCode, String data,
19973                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19974                        finishUserStop(uss);
19975                    }
19976                };
19977                // This is the result receiver for the initial stopping broadcast.
19978                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19979                    @Override
19980                    public void performReceive(Intent intent, int resultCode, String data,
19981                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19982                        // On to the next.
19983                        synchronized (ActivityManagerService.this) {
19984                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19985                                // Whoops, we are being started back up.  Abort, abort!
19986                                return;
19987                            }
19988                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19989                        }
19990                        mBatteryStatsService.noteEvent(
19991                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19992                                Integer.toString(userId), userId);
19993                        mSystemServiceManager.stopUser(userId);
19994                        broadcastIntentLocked(null, null, shutdownIntent,
19995                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19996                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19997                    }
19998                };
19999                // Kick things off.
20000                broadcastIntentLocked(null, null, stoppingIntent,
20001                        null, stoppingReceiver, 0, null, null,
20002                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20003                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20004            } finally {
20005                Binder.restoreCallingIdentity(ident);
20006            }
20007        }
20008
20009        return ActivityManager.USER_OP_SUCCESS;
20010    }
20011
20012    void finishUserStop(UserStartedState uss) {
20013        final int userId = uss.mHandle.getIdentifier();
20014        boolean stopped;
20015        ArrayList<IStopUserCallback> callbacks;
20016        synchronized (this) {
20017            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20018            if (mStartedUsers.get(userId) != uss) {
20019                stopped = false;
20020            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
20021                stopped = false;
20022            } else {
20023                stopped = true;
20024                // User can no longer run.
20025                mStartedUsers.remove(userId);
20026                mUserLru.remove(Integer.valueOf(userId));
20027                updateStartedUserArrayLocked();
20028
20029                // Clean up all state and processes associated with the user.
20030                // Kill all the processes for the user.
20031                forceStopUserLocked(userId, "finish user");
20032            }
20033
20034            // Explicitly remove the old information in mRecentTasks.
20035            mRecentTasks.removeTasksForUserLocked(userId);
20036        }
20037
20038        for (int i=0; i<callbacks.size(); i++) {
20039            try {
20040                if (stopped) callbacks.get(i).userStopped(userId);
20041                else callbacks.get(i).userStopAborted(userId);
20042            } catch (RemoteException e) {
20043            }
20044        }
20045
20046        if (stopped) {
20047            mSystemServiceManager.cleanupUser(userId);
20048            synchronized (this) {
20049                mStackSupervisor.removeUserLocked(userId);
20050            }
20051        }
20052    }
20053
20054    @Override
20055    public UserInfo getCurrentUser() {
20056        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20057                != PackageManager.PERMISSION_GRANTED) && (
20058                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20059                != PackageManager.PERMISSION_GRANTED)) {
20060            String msg = "Permission Denial: getCurrentUser() from pid="
20061                    + Binder.getCallingPid()
20062                    + ", uid=" + Binder.getCallingUid()
20063                    + " requires " + INTERACT_ACROSS_USERS;
20064            Slog.w(TAG, msg);
20065            throw new SecurityException(msg);
20066        }
20067        synchronized (this) {
20068            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20069            return getUserManagerLocked().getUserInfo(userId);
20070        }
20071    }
20072
20073    int getCurrentUserIdLocked() {
20074        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20075    }
20076
20077    @Override
20078    public boolean isUserRunning(int userId, boolean orStopped) {
20079        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20080                != PackageManager.PERMISSION_GRANTED) {
20081            String msg = "Permission Denial: isUserRunning() from pid="
20082                    + Binder.getCallingPid()
20083                    + ", uid=" + Binder.getCallingUid()
20084                    + " requires " + INTERACT_ACROSS_USERS;
20085            Slog.w(TAG, msg);
20086            throw new SecurityException(msg);
20087        }
20088        synchronized (this) {
20089            return isUserRunningLocked(userId, orStopped);
20090        }
20091    }
20092
20093    boolean isUserRunningLocked(int userId, boolean orStopped) {
20094        UserStartedState state = mStartedUsers.get(userId);
20095        if (state == null) {
20096            return false;
20097        }
20098        if (orStopped) {
20099            return true;
20100        }
20101        return state.mState != UserStartedState.STATE_STOPPING
20102                && state.mState != UserStartedState.STATE_SHUTDOWN;
20103    }
20104
20105    @Override
20106    public int[] getRunningUserIds() {
20107        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20108                != PackageManager.PERMISSION_GRANTED) {
20109            String msg = "Permission Denial: isUserRunning() from pid="
20110                    + Binder.getCallingPid()
20111                    + ", uid=" + Binder.getCallingUid()
20112                    + " requires " + INTERACT_ACROSS_USERS;
20113            Slog.w(TAG, msg);
20114            throw new SecurityException(msg);
20115        }
20116        synchronized (this) {
20117            return mStartedUserArray;
20118        }
20119    }
20120
20121    private void updateStartedUserArrayLocked() {
20122        int num = 0;
20123        for (int i=0; i<mStartedUsers.size();  i++) {
20124            UserStartedState uss = mStartedUsers.valueAt(i);
20125            // This list does not include stopping users.
20126            if (uss.mState != UserStartedState.STATE_STOPPING
20127                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20128                num++;
20129            }
20130        }
20131        mStartedUserArray = new int[num];
20132        num = 0;
20133        for (int i=0; i<mStartedUsers.size();  i++) {
20134            UserStartedState uss = mStartedUsers.valueAt(i);
20135            if (uss.mState != UserStartedState.STATE_STOPPING
20136                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20137                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20138                num++;
20139            }
20140        }
20141    }
20142
20143    @Override
20144    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20145        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20146                != PackageManager.PERMISSION_GRANTED) {
20147            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20148                    + Binder.getCallingPid()
20149                    + ", uid=" + Binder.getCallingUid()
20150                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20151            Slog.w(TAG, msg);
20152            throw new SecurityException(msg);
20153        }
20154
20155        mUserSwitchObservers.register(observer);
20156    }
20157
20158    @Override
20159    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20160        mUserSwitchObservers.unregister(observer);
20161    }
20162
20163    int[] getUsersLocked() {
20164        UserManagerService ums = getUserManagerLocked();
20165        return ums != null ? ums.getUserIds() : new int[] { 0 };
20166    }
20167
20168    UserManagerService getUserManagerLocked() {
20169        if (mUserManager == null) {
20170            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20171            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20172        }
20173        return mUserManager;
20174    }
20175
20176    private int applyUserId(int uid, int userId) {
20177        return UserHandle.getUid(userId, uid);
20178    }
20179
20180    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20181        if (info == null) return null;
20182        ApplicationInfo newInfo = new ApplicationInfo(info);
20183        newInfo.uid = applyUserId(info.uid, userId);
20184        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20185                userId).getAbsolutePath();
20186        return newInfo;
20187    }
20188
20189    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20190        if (aInfo == null
20191                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20192            return aInfo;
20193        }
20194
20195        ActivityInfo info = new ActivityInfo(aInfo);
20196        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20197        return info;
20198    }
20199
20200    private final class LocalService extends ActivityManagerInternal {
20201        @Override
20202        public void onWakefulnessChanged(int wakefulness) {
20203            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20204        }
20205
20206        @Override
20207        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20208                String processName, String abiOverride, int uid, Runnable crashHandler) {
20209            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20210                    processName, abiOverride, uid, crashHandler);
20211        }
20212
20213        @Override
20214        public SleepToken acquireSleepToken(String tag) {
20215            Preconditions.checkNotNull(tag);
20216
20217            synchronized (ActivityManagerService.this) {
20218                SleepTokenImpl token = new SleepTokenImpl(tag);
20219                mSleepTokens.add(token);
20220                updateSleepIfNeededLocked();
20221                return token;
20222            }
20223        }
20224
20225        @Override
20226        public ComponentName getHomeActivityForUser(int userId) {
20227            synchronized (ActivityManagerService.this) {
20228                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20229                return homeActivity == null ? null : homeActivity.realActivity;
20230            }
20231        }
20232    }
20233
20234    private final class SleepTokenImpl extends SleepToken {
20235        private final String mTag;
20236        private final long mAcquireTime;
20237
20238        public SleepTokenImpl(String tag) {
20239            mTag = tag;
20240            mAcquireTime = SystemClock.uptimeMillis();
20241        }
20242
20243        @Override
20244        public void release() {
20245            synchronized (ActivityManagerService.this) {
20246                if (mSleepTokens.remove(this)) {
20247                    updateSleepIfNeededLocked();
20248                }
20249            }
20250        }
20251
20252        @Override
20253        public String toString() {
20254            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20255        }
20256    }
20257
20258    /**
20259     * An implementation of IAppTask, that allows an app to manage its own tasks via
20260     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20261     * only the process that calls getAppTasks() can call the AppTask methods.
20262     */
20263    class AppTaskImpl extends IAppTask.Stub {
20264        private int mTaskId;
20265        private int mCallingUid;
20266
20267        public AppTaskImpl(int taskId, int callingUid) {
20268            mTaskId = taskId;
20269            mCallingUid = callingUid;
20270        }
20271
20272        private void checkCaller() {
20273            if (mCallingUid != Binder.getCallingUid()) {
20274                throw new SecurityException("Caller " + mCallingUid
20275                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20276            }
20277        }
20278
20279        @Override
20280        public void finishAndRemoveTask() {
20281            checkCaller();
20282
20283            synchronized (ActivityManagerService.this) {
20284                long origId = Binder.clearCallingIdentity();
20285                try {
20286                    if (!removeTaskByIdLocked(mTaskId, false)) {
20287                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20288                    }
20289                } finally {
20290                    Binder.restoreCallingIdentity(origId);
20291                }
20292            }
20293        }
20294
20295        @Override
20296        public ActivityManager.RecentTaskInfo getTaskInfo() {
20297            checkCaller();
20298
20299            synchronized (ActivityManagerService.this) {
20300                long origId = Binder.clearCallingIdentity();
20301                try {
20302                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20303                    if (tr == null) {
20304                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20305                    }
20306                    return createRecentTaskInfoFromTaskRecord(tr);
20307                } finally {
20308                    Binder.restoreCallingIdentity(origId);
20309                }
20310            }
20311        }
20312
20313        @Override
20314        public void moveToFront() {
20315            checkCaller();
20316            // Will bring task to front if it already has a root activity.
20317            startActivityFromRecentsInner(mTaskId, null);
20318        }
20319
20320        @Override
20321        public int startActivity(IBinder whoThread, String callingPackage,
20322                Intent intent, String resolvedType, Bundle options) {
20323            checkCaller();
20324
20325            int callingUser = UserHandle.getCallingUserId();
20326            TaskRecord tr;
20327            IApplicationThread appThread;
20328            synchronized (ActivityManagerService.this) {
20329                tr = mRecentTasks.taskForIdLocked(mTaskId);
20330                if (tr == null) {
20331                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20332                }
20333                appThread = ApplicationThreadNative.asInterface(whoThread);
20334                if (appThread == null) {
20335                    throw new IllegalArgumentException("Bad app thread " + appThread);
20336                }
20337            }
20338            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20339                    resolvedType, null, null, null, null, 0, 0, null, null,
20340                    null, options, callingUser, null, tr);
20341        }
20342
20343        @Override
20344        public void setExcludeFromRecents(boolean exclude) {
20345            checkCaller();
20346
20347            synchronized (ActivityManagerService.this) {
20348                long origId = Binder.clearCallingIdentity();
20349                try {
20350                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20351                    if (tr == null) {
20352                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20353                    }
20354                    Intent intent = tr.getBaseIntent();
20355                    if (exclude) {
20356                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20357                    } else {
20358                        intent.setFlags(intent.getFlags()
20359                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20360                    }
20361                } finally {
20362                    Binder.restoreCallingIdentity(origId);
20363                }
20364            }
20365        }
20366    }
20367}
20368